Annotation of 43BSDTahoe/new/rcs/src/rcsutil.c, revision 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.