|
|
1.1 root 1: /*
2: * RCS utilities
3: */
4: static char rcsid[]=
5: "$Header: /usr/wft/RCS/SRC/RCS/rcsutil.c,v 3.8 83/02/15 15:41:49 wft Exp $ Purdue CS";
6: /*****************************************************************************
7: *****************************************************************************
8: *
9: * Copyright (C) 1982 by Walter F. Tichy
10: * Purdue University
11: * Computer Science Department
12: * West Lafayette, IN 47907
13: *
14: * All rights reserved. No part of this software may be sold or distributed
15: * in any form or by any means without the prior written permission of the
16: * author.
17: * Report problems and direct all inquiries to Tichy@purdue (ARPA net).
18: */
19:
20:
21:
22: /* $Log: rcsutil.c,v $
23: * Revision 3.8 83/02/15 15:41:49 wft
24: * Added routine fastcopy() to copy remainder of a file in blocks.
25: *
26: * Revision 3.7 82/12/24 15:25:19 wft
27: * added catchints(), ignoreints() for catching and ingnoring interrupts;
28: * fixed catchsig().
29: *
30: * Revision 3.6 82/12/08 21:52:05 wft
31: * Using DATEFORM to format dates.
32: *
33: * Revision 3.5 82/12/04 18:20:49 wft
34: * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update
35: * lockedby-field.
36: *
37: * Revision 3.4 82/12/03 17:17:43 wft
38: * Added check to addlock() ensuring only one lock per person.
39: * Addlock also returns a pointer to the lock created. Deleted fancydate().
40: *
41: * Revision 3.3 82/11/27 12:24:37 wft
42: * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c.
43: * Introduced macro SNOOP so that snoop can be placed in directory other than
44: * TARGETDIR. Changed %02d to %.2d for compatibility reasons.
45: *
46: * Revision 3.2 82/10/18 21:15:11 wft
47: * added function getfullRCSname().
48: *
49: * Revision 3.1 82/10/13 16:17:37 wft
50: * Cleanup message is now suppressed in quiet mode.
51: */
52:
53:
54:
55:
56: #include <sys/types.h>
57: #include <sys/stat.h>
58: #include <signal.h>
59: #include "rcsbase.h"
60:
61: extern char * malloc();
62: extern FILE * finptr;
63: extern char * getfullRCSname();
64:
65: struct hshentry dummy; /* dummy delta for reservations */
66:
67:
68: struct lock * addlock(delta,who)
69: struct hshentry * delta; char * who;
70: /* Given a delta, addlock checks whether
71: * the delta is locked by somebody other than who.
72: * If so, an error message is printed, and false returned.
73: * If the delta is not reserved at all, a lock for it is added,
74: * and a pointer for the lock returned.
75: */
76: {
77: struct lock * next;
78:
79: next=Locks;
80: while (next!=nil) {
81: if (cmpnum(delta->num,next->delta->num)==0) {
82: if (strcmp(who,next->login)==0)
83: return next;
84: /* lock exists already */
85: else {
86: error("revision %s already locked by %s",
87: delta->num, next->login);
88: return false;
89: }
90: } else {
91: if (strcmp(who,next->login)==0) {
92: error("you already locked %s; only one lock allowed per person.",
93: next->delta->num);
94: return false;
95: } else {
96: next=next->nextlock;
97: }
98: }
99: }
100: /* not found; set up new lockblock */
101: next= (struct lock *) malloc(sizeof (struct lock));
102: delta->lockedby=next->login=who;
103: next->delta= delta;
104: next->nextlock=Locks;
105: Locks=next;
106: return next;
107: }
108:
109:
110:
111: int addsymbol(delta,name,rebind)
112: struct hshentry * delta; char * name; int rebind;
113: /* Function: adds a new symbolic name and associates it with node delta.
114: * If name already exists and rebind is true, the name is associated
115: * with the new delta; otherwise, an error message is printed and
116: * false returned. Returns true it successful.
117: */
118: { register struct assoc * next;
119: next=Symbols;
120: while (next!=nil) {
121: if (strcmp(name,next->symbol)==0) {
122: if (rebind) {
123: next->delta=delta;
124: return true;
125: } else {
126: error("symbolic name %s already bound to %s",
127: name,next->delta->num);
128: return false;
129: }
130: } else next = next->nextassoc;
131: }
132: /* not found; insert new pair. */
133: next = (struct assoc *) malloc(sizeof(struct assoc));
134: next->symbol=name;
135: next->delta=delta;
136: next->nextassoc=Symbols;
137: Symbols = next;
138: return true;
139: }
140:
141:
142:
143:
144: int checkaccesslist(who)
145: char * who;
146: /* function: Returns true if who is the superuser, the owner of the
147: * file, the access list is empty, or who is on the access list.
148: * Prints an error message and returns false otherwise.
149: */
150: {
151: register struct access * next;
152: struct stat statbuf;
153:
154: if ((AccessList==nil) || (strcmp(who,"root")==0))
155: return true;
156:
157: next=AccessList;
158: do {
159: if (strcmp(who,next->login)==0)
160: return true;
161: next=next->nextaccess;
162: } while (next!=nil);
163:
164: fstat(fileno(finptr),&statbuf); /* get owner of file */
165: if (getuid() == statbuf.st_uid) return true;
166:
167: error("User %s not on the access list",who);
168: return false;
169: }
170:
171: void catchsig(sig)
172: {
173: signal(sig, SIG_IGN);
174: diagnose("\nRCS: cleaning up\n");
175: cleanup();
176: exit(1);
177: }
178:
179: void catchints()
180: {
181: signal(SIGINT,catchsig); signal(SIGHUP,catchsig);
182: signal(SIGQUIT,catchsig); signal(SIGPIPE,catchsig);
183: signal(SIGTERM,catchsig);
184: }
185:
186: void ignoreints()
187: {
188: signal(SIGINT,SIG_IGN); signal(SIGHUP,SIG_IGN);
189: signal(SIGQUIT,SIG_IGN); signal(SIGPIPE,SIG_IGN);
190: signal(SIGTERM,SIG_IGN);
191: }
192:
193:
194: fastcopy(inf,outf)
195: FILE * inf, * outf;
196: /* Function: copies the remainder of file inf to outf. First copies the
197: * rest that is in the IO-buffer of inf character by character, and then
198: * copies the remainder in blocks.
199: */
200: { char buf[BUFSIZ];
201: register int rcount, wcount;
202:
203: /* write the rest of the buffer to outf */
204: while ((--inf->_cnt)>=0) {
205: putc(*inf->_ptr++&0377,outf);
206: }
207: fflush(outf);
208:
209: /*now read the rest of the file in blocks*/
210: while ((rcount=read(fileno(inf),buf,BUFSIZ))>0) {
211: wcount=write(fileno(outf),buf,rcount);
212: if (wcount!=rcount) {
213: faterror("write error");
214: }
215: }
216: }
217:
218:
219:
220:
221:
222:
223: #ifdef SNOOPFILE
224:
225: #include "time.h"
226: extern struct tm* localtime();
227: extern long time();
228:
229: logcommand(commandname,delta, sequence,login)
230: char* commandname; struct hshentry * delta, * sequence[];char * login;
231: /* Function: start a process to write the file that
232: * logs the RCS command.
233: * Each line in the log file contains the following information:
234: * operation, revision(r), backward deltas applied(b), forward deltas applied(f),
235: * total deltas present(t), creation date of delta(d), date of operation(o),
236: * login of caller, full path of RCS file
237: */
238: {
239: char command[200];
240: char curdate[datelength];
241: register int i, backward, forward;
242: long clock;
243: struct tm * tm;
244:
245: clock=time(0);
246: tm=localtime(&clock);
247:
248: sprintf(curdate,DATEFORM,
249: tm->tm_year, tm->tm_mon+1, tm->tm_mday,
250: tm->tm_hour, tm->tm_min, tm->tm_sec);
251:
252: i= backward=forward=0;
253: while(sequence[i]!=nil) { /* count deltas to be applied*/
254: if (countnumflds(sequence[i]->num) == 2)
255: backward++; /* reverse delta */
256: else forward++; /* branch delta */
257: i++;
258: }
259: sprintf(command,"%s \"%s %10sr %3db %3df %3dt %sc %so %s %s\" &\n",
260: SNOOP, commandname,delta->num,backward,forward,TotalDeltas,delta->date,
261: curdate,login,getfullRCSname());
262: system(command);
263: }
264: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.