# 2.11BSD#431 - /usr/src/new/rcs/src/rcsutil.c

##### Functions

    addlock           X
    addsymbol         X
    catchints         X
    catchsig          X
    checkaccesslist   X
    cksignal          X
    fastcopy          X
    findlock          X
    getcaller         X
    ignoreints        X
    logcommand        X
    restoreints       X

       1: /*
       2:  *                     RCS utilities
       3:  */
       4: #if !defined(lint) && defined(DOSCCS)
       5: static char rcsid[]= "$Id: rcsutil.c,v 4.3.1 97/10/2 10:40:22 sms Exp $";
       6: #endif
       7: /*****************************************************************************
       8:  *****************************************************************************
       9:  *
      10:  * Copyright (C) 1982 by Walter F. Tichy
      11:  *                       Purdue University
      12:  *                       Computer Science Department
      13:  *                       West Lafayette, IN 47907
      14:  *
      15:  * All rights reserved. No part of this software may be sold or distributed
      16:  * in any form or by any means without the prior written permission of the
      17:  * author.
      18:  * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
      19:  */
      20:
      21:
      22:
      23: /* $Log:	rcsutil.c,v $
      24:  * Revision 4.3.1 97/10/2 sms
      25:  * Use unistd.h instead of declaring system functions locally
      26:  *
      27:  * Revision 4.3  87/10/18  10:40:22  narten
      28:  * Updating version numbers. Changes relative to 1.1 actually
      29:  * relative to 4.1
      30:  *
      31:  * Revision 1.3  87/09/24  14:01:01  narten
      32:  * Sources now pass through lint (if you ignore printf/sprintf/fprintf
      33:  * warnings)
      34:  *
      35:  * Revision 1.2  87/03/27  14:22:43  jenkins
      36:  * Port to suns
      37:  *
      38:  * Revision 1.1  84/01/23  14:50:43  kcs
      39:  * Initial revision
      40:  *
      41:  * Revision 4.1  83/05/10  15:53:13  wft
      42:  * Added getcaller() and findlock().
      43:  * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal
      44:  * (needed for background jobs in older shells). Added restoreints().
      45:  * Removed printing of full RCS path from logcommand().
      46:  *
      47:  * Revision 3.8  83/02/15  15:41:49  wft
      48:  * Added routine fastcopy() to copy remainder of a file in blocks.
      49:  *
      50:  * Revision 3.7  82/12/24  15:25:19  wft
      51:  * added catchints(), ignoreints() for catching and ingnoring interrupts;
      52:  * fixed catchsig().
      53:  *
      54:  * Revision 3.6  82/12/08  21:52:05  wft
      55:  * Using DATEFORM to format dates.
      56:  *
      57:  * Revision 3.5  82/12/04  18:20:49  wft
      58:  * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update
      59:  * lockedby-field.
      60:  *
      61:  * Revision 3.4  82/12/03  17:17:43  wft
      62:  * Added check to addlock() ensuring only one lock per person.
      63:  * Addlock also returns a pointer to the lock created. Deleted fancydate().
      64:  *
      65:  * Revision 3.3  82/11/27  12:24:37  wft
      66:  * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c.
      67:  * Introduced macro SNOOP so that snoop can be placed in directory other than
      68:  * TARGETDIR. Changed %02d to %.2d for compatibility reasons.
      69:  *
      70:  * Revision 3.2  82/10/18  21:15:11  wft
      71:  * added function getfullRCSname().
      72:  *
      73:  * Revision 3.1  82/10/13  16:17:37  wft
      74:  * Cleanup message is now suppressed in quiet mode.
      75:  */
      76:
      77:
      78:
      79:
      80: #include <sys/types.h>
      81: #include <sys/stat.h>
      82: #include <signal.h>
      83: #include "rcsbase.h"
      84: #include <pwd.h>
      85: #include <unistd.h>
      86:
      87: extern char * malloc();
      88: extern char * bindex();
      89: extern FILE * finptr;
      90: extern char * RCSfilename;
      91:
      92: sig_t    oldSIGINT;         /* saves the original value for SIGINT */
      93:
      94: char * getcaller()
      95: /* Function: gets the callers login from his uid.
      96:  * If the uid is root, tries to get the true login with getlogin().
      97:  */
      98: {       char * name;
      99:     int uid;
     100:     uid=getuid();
     101:     if (uid==0) {
     102:         /* super user; try getlogin() to distinguish */
     103:         name = getlogin();
     104:         if (name!=nil && *name!='\0')
     105:             return name;
     106:     }
     107:     return(getpwuid(uid)->pw_name);
     108: }
     109:
     110:
     111:
     112: struct hshentry * findlock(who,delete)
     113: char * who; int delete;
     114: /* Finds the first lock held by who and returns a pointer
     115:  * to the locked delta; also removes the lock if delete==true.
     116:  * Returns nil if there is no lock held by who.
     117:  */
     118: {
     119:         register struct lock * next, * trail;
     120:         struct lock dummy;
     121:
     122:         dummy.nextlock=next=Locks;
     123:         trail = &dummy;
     124:         while (next!=nil) {
     125:                 if(strcmp(who,next->login)==0) break; /*found a lock*/
     126:                 trail=next;
     127:                 next=next->nextlock;
     128:         }
     129:         if (next!=nil) {
     130:         /* found one */
     131:         if (delete) {
     132:             /* delete it */
     133:             trail->nextlock=next->nextlock;
     134:             Locks=dummy.nextlock;
     135:             next->delta->lockedby=nil; /* reset locked-by */
     136:         }
     137:                 return next->delta;
     138:         } else  return nil;
     139: }
     140:
     141:
     142:
     143:
     144:
     145:
     146:
     147: struct lock * addlock(delta,who)
     148: struct hshentry * delta; char * who;
     149: /* Given a delta, addlock checks whether
     150:  * the delta is locked by somebody other than who.
     151:  * If so, an error message is printed, and false returned.
     152:  * If the delta is not reserved at all, a lock for it is added,
     153:  * and a pointer for the lock returned.
     154:  */
     155: {
     156:         struct lock * next;
     157:
     158:         next=Locks;
     159:         while (next!=nil) {
     160:                 if (cmpnum(delta->num,next->delta->num)==0) {
     161:                         if (strcmp(who,next->login)==0)
     162:                                 return next;
     163:                                 /* lock exists already */
     164:                         else {
     165:                                 error("revision %s already locked by %s",
     166:                                       delta->num, next->login);
     167:                                 return false;
     168:                         }
     169:                 } else {
     170:                         if (strcmp(who,next->login)==0) {
     171:                                 error("you already locked %s; only one lock allowed per person.",
     172:                                        next->delta->num);
     173:                                 return false;
     174:                         } else {
     175:                                 next=next->nextlock;
     176:                         }
     177:                 }
     178:         }
     179:         /* not found; set up new lockblock */
     180:         next= (struct lock *) malloc(sizeof (struct lock));
     181:         delta->lockedby=next->login=who;
     182:         next->delta= delta;
     183:         next->nextlock=Locks;
     184:         Locks=next;
     185:         return next;
     186: }
     187:
     188:
     189:
     190: int addsymbol(delta,name,rebind)
     191: struct hshentry * delta; char * name; int rebind;
     192: /* Function: adds a new symbolic name and associates it with node delta.
     193:  * If name already exists and rebind is true, the name is associated
     194:  * with the new delta; otherwise, an error message is printed and
     195:  * false returned. Returns true it successful.
     196:  */
     197: {       register struct assoc * next;
     198:         next=Symbols;
     199:         while (next!=nil) {
     200:                 if (strcmp(name,next->symbol)==0) {
     201:                         if (rebind) {
     202:                                 next->delta=delta;
     203:                                 return true;
     204:                         } else {
     205:                                 error("symbolic name %s already bound to %s",
     206:                                         name,next->delta->num);
     207:                                 return false;
     208:                         }
     209:                 } else  next = next->nextassoc;
     210:         }
     211:         /* not found; insert new pair. */
     212:         next = (struct assoc *) malloc(sizeof(struct assoc));
     213:         next->symbol=name;
     214:         next->delta=delta;
     215:         next->nextassoc=Symbols;
     216:         Symbols = next;
     217:         return true;
     218: }
     219:
     220:
     221:
     222:
     223: int checkaccesslist(who)
     224: char * who;
     225: /* function: Returns true if who is the superuser, the owner of the
     226:  * file, the access list is empty, or who is on the access list.
     227:  * Prints an error message and returns false otherwise.
     228:  */
     229: {
     230:         register struct access * next;
     231:         struct stat statbuf;
     232:
     233:         if ((AccessList==nil) || (strcmp(who,"root")==0))
     234:                 return true;
     235:
     236:         next=AccessList;
     237:         do {
     238:                 if (strcmp(who,next->login)==0)
     239:                         return true;
     240:                 next=next->nextaccess;
     241:         } while (next!=nil);
     242:
     243:         VOID fstat(fileno(finptr),&statbuf);  /* get owner of file */
     244:         if (getuid() == statbuf.st_uid) return true;
     245:
     246:         error("User %s not on the access list",who);
     247:         return false;
     248: }
     249:
     250: catchsig(sig)
     251: {
     252:     VOID signal(sig, SIG_IGN);
     253:         diagnose("\nRCS: cleaning up\n");
     254:         VOID cleanup();
     255:         exit(1);
     256: }
     257:
     258:
     259:   void catchints()
     260:   {
     261:         cksignal(SIGINT); cksignal(SIGHUP);
     262:         cksignal(SIGQUIT); cksignal(SIGPIPE);
     263:     cksignal(SIGTERM);
     264:   }
     265:
     266:
     267: cksignal(sig)
     268: int sig;
     269: {
     270:     if (signal(sig,SIG_IGN) != SIG_IGN)
     271:         VOID signal(sig,catchsig);
     272: }
     273:
     274:   void ignoreints()
     275:   {
     276:         VOID signal(SIGINT,SIG_IGN); VOID signal(SIGHUP,SIG_IGN);
     277:         VOID signal(SIGQUIT,SIG_IGN); VOID signal(SIGPIPE,SIG_IGN);
     278:     VOID signal(SIGTERM,SIG_IGN);
     279:   }
     280:
     281:
     282: void restoreints()
     283: {
     284:         if (oldSIGINT!=SIG_IGN)
     285:                 VOID signal(SIGINT,catchsig);
     286:         VOID signal(SIGHUP,catchsig); VOID signal(SIGQUIT,catchsig);
     287:         VOID signal(SIGPIPE,catchsig); VOID signal(SIGTERM,catchsig);
     288: }
     289:
     290:
     291: fastcopy(inf,outf)
     292: FILE * inf, * outf;
     293: /* Function: copies the remainder of file inf to outf. First copies the
     294:  * rest that is in the IO-buffer of inf character by character, and then
     295:  * copies the remainder in blocks.
     296:  */
     297: {       char buf[BUFSIZ];
     298:         register int rcount, wcount;
     299:
     300:         /* write the rest of the buffer to outf */
     301:         while ((--inf->_cnt)>=0) {
     302:                 VOID putc(*inf->_ptr++&0377,outf);
     303:         }
     304:         if (fflush(outf) == EOF) {
     305:         faterror("write error");
     306:     }
     307:
     308:         /*now read the rest of the file in blocks*/
     309:         while ((rcount=read(fileno(inf),buf,BUFSIZ))>0) {
     310:                 wcount=write(fileno(outf),buf,rcount);
     311:                 if (wcount!=rcount) {
     312:                     faterror("write error");
     313:                 }
     314:         }
     315: }
     316:
     317:
     318:
     319:
     320:
     321:
     322: #ifdef SNOOPFILE
     323:
     324: #include "time.h"
     325: extern struct tm* localtime();
     326: extern long time();
     327:
     328: logcommand(commandname,delta, sequence,login)
     329: char* commandname; struct hshentry * delta, * sequence[];char * login;
     330: /* Function: start a process to write the file that
     331:  * logs the RCS command.
     332:  * Each line in the log file contains the following information:
     333:  * operation, revision(r), backward deltas applied(b), forward deltas applied(f),
     334:  * total deltas present(t), creation date of delta(d), date of operation(o),
     335:  * login of caller, RCS file name.
     336:  */
     337: {
     338:         char command[200];
     339:         char curdate[datelength];
     340:         register int i, backward, forward;
     341:         long clock;
     342:         struct tm * tm;
     343:
     344:         clock=time((long *)0);
     345:         tm=localtime(&clock);
     346:
     347:         VOID sprintf(curdate,DATEFORM,
     348:                 tm->tm_year, tm->tm_mon+1, tm->tm_mday,
     349:                 tm->tm_hour, tm->tm_min, tm->tm_sec);
     350:
     351:         i= backward=forward=0;
     352:         while(sequence[i]!=nil) {  /* count deltas to be applied*/
     353:         if (countnumflds(sequence[i]->num) == 2)
     354:                 backward++;  /* reverse delta */
     355:         else    forward++;   /* branch delta  */
     356:         i++;
     357:         }
     358:         VOID sprintf(command,"%s \"%s %10sr %3db %3df %3dt %sc %so %s %s\" &\n",
     359:                 SNOOP, commandname,delta->num,backward,forward,TotalDeltas,delta->date,
     360:                 curdate,login,bindex(RCSfilename,'/'));
     361:         VOID system(command);
     362: }
     363: #endif

#### Defined functions

addlock defined in line 147; used 7 times

- in /usr/src/new/rcs/src/ci.c line 132, 422
- in /usr/src/new/rcs/src/co.c line 115, 287
- in /usr/src/new/rcs/src/rcs.c line 118, 1384, 1411

addsymbol defined in line 190; used 2 times

- in /usr/src/new/rcs/src/ci.c line 423
- in /usr/src/new/rcs/src/rcs.c line 1322

catchints defined in line 259; used 8 times

- in /usr/src/new/rcs/src/ci.c line 188
- in /usr/src/new/rcs/src/co.c line 153
- in /usr/src/new/rcs/src/rcs.c line 134, 215
- in /usr/src/new/rcs/src/rcsbase.h line 316
- in /usr/src/new/rcs/src/rcsclean.c line 71
- in /usr/src/new/rcs/src/rcsdiff.c line 109
- in /usr/src/new/rcs/src/rcsmerge.c line 78

catchsig defined in line 250; used 6 times

- in line 271, 285-287(5)

checkaccesslist defined in line 223; used 3 times

- in /usr/src/new/rcs/src/ci.c line 361
- in /usr/src/new/rcs/src/co.c line 260
- in /usr/src/new/rcs/src/rcs.c line 453

cksignal defined in line 267; used 5 times

- in line 261-263(5)

fastcopy defined in line 291; used 3 times

- in /usr/src/new/rcs/src/ci.c line 477
- in /usr/src/new/rcs/src/co.c line 329
- in /usr/src/new/rcs/src/rcs.c line 544

findlock defined in line 112; used 6 times

- in /usr/src/new/rcs/src/ci.c line 135, 562
- in /usr/src/new/rcs/src/co.c line 114, 278
- in /usr/src/new/rcs/src/rcs.c line 129, 1344

getcaller defined in line 94; used 8 times

- in /usr/src/new/rcs/src/ci.c line 119, 194
- in /usr/src/new/rcs/src/co.c line 104, 158
- in /usr/src/new/rcs/src/rcs.c line 125, 226
- in /usr/src/new/rcs/src/rlog.c line 88, 182

ignoreints defined in line 274; used 6 times

- in /usr/src/new/rcs/src/ci.c line 480, 508
- in /usr/src/new/rcs/src/co.c line 331
- in /usr/src/new/rcs/src/rcs.c line 135, 555
- in /usr/src/new/rcs/src/rcsbase.h line 315

logcommand defined in line 328; used 2 times

- in /usr/src/new/rcs/src/ci.c line 498
- in /usr/src/new/rcs/src/co.c line 346

restoreints defined in line 282; used 9 times

- in /usr/src/new/rcs/src/ci.c line 485, 496, 511, 517
- in /usr/src/new/rcs/src/co.c line 336, 342
- in /usr/src/new/rcs/src/rcs.c line 560, 573
- in /usr/src/new/rcs/src/rcsbase.h line 317

#### Defined variables

rcsid defined in line 5; never used

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1162 |