Annotation of 43BSDTahoe/new/rcs/src/rcsutil.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *                     RCS utilities
                      3:  */
                      4: #ifndef lint
                      5: static char rcsid[]= "$Id: rcsutil.c,v 4.3 87/10/18 10:40:22 narten Exp $ Purdue CS";
                      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  87/10/18  10:40:22  narten
                     25:  * Updating version numbers. Changes relative to 1.1 actually
                     26:  * relative to 4.1
                     27:  * 
                     28:  * Revision 1.3  87/09/24  14:01:01  narten
                     29:  * Sources now pass through lint (if you ignore printf/sprintf/fprintf 
                     30:  * warnings)
                     31:  * 
                     32:  * Revision 1.2  87/03/27  14:22:43  jenkins
                     33:  * Port to suns
                     34:  * 
                     35:  * Revision 1.1  84/01/23  14:50:43  kcs
                     36:  * Initial revision
                     37:  * 
                     38:  * Revision 4.1  83/05/10  15:53:13  wft
                     39:  * Added getcaller() and findlock().
                     40:  * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal
                     41:  * (needed for background jobs in older shells). Added restoreints().
                     42:  * Removed printing of full RCS path from logcommand().
                     43:  * 
                     44:  * Revision 3.8  83/02/15  15:41:49  wft
                     45:  * Added routine fastcopy() to copy remainder of a file in blocks.
                     46:  *
                     47:  * Revision 3.7  82/12/24  15:25:19  wft
                     48:  * added catchints(), ignoreints() for catching and ingnoring interrupts;
                     49:  * fixed catchsig().
                     50:  *
                     51:  * Revision 3.6  82/12/08  21:52:05  wft
                     52:  * Using DATEFORM to format dates.
                     53:  *
                     54:  * Revision 3.5  82/12/04  18:20:49  wft
                     55:  * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update
                     56:  * lockedby-field.
                     57:  *
                     58:  * Revision 3.4  82/12/03  17:17:43  wft
                     59:  * Added check to addlock() ensuring only one lock per person.
                     60:  * Addlock also returns a pointer to the lock created. Deleted fancydate().
                     61:  *
                     62:  * Revision 3.3  82/11/27  12:24:37  wft
                     63:  * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c.
                     64:  * Introduced macro SNOOP so that snoop can be placed in directory other than
                     65:  * TARGETDIR. Changed %02d to %.2d for compatibility reasons.
                     66:  *
                     67:  * Revision 3.2  82/10/18  21:15:11  wft
                     68:  * added function getfullRCSname().
                     69:  *
                     70:  * Revision 3.1  82/10/13  16:17:37  wft
                     71:  * Cleanup message is now suppressed in quiet mode.
                     72:  */
                     73: 
                     74: 
                     75: 
                     76: 
                     77: #include <sys/types.h>
                     78: #include <sys/stat.h>
                     79: #include <signal.h>
                     80: #include "rcsbase.h"
                     81: #include <pwd.h>
                     82: 
                     83: extern char * malloc();
                     84: extern char * bindex();
                     85: extern FILE * finptr;
                     86: extern char * RCSfilename;
                     87: extern char * getlogin();
                     88: extern struct passwd *getpwuid();
                     89: 
                     90: int    (*oldSIGINT)();         /* saves the original value for SIGINT */
                     91: 
                     92: 
                     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
                    364: 
                    365: 
                    366: 
                    367: 
                    368: 
                    369: 
                    370: 
                    371: 
                    372: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.