1 /* $MirOS: src/gnu/usr.bin/rcs/src/rcsbase.h,v 1.5 2009/07/18 13:10:34 tg Exp $ */
2 
3 /* RCS common definitions and data structures */
4 
5 #define RCSBASE "$MirOS: src/gnu/usr.bin/rcs/src/rcsbase.h,v 1.5 2009/07/18 13:10:34 tg Exp $"
6 
7 /* Copyright 1982, 1988, 1989 Walter F. Tichy, Purdue CS
8    Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
9    Distributed under license by the Free Software Foundation, Inc.
10 
11 This file is part of RCS.
12 
13 RCS is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2, or (at your option)
16 any later version.
17 
18 RCS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with RCS; see the file COPYING.
25 If not, write to the Free Software Foundation,
26 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 
28 Report problems and direct all questions to:
29 
30     rcs-bugs@cs.purdue.edu
31 
32 */
33 
34 /*
35  * $Log: rcsbase.h,v $
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, (size_t)(s), (size_t)(n), f)
204 #define Fwrite(p,s,n,f)  fwrite(p, (size_t)(s), (size_t)(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 #define yearlength	   16 /* (good through AD 9,999,999,999,999,999)    */
228 #define datesize (yearlength+16)	/* size of output of time2date */
229 #define RCSTMPPREFIX '_' /* prefix for temp files in working dir  */
230 #define KDELIM            '$' /* delimiter for keywords                     */
231 #define VDELIM            ':' /* separates keywords from values             */
232 #define DEFAULTSTATE    "Exp" /* default state of revisions                 */
233 
234 
235 
236 #define true     1
237 #define false    0
238 
239 
240 /*
241  * RILE - readonly file
242  * declarecache; - declares local cache for RILE variable(s)
243  * setupcache - sets up the local RILE cache, but does not initialize it
244  * cache, uncache - caches and uncaches the local RILE;
245  *	(uncache,cache) is needed around functions that advance the RILE pointer
246  * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF
247  * cachegeteof_(c,s) - Igeteof_ applied to the local RILE
248  * Iget_(f,c) - like Igeteof_, except EOF is an error
249  * cacheget_(c) - Iget_ applied to the local RILE
250  * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF
251  * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines
252  *
253  * By conventions, macros whose names end in _ are statements, not expressions.
254  * Following such macros with `; else' results in a syntax error.
255  */
256 
257 #define maps_memory (has_map_fd || has_mmap)
258 
259 	typedef unsigned char const *Iptr_type;
260 	typedef struct RILE {
261 		Iptr_type ptr, lim;
262 		unsigned char *base; /* not Iptr_type for lint's sake */
263 		unsigned char *readlim;
264 		int fd;
265 			void (*deallocate)(struct RILE *);
266 	} RILE;
267 #		define declarecache register Iptr_type ptr, lim
268 #		define setupcache(f) (lim = (f)->lim)
269 #		define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++;
270 #		define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++;
271 #	define uncache(f) ((f)->ptr = ptr)
272 #	define cache(f) (ptr = (f)->ptr)
273 #	define Iget_(f,c) Igeteof_(f,c,Ieof();)
274 #	define cacheget_(c) cachegeteof_(c,Ieof();)
275 #	define cacheunget_(f,c) (c)=(--ptr)[-1];
276 #	define Ioffset_type size_t
277 #	define Itell(f) ((f)->ptr - (f)->base)
278 #	define Irewind(f) ((f)->ptr = (f)->base)
279 #	define cacheptr() ptr
280 #	define Ifileno(f) ((f)->fd)
281 
282 /* Print a char, but abort on write error.  */
283 #define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
284 
285 /* Get a character from an RCS file, perhaps copying to a new RCS file.  */
286 #define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
287 #define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
288 
289 
290 #define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
291 /* computes mode of working file: same as RCSmode, but write permission     */
292 /* determined by writable */
293 
294 
295 /* character classes and token codes */
296 enum tokens {
297 /* classes */	DELIM,	DIGIT,	IDCHAR,	NEWLN,	LETTER,	Letter,
298 		PERIOD,	SBEGIN,	SPACE,	UNKN,
299 /* tokens */	COLON,	ID,	NUM,	SEMI,	STRING
300 };
301 
302 #define SDELIM  '@'     /* the actual character is needed for string handling*/
303 /* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
304  * there should be no overlap among SDELIM, KDELIM, and VDELIM
305  */
306 
307 #define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
308 
309 
310 
311 
312 
313 /***************************************
314  * Data structures for the symbol table
315  ***************************************/
316 
317 /* Buffer of arbitrary data */
318 struct buf {
319 	char *string;
320 	size_t size;
321 };
322 struct cbuf {
323 	char const *string;
324 	size_t size;
325 };
326 
327 /* Hash table entry */
328 struct hshentry {
329 	char const	  * num;      /* pointer to revision number (ASCIZ) */
330 	char const	  * date;     /* pointer to date of checkin	    */
331 	char const	  * author;   /* login of person checking in	    */
332 	char const	  * lockedby; /* who locks the revision		    */
333 	char const	  * state;    /* state of revision (Exp by default) */
334 	char const	  * name;     /* name (if any) by which retrieved   */
335 	char const	  * commitid; /* unique commit ID (CVS extension)   */
336 	struct cbuf	    log;      /* log message requested at checkin   */
337         struct branchhead * branches; /* list of first revisions on branches*/
338 	struct cbuf	    ig;	      /* ignored phrases in admin part	    */
339 	struct cbuf	    igtext;   /* ignored phrases in deltatext part  */
340         struct hshentry   * next;     /* next revision on same branch       */
341 	struct hshentry   * nexthsh;  /* next revision with same hash value */
342 	long		    insertlns;/* lines inserted (computed by rlog)  */
343 	long		    deletelns;/* lines deleted  (computed by rlog)  */
344 	char		    selector; /* true if selected, false if deleted */
345 };
346 
347 /* list of hash entries */
348 struct hshentries {
349 	struct hshentries *rest;
350 	struct hshentry *first;
351 };
352 
353 /* list element for branch lists */
354 struct branchhead {
355         struct hshentry   * hsh;
356         struct branchhead * nextbranch;
357 };
358 
359 /* accesslist element */
360 struct access {
361 	char const	  * login;
362         struct access     * nextaccess;
363 };
364 
365 /* list element for locks  */
366 struct rcslock {
367 	char const	  * login;
368         struct hshentry   * delta;
369 	struct rcslock    * nextlock;
370 };
371 
372 /* list element for symbolic names */
373 struct assoc {
374 	char const	  * symbol;
375 	char const	  * num;
376         struct assoc      * nextassoc;
377 };
378 
379 /*
380  * Markers for keyword expansion (used in co and ident)
381  *	Every byte must have class LETTER or Letter.
382  */
383 #define AUTHOR          "Author"
384 #define DATE            "Date"
385 #define HEADER          "Header"
386 #define IDH             "Id"
387 #define LOCKER          "Locker"
388 #define LOG             "Log"
389 #define NAME		"Name"
390 #define RCSFILE         "RCSfile"
391 #define REVISION        "Revision"
392 #define SOURCE          "Source"
393 #define STATE           "State"
394 #define keylength	12	/* max length of any of the above keywords */
395 
396 enum markers { Nomatch, Author, Date, Header, Id,
397 	       Locker, Log, Name, RCSfile, Revision, Source, State, LocalId };
398 	/* This must be in the same order as rcskeys.c's Keyword[] array. */
399 
400 #define DELNUMFORM      "\n\n%s\n%s\n"
401 /* used by putdtext and scanlogtext */
402 
403 #define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
404 
405 /* main program */
406 extern char const cmdid[];
407 __dead void exiterr(void);
408 
409 /* merge */
410 int merge(int,char const*,char const*const[3],char const*const[3]);
411 
412 /* rcsedit */
413 #define ciklogsize 23 /* sizeof("checked in with -k by ") */
414 extern FILE *fcopy;
415 extern char const *resultname;
416 extern char const ciklog[ciklogsize];
417 extern int locker_expansion;
418 RILE *rcswriteopen(struct buf*,struct stat*,int);
419 char const *makedirtemp(int);
420 char const *getcaller(void);
421 int addlock(struct hshentry*,int);
422 int addsymbol(char const*,char const*,int);
423 int checkaccesslist(void);
424 int chnamemod(FILE**,char const*,char const*,int,mode_t,time_t);
425 int donerewrite(int,time_t);
426 int dorewrite(int,int);
427 int expandline(RILE*,FILE*,struct hshentry const*,int,FILE*,int);
428 int findlock(int,struct hshentry**);
429 int setmtime(char const*,time_t);
430 void ORCSclose(void);
431 void ORCSerror(void);
432 void copystring(void);
433 void dirtempunlink(void);
434 void enterstring(void);
435 void finishedit(struct hshentry const*,FILE*,int);
436 void keepdirtemp(char const*);
437 void openfcopy(FILE*);
438 void snapshotedit(FILE*);
439 void xpandstring(struct hshentry const*);
440 #if has_NFS || bad_unlink
441 	int un_link(char const*);
442 #else
443 #	define un_link(s) unlink(s)
444 #endif
445 	void edit_string(void);
446 #	define editstring(delta) edit_string()
447 
448 /* rcsfcmp */
449 int rcsfcmp(RILE*,struct stat const*,char const*,struct hshentry const*);
450 
451 /* rcsfnms */
452 #define bufautobegin(b) clear_buf(b)
453 #define clear_buf(b) (((b)->string = 0, (b)->size = 0))
454 extern FILE *workstdout;
455 extern char *workname;
456 extern char const *RCSname;
457 extern char const *suffixes;
458 extern int fdlock;
459 extern struct stat RCSstat;
460 RILE *rcsreadopen(struct buf*,struct stat*,int);
461 char *bufenlarge(struct buf*,char const**);
462 char const *basefilename(char const*);
463 char const *getfullRCSname(void);
464 char const *maketemp(int);
465 char const *rcssuffix(char const*);
466 int pairnames(int,char**,RILE*(*)(struct buf*,struct stat*,int),int,int);
467 struct cbuf bufremember(struct buf*,size_t);
468 void bufalloc(struct buf*,size_t);
469 void bufautoend(struct buf*);
470 void bufrealloc(struct buf*,size_t);
471 void bufscat(struct buf*,char const*);
472 void bufscpy(struct buf*,char const*);
473 void tempunlink(void);
474 
475 /* rcsgen */
476 extern int interactiveflag;
477 extern struct buf curlogbuf;
478 char const *buildrevision(struct hshentries const*,struct hshentry*,FILE*,int);
479 int getcstdin(void);
480 int putdtext(struct hshentry const*,char const*,FILE*,int);
481 int ttystdin(void);
482 int yesorno(int,char const*,...) __attribute__((format(printf, 2, 3)));
483 struct cbuf cleanlogmsg(char*,size_t);
484 struct cbuf getsstdin(char const*,char const*,char const*,struct buf*);
485 void putdesc(int,char*);
486 void putdftext(struct hshentry const*,RILE*,FILE*,int);
487 
488 /* rcskeep */
489 extern int prevkeys;
490 extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
491 int getoldkeys(RILE*);
492 
493 /* rcskeys */
494 extern char const *Keyword[];
495 extern int onlyRCSlocalId;
496 void setRCSlocalId(char const *);
497 enum markers trymatch(char const*);
498 
499 /* rcslex */
500 extern FILE *foutptr;
501 extern FILE *frewrite;
502 extern RILE *finptr;
503 extern char const *NextString;
504 extern enum tokens nexttok;
505 extern int hshenter;
506 extern int nerror;
507 extern int nextc;
508 extern int quietflag;
509 extern long rcsline;
510 char const *getid(void);
511 __dead void efaterror(char const*);
512 __dead void enfaterror(int,char const*);
513 __dead void fatcleanup(int);
514 __dead void faterror(char const*,...) __attribute__((format(printf, 1, 2)));
515 __dead void fatserror(char const*,...) __attribute__((format(printf, 1, 2)));
516 __dead void rcsfaterror(char const*,...) __attribute__((format(printf, 1, 2)));
517 __dead void Ieof(void);
518 __dead void Ierror(void);
519 __dead void Oerror(void);
520 char *checkid(char*,int);
521 char *checksym(char*,int);
522 int eoflex(void);
523 int getkeyopt(char const*);
524 int getlex(enum tokens);
525 struct cbuf getphrases(char const*);
526 struct cbuf savestring(struct buf*);
527 struct hshentry *getnum(void);
528 void Ifclose(RILE*);
529 void Izclose(RILE**);
530 void Lexinit(void);
531 void Ofclose(FILE*);
532 void Orewind(FILE*);
533 void Ozclose(FILE**);
534 void aflush(FILE*);
535 void afputc(int,FILE*);
536 void aprintf(FILE*,char const*,...) __attribute__((format(printf, 2, 3)));
537 void aputs(char const*,FILE*);
538 void checksid(char*);
539 void checkssym(char*);
540 void diagnose(char const*,...) __attribute__((format(printf, 1, 2)));
541 void eerror(char const*);
542 void eflush(void);
543 void enerror(int,char const*);
544 void error(char const*,...) __attribute__((format(printf, 1, 2)));
545 void fvfprintf(FILE*,char const*,va_list);
546 void getkey(char const*);
547 void getkeystring(char const*);
548 void nextlex(void);
549 void oflush(void);
550 void printstring(void);
551 void readstring(void);
552 void redefined(int);
553 void rcserror(char const*,...) __attribute__((format(printf, 1, 2)));
554 void rcswarn(char const*,...) __attribute__((format(printf, 1, 2)));
555 void testIerror(FILE*);
556 void testOerror(FILE*);
557 void warn(char const*,...) __attribute__((format(printf, 1, 2)));
558 void warnignore(void);
559 void workerror(char const*,...) __attribute__((format(printf, 1, 2)));
560 void workwarn(char const*,...) __attribute__((format(printf, 1, 2)));
561 	void advise_access(RILE*,int);
562 #	define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
563 	RILE *I_open(char const*,struct stat*);
564 #	define Iopen(f,m,s) I_open(f,s)
565 
566 /* rcsmap */
567 extern enum tokens const ctab[];
568 
569 /* rcsrev */
570 char *partialno(struct buf*,char const*,int);
571 char const *namedrev(char const*,struct hshentry*);
572 char const *tiprev(void);
573 int cmpdate(char const*,char const*);
574 int cmpnum(char const*,char const*);
575 int cmpnumfld(char const*,char const*,int);
576 int compartial(char const*,char const*,int);
577 int expandsym(char const*,struct buf*);
578 int fexpandsym(char const*,struct buf*,RILE*);
579 struct hshentry *genrevs(char const*,char const*,char const*,char const*,struct hshentries**);
580 int countnumflds(char const*);
581 void getbranchno(char const*,struct buf*);
582 
583 /* rcssyn */
584 /* These expand modes must agree with Expand_names[] in rcssyn.c.  */
585 #define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
586 #define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
587 #define KEY_EXPAND 2 /* -kk `$Keyword$' */
588 #define VAL_EXPAND 3 /* -kv `value' */
589 #define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
590 #define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
591 #define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
592 #define MIN_UNCHANGED_EXPAND OLD_EXPAND
593 			/* min value guaranteed to yield an identical file */
594 struct diffcmd {
595 	long
596 		line1, /* number of first line */
597 		nlines, /* number of lines affected */
598 		adprev, /* previous 'a' line1+1 or 'd' line1 */
599 		dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
600 };
601 extern char const      * Dbranch;
602 extern struct access   * AccessList;
603 extern struct assoc    * Symbols;
604 extern struct cbuf Comment;
605 extern struct cbuf Ignored;
606 extern struct rcslock *Locks;
607 extern struct hshentry * Head;
608 extern int		 Expand;
609 extern int               StrictLocks;
610 extern int               TotalDeltas;
611 extern char const *const expand_names[];
612 extern char const
613 	Kaccess[], Kauthor[], Kbranch[], Kcomment[], Kcommitid[],
614 	Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
615 	Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
616 __dead void unexpected_EOF(void);
617 int getdiffcmd(RILE*,int,FILE*,struct diffcmd*);
618 int str2expmode(char const*);
619 void getadmin(void);
620 void getdesc(int);
621 void gettree(void);
622 void ignorephrases(char const*);
623 void initdiffcmd(struct diffcmd*);
624 void putadmin(void);
625 void putstring(FILE*,int,struct cbuf,int);
626 void puttree(struct hshentry const*,FILE*);
627 
628 /* rcstime */
629 #define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
630 char const *date2str(char const[datesize],char[datesize + zonelenmax]);
631 time_t date2time(char const[datesize]);
632 void str2date(char const*,char[datesize]);
633 void time2date(time_t,char[datesize]);
634 #define zone_set(x) /* nothing */
635 
636 /* rcsutil */
637 extern int RCSversion;
638 FILE *fopenSafer(char const*,char const*);
639 char *cgetenv(char const*);
640 char *fstr_save(char const*);
641 char *str_save(char const*);
642 char const *getusername(int);
643 int fdSafer(int);
644 int getRCSINIT(int,char**,char***);
645 int run(int,char const*,...);
646 int runv(int,char const*,char const**);
647 void *fremember(void *);
648 void *ftestalloc(size_t);
649 void *testalloc(size_t);
650 void *testrealloc(void *,size_t);
651 #define ftalloc(T) ftnalloc(T,1)
652 #define talloc(T) tnalloc(T,1)
653 #define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
654 #define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
655 #define trealloc(T,p,n) ((T*) testrealloc((void *)(p), sizeof(T)*(n)))
656 #define tfree(p) free((void *)(p))
657 time_t now(void);
658 void awrite(char const*,size_t,FILE*);
659 void fastcopy(RILE*,FILE*);
660 void ffree(void);
661 void ffree1(char const*);
662 void setRCSversion(char const*);
663 #if has_signal
664 	void catchints(void);
665 	void ignoreints(void);
666 	void restoreints(void);
667 #else
668 #	define catchints()
669 #	define ignoreints()
670 #	define restoreints()
671 #endif
672 	void catchmmapints(void);
673 	void readAccessFilenameBuffer(char const*,unsigned char const*);
674 	uid_t ruid(void);
675 #	define myself(u) ((u) == ruid())
676 	uid_t euid(void);
677 	void nosetid(void);
678 	void seteid(void);
679 	void setrid(void);
680 
681 /* version */
682 extern char const RCS_version_string[];
683