xref: /dragonfly/gnu/usr.bin/rcs/lib/rcsbase.h (revision 86d7f5d3)
1 /* RCS common definitions and data structures */
2 
3 #define RCSBASE "$DragonFly: src/gnu/usr.bin/rcs/lib/rcsbase.h,v 1.3 2007/01/17 17:56:23 y0netan1 Exp $"
4 
5 /* Copyright 1982, 1988, 1989 Walter Tichy
6    Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
7    Distributed under license by the Free Software Foundation, Inc.
8 
9 This file is part of RCS.
10 
11 RCS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
15 
16 RCS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 along with RCS; see the file COPYING.
23 If not, write to the Free Software Foundation,
24 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 
26 Report problems and direct all questions to:
27 
28     rcs-bugs@cs.purdue.edu
29 
30 */
31 
32 /*
33  * $FreeBSD: src/gnu/usr.bin/rcs/lib/rcsbase.h,v 1.10 1999/08/27 23:36:44 peter Exp $
34  * $DragonFly: src/gnu/usr.bin/rcs/lib/rcsbase.h,v 1.3 2007/01/17 17:56:23 y0netan1 Exp $
35  *
36  * Revision 5.20  1995/06/16 06:19:24  eggert
37  * Update FSF address.
38  *
39  * Revision 5.19  1995/06/01 16:23:43  eggert
40  * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring.
41  * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros.
42  * (maps_memory): New macro; replaces many instances of `has_mmap'.
43  * (cacheptr): Renamed from cachetell.
44  * (struct RILE): New alternate name for RILE; the type is now recursive.
45  * (deallocate): New member for RILE, used for generic buffer deallocation.
46  * (cacheunget_): No longer take a failure arg; just call Ierror on failure.
47  * (struct rcslock): Renamed from struct lock, to avoid collisions with
48  * system headers on some hosts.  All users changed.
49  * (basefilename): Renamed from basename, likewise.
50  * (dirtpname): Remove; no longer external.
51  * (dirlen, dateform): Remove; no longer used.
52  * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions.
53  * (zonelenmax): Increase to 9 for full ISO 8601 format.
54  * (catchmmapints): Depend on has_NFS.
55  *
56  * Revision 5.18  1994/03/17 14:05:48  eggert
57  * Add primitives for reading backwards from a RILE;
58  * this is needed to go back and find the $Log prefix.
59  * Specify subprocess input via file descriptor, not file name.  Remove lint.
60  *
61  * Revision 5.17  1993/11/09 17:40:15  eggert
62  * Move RCS-specific time handling into rcstime.c.
63  * printf_string now takes two arguments, alas.
64  *
65  * Revision 5.16  1993/11/03 17:42:27  eggert
66  * Don't arbitrarily limit the number of joins.  Remove `nil'.
67  * Add Name keyword.  Don't discard ignored phrases.
68  * Add support for merge -A vs -E, and allow up to three labels.
69  * Improve quality of diagnostics and prototypes.
70  *
71  * Revision 5.15  1992/07/28  16:12:44  eggert
72  * Statement macro names now end in _.
73  *
74  * Revision 5.14  1992/02/17  23:02:22  eggert
75  * Add -T support.  Work around NFS mmap SIGBUS problem.
76  *
77  * Revision 5.13  1992/01/24  18:44:19  eggert
78  * Add support for bad_creat0.  lint -> RCS_lint
79  *
80  * Revision 5.12  1992/01/06  02:42:34  eggert
81  * while (E) ; -> while (E) continue;
82  *
83  * Revision 5.11  1991/10/07  17:32:46  eggert
84  * Support piece tables even if !has_mmap.
85  *
86  * Revision 5.10  1991/09/24  00:28:39  eggert
87  * Remove unexported functions.
88  *
89  * Revision 5.9  1991/08/19  03:13:55  eggert
90  * Add piece tables and other tuneups, and NFS workarounds.
91  *
92  * Revision 5.8  1991/04/21  11:58:20  eggert
93  * Add -x, RCSINIT, MS-DOS support.
94  *
95  * Revision 5.7  1991/02/28  19:18:50  eggert
96  * Try setuid() if seteuid() doesn't work.
97  *
98  * Revision 5.6  1991/02/26  17:48:37  eggert
99  * Support new link behavior.  Move ANSI C / Posix declarations into conf.sh.
100  *
101  * Revision 5.5  1990/12/04  05:18:43  eggert
102  * Use -I for prompts and -q for diagnostics.
103  *
104  * Revision 5.4  1990/11/01  05:03:35  eggert
105  * Don't assume that builtins are functions; they may be macros.
106  * Permit arbitrary data in logs.
107  *
108  * Revision 5.3  1990/09/26  23:36:58  eggert
109  * Port wait() to non-Posix ANSI C hosts.
110  *
111  * Revision 5.2  1990/09/04  08:02:20  eggert
112  * Don't redefine NAME_MAX, PATH_MAX.
113  * Improve incomplete line handling.  Standardize yes-or-no procedure.
114  *
115  * Revision 5.1  1990/08/29  07:13:53  eggert
116  * Add -kkvl.  Fix type typos exposed by porting.  Clean old log messages too.
117  *
118  * Revision 5.0  1990/08/22  08:12:44  eggert
119  * Adjust ANSI C / Posix support.  Add -k, -V, setuid.  Don't call access().
120  * Remove compile-time limits; use malloc instead.
121  * Ansify and Posixate.  Add support for ISO 8859.
122  * Remove snoop and v2 support.
123  *
124  * Revision 4.9  89/05/01  15:17:14  narten
125  * botched previous USG fix
126  *
127  * Revision 4.8  89/05/01  14:53:05  narten
128  * changed #include <strings.h> -> string.h for USG systems.
129  *
130  * Revision 4.7  88/11/08  15:58:45  narten
131  * removed defs for functions loaded from libraries
132  *
133  * Revision 4.6  88/08/09  19:12:36  eggert
134  * Shrink stdio code size; remove lint; permit -Dhshsize=nn.
135  *
136  * Revision 4.5  87/12/18  17:06:41  narten
137  * made removed BSD ifdef, now uses V4_2BSD
138  *
139  * Revision 4.4  87/10/18  10:29:49  narten
140  * Updating version numbers
141  * Changes relative to 1.1 are actually relative to 4.2
142  *
143  * Revision 1.3  87/09/24  14:02:25  narten
144  * changes for lint
145  *
146  * Revision 1.2  87/03/27  14:22:02  jenkins
147  * Port to suns
148  *
149  * Revision 4.2  83/12/20  16:04:20  wft
150  * merged 3.6.1.1 and 4.1 (SMALLOG, logsize).
151  * moved setting of STRICT_LOCKING to Makefile.
152  * changed DOLLAR to UNKN (conflict with KDELIM).
153  *
154  * Revision 4.1  83/05/04  09:12:41  wft
155  * Added markers Id and RCSfile.
156  * Added Dbranch for default branches.
157  *
158  * Revision 3.6.1.1  83/12/02  21:56:22  wft
159  * Increased logsize, added macro SMALLOG.
160  *
161  * Revision 3.6  83/01/15  16:43:28  wft
162  * 4.2 prerelease
163  *
164  * Revision 3.6  83/01/15  16:43:28  wft
165  * Replaced dbm.h with BYTESIZ, fixed definition of rindex().
166  * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD.
167  * Added macro DELNUMFORM to have uniform format for printing delta text nodes.
168  * Added macro DELETE to mark deleted deltas.
169  *
170  * Revision 3.5  82/12/10  12:16:56  wft
171  * Added two forms of DATEFORM, one using %02d, the other %.2d.
172  *
173  * Revision 3.4  82/12/04  20:01:25  wft
174  * added LOCKER, Locker, and USG (redefinition of rindex).
175  *
176  * Revision 3.3  82/12/03  12:22:04  wft
177  * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3,
178  * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength
179  * using NCPPN. Changed putc() to abort on write error.
180  *
181  * Revision 3.2  82/10/18  15:03:52  wft
182  * added macro STRICT_LOCKING, removed RCSUMASK.
183  * renamed JOINFILE[1,2] to JOINFIL[1,2].
184  *
185  * Revision 3.1  82/10/11  19:41:17  wft
186  * removed NBPW, NBPC, NCPW.
187  * added typdef int void to aid compiling
188  */
189 
190 
191 #include "conf.h"
192 
193 
194 #define EXIT_TROUBLE DIFF_TROUBLE
195 
196 #ifdef _POSIX_PATH_MAX
197 #	define SIZEABLE_PATH _POSIX_PATH_MAX
198 #else
199 #	define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */
200 #endif
201 
202 /* for traditional C hosts with unusual size arguments */
203 #define Fread(p,s,n,f)  fread(p, (freadarg_type)(s), (freadarg_type)(n), f)
204 #define Fwrite(p,s,n,f)  fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f)
205 
206 
207 /*
208  * Parameters
209  */
210 
211 /* backwards compatibility with old versions of RCS */
212 #define VERSION_min 3		/* old output RCS format supported */
213 #define VERSION_max 5		/* newest output RCS format supported */
214 #ifndef VERSION_DEFAULT		/* default RCS output format */
215 #	define VERSION_DEFAULT VERSION_max
216 #endif
217 #define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */
218 
219 #ifndef STRICT_LOCKING
220 #define STRICT_LOCKING 1
221 #endif
222 			      /* 0 sets the default locking to non-strict;  */
223                               /* used in experimental environments.         */
224                               /* 1 sets the default locking to strict;      */
225                               /* used in production environments.           */
226 
227 /* base64_encode(128 random bits) needs 24 bytes + 1 for NUL */
228 /* time_t may be 64bits on some machines needs 16 bytes + 1 as hex */
229 #define commitidsize	   64 /* time+1+base64(128bits)+1 | pid+time+rand+1 */
230 #define urandom_dev "/dev/urandom"
231 
232 #define yearlength	   16 /* (good through AD 9,999,999,999,999,999)    */
233 #define datesize (yearlength+16)	/* size of output of time2date */
234 #define RCSTMPPREFIX '_' /* prefix for temp files in working dir  */
235 #define KDELIM            '$' /* delimiter for keywords                     */
236 #define VDELIM            ':' /* separates keywords from values             */
237 #define DEFAULTSTATE    "Exp" /* default state of revisions                 */
238 
239 
240 
241 #define true     1
242 #define false    0
243 
244 
245 /*
246  * RILE - readonly file
247  * declarecache; - declares local cache for RILE variable(s)
248  * setupcache - sets up the local RILE cache, but does not initialize it
249  * cache, uncache - caches and uncaches the local RILE;
250  *	(uncache,cache) is needed around functions that advance the RILE pointer
251  * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF
252  * cachegeteof_(c,s) - Igeteof_ applied to the local RILE
253  * Iget_(f,c) - like Igeteof_, except EOF is an error
254  * cacheget_(c) - Iget_ applied to the local RILE
255  * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF
256  * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines
257  *
258  * By conventions, macros whose names end in _ are statements, not expressions.
259  * Following such macros with `; else' results in a syntax error.
260  */
261 
262 #define maps_memory (has_map_fd || has_mmap)
263 
264 #if large_memory
265 	typedef unsigned char const *Iptr_type;
266 	typedef struct RILE {
267 		Iptr_type ptr, lim;
268 		unsigned char *base; /* not Iptr_type for lint's sake */
269 		unsigned char *readlim;
270 		int fd;
271 #		if maps_memory
272 			void (*deallocate) P((struct RILE *));
273 #		else
274 			FILE *stream;
275 #		endif
276 	} RILE;
277 #	if maps_memory
278 #		define declarecache register Iptr_type ptr, lim
279 #		define setupcache(f) (lim = (f)->lim)
280 #		define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++;
281 #		define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++;
282 #	else
283 		int Igetmore P((RILE*));
284 #		define declarecache register Iptr_type ptr; register RILE *rRILE
285 #		define setupcache(f) (rRILE = (f))
286 #		define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++;
287 #		define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++;
288 #	endif
289 #	define uncache(f) ((f)->ptr = ptr)
290 #	define cache(f) (ptr = (f)->ptr)
291 #	define Iget_(f,c) Igeteof_(f,c,Ieof();)
292 #	define cacheget_(c) cachegeteof_(c,Ieof();)
293 #	define cacheunget_(f,c) (c)=(--ptr)[-1];
294 #	define Ioffset_type size_t
295 #	define Itell(f) ((f)->ptr - (f)->base)
296 #	define Irewind(f) ((f)->ptr = (f)->base)
297 #	define cacheptr() ptr
298 #	define Ifileno(f) ((f)->fd)
299 #else
300 #	define RILE FILE
301 #	define declarecache register FILE *ptr
302 #	define setupcache(f) (ptr = (f))
303 #	define uncache(f)
304 #	define cache(f)
305 #	define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}}
306 #	define cachegeteof_(c,s) Igeteof_(ptr,c,s)
307 #	define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); }
308 #	define cacheget_(c) Iget_(ptr,c)
309 #	define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c)
310 #	define Ioffset_type long
311 #	define Itell(f) ftell(f)
312 #	define Ifileno(f) fileno(f)
313 #endif
314 
315 /* Print a char, but abort on write error.  */
316 #define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
317 
318 /* Get a character from an RCS file, perhaps copying to a new RCS file.  */
319 #define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
320 #define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
321 
322 
323 #define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
324 /* computes mode of working file: same as RCSmode, but write permission     */
325 /* determined by writable */
326 
327 
328 /* character classes and token codes */
329 enum tokens {
330 /* classes */	DELIM,	DIGIT,	IDCHAR,	NEWLN,	LETTER,	Letter,
331 		PERIOD,	SBEGIN,	SPACE,	UNKN,
332 /* tokens */	COLON,	ID,	NUM,	SEMI,	STRING
333 };
334 
335 #define SDELIM  '@'     /* the actual character is needed for string handling*/
336 /* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
337  * there should be no overlap among SDELIM, KDELIM, and VDELIM
338  */
339 
340 #define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
341 
342 
343 
344 
345 
346 /***************************************
347  * Data structures for the symbol table
348  ***************************************/
349 
350 /* Buffer of arbitrary data */
351 struct buf {
352 	char *string;
353 	size_t size;
354 };
355 struct cbuf {
356 	char const *string;
357 	size_t size;
358 };
359 
360 /* Hash table entry */
361 struct hshentry {
362 	char const	  * num;      /* pointer to revision number (ASCIZ) */
363 	char const	  * date;     /* pointer to date of checkin	    */
364 	char const	  * author;   /* login of person checking in	    */
365 	char const	  * lockedby; /* who locks the revision		    */
366 	char const	  * state;    /* state of revision (Exp by default) */
367 	char const	  * name;     /* name (if any) by which retrieved   */
368 	char const        * commitid; /* text string to associate commits   */
369 	struct cbuf	    log;      /* log message requested at checkin   */
370         struct branchhead * branches; /* list of first revisions on branches*/
371 	struct cbuf	    ig;	      /* ignored phrases in admin part	    */
372 	struct cbuf	    igtext;   /* ignored phrases in deltatext part  */
373         struct hshentry   * next;     /* next revision on same branch       */
374 	struct hshentry   * nexthsh;  /* next revision with same hash value */
375 	long		    insertlns;/* lines inserted (computed by rlog)  */
376 	long		    deletelns;/* lines deleted  (computed by rlog)  */
377 	char		    selector; /* true if selected, false if deleted */
378 };
379 
380 /* list of hash entries */
381 struct hshentries {
382 	struct hshentries *rest;
383 	struct hshentry *first;
384 };
385 
386 /* list element for branch lists */
387 struct branchhead {
388         struct hshentry   * hsh;
389         struct branchhead * nextbranch;
390 };
391 
392 /* accesslist element */
393 struct access {
394 	char const	  * login;
395         struct access     * nextaccess;
396 };
397 
398 /* list element for locks  */
399 struct rcslock {
400 	char const	  * login;
401         struct hshentry   * delta;
402 	struct rcslock    * nextlock;
403 };
404 
405 /* list element for symbolic names */
406 struct assoc {
407 	char const	  * symbol;
408 	char const	  * num;
409         struct assoc      * nextassoc;
410 };
411 
412 
413 #define mainArgs (argc,argv) int argc; char **argv;
414 
415 #if RCS_lint
416 #	define libId(name,rcsid)
417 #	define mainProg(name,cmd,rcsid) int name mainArgs
418 #else
419 #	define libId(name,rcsid) char const name[] = rcsid;
420 #	define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs
421 #endif
422 
423 /*
424  * Markers for keyword expansion (used in co and ident)
425  *	Every byte must have class LETTER or Letter.
426  */
427 #define AUTHOR          "Author"
428 #define DATE            "Date"
429 #define HEADER          "Header"
430 #define IDH             "Id"
431 #define LOCKER          "Locker"
432 #define LOG             "Log"
433 #define NAME		"Name"
434 #define RCSFILE         "RCSfile"
435 #define REVISION        "Revision"
436 #define SOURCE          "Source"
437 #define STATE           "State"
438 #define CVSHEADER       "CVSHeader"
439 #define keylength 9 /* max length of any of the above keywords */
440 
441 enum markers { Nomatch, Author, Date, Header, Id,
442 	       Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader,
443 	       LocalId };
444 	/* This must be in the same order as rcskeys.c's Keyword[] array. */
445 
446 #define DELNUMFORM      "\n\n%s\n%s\n"
447 /* used by putdtext and scanlogtext */
448 
449 #define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
450 
451 /* main program */
452 extern char const cmdid[];
453 void exiterr P((void)) exiting;
454 
455 /* merge */
456 int merge P((int,char const*,char const*const[3],char const*const[3]));
457 
458 /* rcsedit */
459 #define ciklogsize 23 /* sizeof("checked in with -k by ") */
460 extern FILE *fcopy;
461 extern char const *resultname;
462 extern char const ciklog[ciklogsize];
463 extern int locker_expansion;
464 RILE *rcswriteopen P((struct buf*,struct stat*,int));
465 char const *makedirtemp P((int));
466 char const *getcaller P((void));
467 int addlock P((struct hshentry*,int));
468 int addsymbol P((char const*,char const*,int));
469 int checkaccesslist P((void));
470 int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t));
471 int donerewrite P((int,time_t));
472 int dorewrite P((int,int));
473 int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int));
474 int findlock P((int,struct hshentry**));
475 int setmtime P((char const*,time_t));
476 void ORCSclose P((void));
477 void ORCSerror P((void));
478 void copystring P((void));
479 void dirtempunlink P((void));
480 void enterstring P((void));
481 void finishedit P((struct hshentry const*,FILE*,int));
482 void keepdirtemp P((char const*));
483 void openfcopy P((FILE*));
484 void snapshotedit P((FILE*));
485 void xpandstring P((struct hshentry const*));
486 #if has_NFS || bad_unlink
487 	int un_link P((char const*));
488 #else
489 #	define un_link(s) unlink(s)
490 #endif
491 #if large_memory
492 	void edit_string P((void));
493 #	define editstring(delta) edit_string()
494 #else
495 	void editstring P((struct hshentry const*));
496 #endif
497 
498 /* rcsfcmp */
499 int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
500 
501 /* rcsfnms */
502 #define bufautobegin(b) clear_buf(b)
503 #define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0))
504 extern FILE *workstdout;
505 extern char *workname;
506 extern char const *RCSname;
507 extern char const *suffixes;
508 extern int fdlock;
509 extern struct stat RCSstat;
510 RILE *rcsreadopen P((struct buf*,struct stat*,int));
511 char *bufenlarge P((struct buf*,char const**));
512 char const *basefilename P((char const*));
513 char const *getfullRCSname P((void));
514 char const *getfullCVSname P((void));
515 char const *maketemp P((int));
516 char const *rcssuffix P((char const*));
517 int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
518 struct cbuf bufremember P((struct buf*,size_t));
519 void bufalloc P((struct buf*,size_t));
520 void bufautoend P((struct buf*));
521 void bufrealloc P((struct buf*,size_t));
522 void bufscat P((struct buf*,char const*));
523 void bufscpy P((struct buf*,char const*));
524 void tempunlink P((void));
525 
526 /* rcsgen */
527 extern int interactiveflag;
528 extern struct buf curlogbuf;
529 char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
530 int getcstdin P((void));
531 int putdtext P((struct hshentry const*,char const*,FILE*,int));
532 int ttystdin P((void));
533 int yesorno P((int,char const*,...)) printf_string(2,3);
534 struct cbuf cleanlogmsg P((char*,size_t));
535 struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
536 void putdesc P((int,char*));
537 void putdftext P((struct hshentry const*,RILE*,FILE*,int));
538 
539 /* rcskeep */
540 extern int prevkeys;
541 extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
542 int getoldkeys P((RILE*));
543 
544 /* rcskeys */
545 extern char const *Keyword[];
546 extern enum markers LocalIdMode;
547 enum markers trymatch P((char const*));
548 void setRCSLocalId(char const *);
549 void setIncExc(char const *);
550 
551 /* rcslex */
552 extern FILE *foutptr;
553 extern FILE *frewrite;
554 extern RILE *finptr;
555 extern char const *NextString;
556 extern enum tokens nexttok;
557 extern int hshenter;
558 extern int nerror;
559 extern int nextc;
560 extern int quietflag;
561 extern long rcsline;
562 char const *getid P((void));
563 void efaterror P((char const*)) exiting;
564 void enfaterror P((int,char const*)) exiting;
565 void fatcleanup P((int)) exiting;
566 void faterror P((char const*,...)) printf_string_exiting(1,2);
567 void fatserror P((char const*,...)) printf_string_exiting(1,2);
568 void rcsfaterror P((char const*,...)) printf_string_exiting(1,2);
569 void Ieof P((void)) exiting;
570 void Ierror P((void)) exiting;
571 void Oerror P((void)) exiting;
572 char *checkid P((char*,int));
573 char *checksym P((char*,int));
574 int eoflex P((void));
575 int getkeyopt P((char const*));
576 int getlex P((enum tokens));
577 struct cbuf getphrases P((char const*));
578 struct cbuf savestring P((struct buf*));
579 struct hshentry *getnum P((void));
580 void Ifclose P((RILE*));
581 void Izclose P((RILE**));
582 void Lexinit P((void));
583 void Ofclose P((FILE*));
584 void Orewind P((FILE*));
585 void Ozclose P((FILE**));
586 void aflush P((FILE*));
587 void afputc P((int,FILE*));
588 void aprintf P((FILE*,char const*,...)) printf_string(2,3);
589 void aputs P((char const*,FILE*));
590 void checksid P((char*));
591 void checkssym P((char*));
592 void diagnose P((char const*,...)) printf_string(1,2);
593 void eerror P((char const*));
594 void eflush P((void));
595 void enerror P((int,char const*));
596 void error P((char const*,...)) printf_string(1,2);
597 void fvfprintf P((FILE*,char const*,va_list));
598 void getkey P((char const*));
599 void getkeystring P((char const*));
600 void nextlex P((void));
601 void oflush P((void));
602 void printstring P((void));
603 void readstring P((void));
604 void redefined P((int));
605 void rcserror P((char const*,...)) printf_string(1,2);
606 void rcswarn P((char const*,...)) printf_string(1,2);
607 void testIerror P((FILE*));
608 void testOerror P((FILE*));
609 void warn P((char const*,...)) printf_string(1,2);
610 void warnignore P((void));
611 void workerror P((char const*,...)) printf_string(1,2);
612 void workwarn P((char const*,...)) printf_string(1,2);
613 #if has_madvise && has_mmap && large_memory
614 	void advise_access P((RILE*,int));
615 #	define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
616 #else
617 #	define advise_access(f,advice)
618 #	define if_advise_access(p,f,advice)
619 #endif
620 #if large_memory && maps_memory
621 	RILE *I_open P((char const*,struct stat*));
622 #	define Iopen(f,m,s) I_open(f,s)
623 #else
624 	RILE *Iopen P((char const*,char const*,struct stat*));
625 #endif
626 #if !large_memory
627 	void testIeof P((FILE*));
628 	void Irewind P((RILE*));
629 #endif
630 
631 /* rcsmap */
632 extern enum tokens const ctab[];
633 
634 /* rcsrev */
635 char *partialno P((struct buf*,char const*,int));
636 char const *namedrev P((char const*,struct hshentry*));
637 char const *tiprev P((void));
638 int cmpdate P((char const*,char const*));
639 int cmpnum P((char const*,char const*));
640 int cmpnumfld P((char const*,char const*,int));
641 int compartial P((char const*,char const*,int));
642 int expandsym P((char const*,struct buf*));
643 int fexpandsym P((char const*,struct buf*,RILE*));
644 struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
645 int countnumflds P((char const*));
646 void getbranchno P((char const*,struct buf*));
647 
648 /* rcssyn */
649 /* These expand modes must agree with Expand_names[] in rcssyn.c.  */
650 #define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
651 #define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
652 #define KEY_EXPAND 2 /* -kk `$Keyword$' */
653 #define VAL_EXPAND 3 /* -kv `value' */
654 #define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
655 #define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
656 #define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
657 #define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND)
658 			/* min value guaranteed to yield an identical file */
659 struct diffcmd {
660 	long
661 		line1, /* number of first line */
662 		nlines, /* number of lines affected */
663 		adprev, /* previous 'a' line1+1 or 'd' line1 */
664 		dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
665 };
666 extern char const      * Dbranch;
667 extern struct access   * AccessList;
668 extern struct assoc    * Symbols;
669 extern struct cbuf Comment;
670 extern struct cbuf Ignored;
671 extern struct rcslock *Locks;
672 extern struct hshentry * Head;
673 extern int		 Expand;
674 extern int               StrictLocks;
675 extern int               TotalDeltas;
676 extern char const *const expand_names[];
677 extern char const
678 	Kaccess[], Kauthor[], Kbranch[], Kcomment[],
679 	Kcommitid[],
680 	Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
681 	Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
682 void unexpected_EOF P((void)) exiting;
683 int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
684 int str2expmode P((char const*));
685 void getadmin P((void));
686 void getdesc P((int));
687 void gettree P((void));
688 void ignorephrases P((char const*));
689 void initdiffcmd P((struct diffcmd*));
690 void putadmin P((void));
691 void putstring P((FILE*,int,struct cbuf,int));
692 void puttree P((struct hshentry const*,FILE*));
693 
694 /* rcstime */
695 #define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
696 char const *date2str P((char const[datesize],char[datesize + zonelenmax]));
697 time_t date2time P((char const[datesize]));
698 void str2date P((char const*,char[datesize]));
699 void time2date P((time_t,char[datesize]));
700 void zone_set P((char const*));
701 
702 /* rcsutil */
703 extern int RCSversion;
704 FILE *fopenSafer P((char const*,char const*));
705 char *cgetenv P((char const*));
706 char *fstr_save P((char const*));
707 char *str_save P((char const*));
708 char const *getusername P((int));
709 int fdSafer P((int));
710 int getRCSINIT P((int,char**,char***));
711 int run P((int,char const*,...));
712 int runv P((int,char const*,char const**));
713 malloc_type fremember P((malloc_type));
714 malloc_type ftestalloc P((size_t));
715 malloc_type testalloc P((size_t));
716 malloc_type testrealloc P((malloc_type,size_t));
717 #define ftalloc(T) ftnalloc(T,1)
718 #define talloc(T) tnalloc(T,1)
719 #if RCS_lint
720 	extern malloc_type lintalloc;
721 #	define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
722 #	define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
723 #	define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
724 #	define tfree(p)
725 #else
726 #	define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
727 #	define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
728 #	define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
729 #	define tfree(p) free((malloc_type)(p))
730 #endif
731 time_t now P((void));
732 void awrite P((char const*,size_t,FILE*));
733 void fastcopy P((RILE*,FILE*));
734 void ffree P((void));
735 void ffree1 P((char const*));
736 void setRCSversion P((char const*));
737 #if has_signal
738 	void catchints P((void));
739 	void ignoreints P((void));
740 	void restoreints P((void));
741 #else
742 #	define catchints()
743 #	define ignoreints()
744 #	define restoreints()
745 #endif
746 #if has_mmap && large_memory
747 #   if has_NFS && mmap_signal
748 	void catchmmapints P((void));
749 	void readAccessFilenameBuffer P((char const*,unsigned char const*));
750 #   else
751 #	define catchmmapints()
752 #   endif
753 #endif
754 #if has_getuid
755 	uid_t ruid P((void));
756 #	define myself(u) ((u) == ruid())
757 #else
758 #	define myself(u) true
759 #endif
760 #if has_setuid
761 	uid_t euid P((void));
762 	void nosetid P((void));
763 	void seteid P((void));
764 	void setrid P((void));
765 #else
766 #	define nosetid()
767 #	define seteid()
768 #	define setrid()
769 #endif
770 
771 /* version */
772 extern char const RCS_version_string[];
773