home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / rcs.t.Z / rcs.t / RCS / SRC / rcsutil.c < prev    next >
Text File  |  1988-09-26  |  11KB  |  378 lines

  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);
  263. /*        cksignal(SIGPIPE);
  264.      cksignal(SIGTERM);
  265. */
  266.   }
  267.   
  268.  
  269. cksignal(sig)
  270. int    sig;
  271. {
  272.     if (signal(sig,SIG_IGN) != SIG_IGN)
  273.         VOID signal(sig,catchsig);
  274. }
  275.  
  276.   void ignoreints()
  277.   {
  278.         VOID signal(SIGINT,SIG_IGN); VOID signal(SIGHUP,SIG_IGN);
  279.         VOID signal(SIGQUIT,SIG_IGN);
  280. /*        VOID signal(SIGPIPE,SIG_IGN);
  281.     VOID signal(SIGTERM,SIG_IGN);
  282. */
  283.   }
  284.   
  285.   
  286. void restoreints()
  287. {
  288.         if (oldSIGINT!=SIG_IGN)
  289.                 VOID signal(SIGINT,catchsig);
  290.         VOID signal(SIGHUP,catchsig); VOID signal(SIGQUIT,catchsig);
  291. /*        VOID signal(SIGPIPE,catchsig); VOID signal(SIGTERM,catchsig);
  292. */
  293. }
  294.  
  295.  
  296. fastcopy(inf,outf)
  297. FILE * inf, * outf;
  298. /* Function: copies the remainder of file inf to outf. First copies the
  299.  * rest that is in the IO-buffer of inf character by character, and then
  300.  * copies the remainder in blocks.
  301.  */
  302. {       char buf[BUFSIZ];
  303.         register int rcount, wcount;
  304.  
  305.         /* write the rest of the buffer to outf */
  306.         while ( inf->_ptr - inf->_end ) {
  307.                 VOID putc(*inf->_ptr++&0377,outf);
  308.         }
  309.         if (fflush(outf) == EOF) {
  310.         faterror("write error");
  311.     }
  312.  
  313.         /*now read the rest of the file in blocks*/
  314.         while ((rcount=read(fileno(inf),buf,BUFSIZ))>0) {
  315.                 wcount=write(fileno(outf),buf,rcount);
  316.                 if (wcount!=rcount) {
  317.                     faterror("write error");
  318.                 }
  319.         }
  320. }
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327. #ifdef SNOOPFILE
  328.  
  329. #include "time.h"
  330. extern struct tm* localtime();
  331. extern long time();
  332.  
  333. logcommand(commandname,delta, sequence,login)
  334. char* commandname; struct hshentry * delta, * sequence[];char * login;
  335. /* Function: start a process to write the file that
  336.  * logs the RCS command.
  337.  * Each line in the log file contains the following information:
  338.  * operation, revision(r), backward deltas applied(b), forward deltas applied(f),
  339.  * total deltas present(t), creation date of delta(d), date of operation(o),
  340.  * login of caller, RCS file name.
  341.  */
  342. {
  343.         char command[200];
  344.         char curdate[datelength];
  345.         register int i, backward, forward;
  346.         long clock;
  347.         struct tm * tm;
  348.  
  349.         clock=time((long *)0);
  350.         tm=localtime(&clock);
  351.  
  352.         VOID sprintf(curdate,DATEFORM,
  353.                 tm->tm_year, tm->tm_mon+1, tm->tm_mday,
  354.                 tm->tm_hour, tm->tm_min, tm->tm_sec);
  355.  
  356.         i= backward=forward=0;
  357.         while(sequence[i]!=nil) {  /* count deltas to be applied*/
  358.         if (countnumflds(sequence[i]->num) == 2)
  359.                 backward++;  /* reverse delta */
  360.         else    forward++;   /* branch delta  */
  361.         i++;
  362.         }
  363.         VOID sprintf(command,"%s \"%s %10sr %3db %3df %3dt %sc %so %s %s\" &\n",
  364.                 SNOOP, commandname,delta->num,backward,forward,TotalDeltas,delta->date,
  365.                 curdate,login,bindex(RCSfilename,'/'));
  366.         VOID system(command);
  367. }
  368. #endif
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.