Home | History | Annotate | Line # | Download | only in src
      1 /*	$NetBSD: rcsbase.h,v 1.2 2016/01/14 04:22:39 christos Exp $	*/
      2 
      3 /* RCS common definitions and data structures */
      4 
      5 #define RCSBASE "Id: rcsbase.h,v 5.20 1995/06/16 06:19:24 eggert Exp "
      6 
      7 /* Copyright 1982, 1988, 1989 Walter Tichy
      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 (at) 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, (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 #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 #if large_memory
    260 	typedef unsigned char const *Iptr_type;
    261 	typedef struct RILE {
    262 		Iptr_type ptr, lim;
    263 		unsigned char *base; /* not Iptr_type for lint's sake */
    264 		unsigned char *readlim;
    265 		int fd;
    266 #		if maps_memory
    267 			void (*deallocate) P((struct RILE *));
    268 #		else
    269 			FILE *stream;
    270 #		endif
    271 	} RILE;
    272 #	if maps_memory
    273 #		define declarecache register Iptr_type ptr, lim
    274 #		define setupcache(f) (lim = (f)->lim)
    275 #		define Igeteof_(f,c,s) { if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++; }
    276 #		define cachegeteof_(c,s) { if (ptr==lim) s else (c)= *ptr++; }
    277 #	else
    278 		int Igetmore P((RILE*));
    279 #		define declarecache register Iptr_type ptr; register RILE *rRILE
    280 #		define setupcache(f) (rRILE = (f))
    281 #		define Igeteof_(f,c,s) { if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++; }
    282 #		define cachegeteof_(c,s) { if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++; }
    283 #	endif
    284 #	define uncache(f) ((f)->ptr = ptr)
    285 #	define cache(f) (ptr = (f)->ptr)
    286 #	define Iget_(f,c) Igeteof_(f,c,Ieof();)
    287 #	define cacheget_(c) cachegeteof_(c,Ieof();)
    288 #	define cacheunget_(f,c) (c)=(--ptr)[-1];
    289 #	define Ioffset_type size_t
    290 #	define Itell(f) ((f)->ptr - (f)->base)
    291 #	define Irewind(f) ((f)->ptr = (f)->base)
    292 #	define cacheptr() ptr
    293 #	define Ifileno(f) ((f)->fd)
    294 #else
    295 #	define RILE FILE
    296 #	define declarecache register FILE *ptr
    297 #	define setupcache(f) (ptr = (f))
    298 #	define uncache(f)
    299 #	define cache(f)
    300 #	define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}}
    301 #	define cachegeteof_(c,s) Igeteof_(ptr,c,s)
    302 #	define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); }
    303 #	define cacheget_(c) Iget_(ptr,c)
    304 #	define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c)
    305 #	define Ioffset_type long
    306 #	define Itell(f) ftell(f)
    307 #	define Ifileno(f) fileno(f)
    308 #endif
    309 
    310 /* Print a char, but abort on write error.  */
    311 #define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
    312 
    313 /* Get a character from an RCS file, perhaps copying to a new RCS file.  */
    314 #define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
    315 #define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
    316 
    317 
    318 #define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
    319 /* computes mode of working file: same as RCSmode, but write permission     */
    320 /* determined by writable */
    321 
    322 
    323 /* character classes and token codes */
    324 enum tokens {
    325 /* classes */	DELIM,	DIGIT,	IDCHAR,	NEWLN,	LETTER,	Letter,
    326 		PERIOD,	SBEGIN,	SPACE,	UNKN,
    327 /* tokens */	COLON,	ID,	NUM,	SEMI,	STRING
    328 };
    329 
    330 #define SDELIM  '@'     /* the actual character is needed for string handling*/
    331 /* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
    332  * there should be no overlap among SDELIM, KDELIM, and VDELIM
    333  */
    334 
    335 #define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
    336 
    337 
    338 
    339 
    340 
    341 /***************************************
    342  * Data structures for the symbol table
    343  ***************************************/
    344 
    345 /* Buffer of arbitrary data */
    346 struct buf {
    347 	char *string;
    348 	size_t size;
    349 };
    350 struct cbuf {
    351 	char const *string;
    352 	size_t size;
    353 };
    354 
    355 /* Hash table entry */
    356 struct hshentry {
    357 	char const	  * num;      /* pointer to revision number (ASCIZ) */
    358 	char const	  * date;     /* pointer to date of checkin	    */
    359 	char const	  * author;   /* login of person checking in	    */
    360 	char const	  * lockedby; /* who locks the revision		    */
    361 	char const	  * state;    /* state of revision (Exp by default) */
    362 	char const	  * name;     /* name (if any) by which retrieved   */
    363 	char const	  * commitid; /* unique commit identifier           */
    364 	struct cbuf	    log;      /* log message requested at checkin   */
    365         struct branchhead * branches; /* list of first revisions on branches*/
    366 	struct cbuf	    ig;	      /* ignored phrases in admin part	    */
    367 	struct cbuf	    igtext;   /* ignored phrases in deltatext part  */
    368         struct hshentry   * next;     /* next revision on same branch       */
    369 	struct hshentry   * nexthsh;  /* next revision with same hash value */
    370 	long		    insertlns;/* lines inserted (computed by rlog)  */
    371 	long		    deletelns;/* lines deleted  (computed by rlog)  */
    372 	char		    selector; /* true if selected, false if deleted */
    373 };
    374 
    375 /* list of hash entries */
    376 struct hshentries {
    377 	struct hshentries *rest;
    378 	struct hshentry *first;
    379 };
    380 
    381 /* list element for branch lists */
    382 struct branchhead {
    383         struct hshentry   * hsh;
    384         struct branchhead * nextbranch;
    385 };
    386 
    387 /* accesslist element */
    388 struct access {
    389 	char const	  * login;
    390         struct access     * nextaccess;
    391 };
    392 
    393 /* list element for locks  */
    394 struct rcslock {
    395 	char const	  * login;
    396         struct hshentry   * delta;
    397 	struct rcslock    * nextlock;
    398 };
    399 
    400 /* list element for symbolic names */
    401 struct assoc {
    402 	char const	  * symbol;
    403 	char const	  * num;
    404         struct assoc      * nextassoc;
    405 };
    406 
    407 
    408 #define mainArgs (argc,argv) int argc; char **argv;
    409 
    410 #if RCS_lint
    411 #	define libId(name,rcsid)
    412 #	define mainProg(name,cmd,rcsid) int name mainArgs
    413 #else
    414 #	define libId(name,rcsid) char const name[] = rcsid;
    415 #	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
    416 #endif
    417 
    418 /*
    419  * Markers for keyword expansion (used in co and ident)
    420  *	Every byte must have class LETTER or Letter.
    421  */
    422 #define AUTHOR          "Author"
    423 #define DATE            "Date"
    424 #define HEADER          "Header"
    425 #define IDH             "Id"
    426 #define LOCKER          "Locker"
    427 #define LOG             "Log"
    428 #define NAME		"Name"
    429 #define RCSFILE         "RCSfile"
    430 #define REVISION        "Revision"
    431 #define SOURCE          "Source"
    432 #define STATE           "State"
    433 #define keylength 32 /* max length of any of the above keywords */
    434 
    435 enum markers { Nomatch, Author, Date, Header, Id,
    436 #ifdef LOCALID
    437 	       LocalId,
    438 #endif
    439 	       Locker, Log, Name, RCSfile, Revision, Source, State };
    440 	/* This must be in the same order as rcskeys.c's Keyword[] array. */
    441 
    442 #define DELNUMFORM      "\n\n%s\n%s\n"
    443 /* used by putdtext and scanlogtext */
    444 
    445 #define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
    446 
    447 /* main program */
    448 extern char const cmdid[];
    449 void exiterr P((void)) exiting;
    450 
    451 /* merge */
    452 int merge P((int,char const*,char const*const[3],char const*const[3]));
    453 
    454 /* rcsedit */
    455 #define ciklogsize 23 /* sizeof("checked in with -k by ") */
    456 extern FILE *fcopy;
    457 extern char const *resultname;
    458 extern char const ciklog[ciklogsize];
    459 extern int locker_expansion;
    460 RILE *rcswriteopen P((struct buf*,struct stat*,int));
    461 char const *makedirtemp P((int));
    462 char const *getcaller P((void));
    463 int addlock P((struct hshentry*,int));
    464 int addsymbol P((char const*,char const*,int));
    465 int checkaccesslist P((void));
    466 int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t));
    467 int donerewrite P((int,time_t));
    468 int dorewrite P((int,int));
    469 int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int));
    470 int findlock P((int,struct hshentry**));
    471 int setmtime P((char const*,time_t));
    472 void ORCSclose P((void));
    473 void ORCSerror P((void));
    474 void copystring P((void));
    475 void dirtempunlink P((void));
    476 void enterstring P((void));
    477 void finishedit P((struct hshentry const*,FILE*,int));
    478 void keepdirtemp P((char const*));
    479 void openfcopy P((FILE*));
    480 void snapshotedit P((FILE*));
    481 void xpandstring P((struct hshentry const*));
    482 #if has_NFS || bad_unlink
    483 	int un_link P((char const*));
    484 #else
    485 #	define un_link(s) unlink(s)
    486 #endif
    487 #if large_memory
    488 	void edit_string P((void));
    489 #	define editstring(delta) edit_string()
    490 #else
    491 	void editstring P((struct hshentry const*));
    492 #endif
    493 
    494 /* rcsfcmp */
    495 int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
    496 
    497 /* rcsfnms */
    498 #define bufautobegin(b) clear_buf(b)
    499 #define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0))
    500 extern FILE *workstdout;
    501 extern char *workname;
    502 extern char const *RCSname;
    503 extern char const *suffixes;
    504 extern int fdlock;
    505 extern struct stat RCSstat;
    506 RILE *rcsreadopen P((struct buf*,struct stat*,int));
    507 char *bufenlarge P((struct buf*,char const**));
    508 char const *basefilename P((char const*));
    509 char const *getfullRCSname P((void));
    510 char const *maketemp P((int));
    511 char const *rcssuffix P((char const*));
    512 int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
    513 struct cbuf bufremember P((struct buf*,size_t));
    514 void bufalloc P((struct buf*,size_t));
    515 void bufautoend P((struct buf*));
    516 void bufrealloc P((struct buf*,size_t));
    517 void bufscat P((struct buf*,char const*));
    518 void bufscpy P((struct buf*,char const*));
    519 void tempunlink P((void));
    520 
    521 /* rcsgen */
    522 extern int interactiveflag;
    523 extern struct buf curlogbuf;
    524 char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
    525 int getcstdin P((void));
    526 int putdtext P((struct hshentry const*,char const*,FILE*,int));
    527 int ttystdin P((void));
    528 int yesorno P((int,char const*,...)) printf_string(2,3);
    529 struct cbuf cleanlogmsg P((char*,size_t));
    530 struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
    531 void putdesc P((int,char*));
    532 void putdftext P((struct hshentry const*,RILE*,FILE*,int));
    533 
    534 /* rcskeep */
    535 extern int prevkeys;
    536 extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
    537 int getoldkeys P((RILE*));
    538 
    539 /* rcskeys */
    540 extern char const *const Keyword[];
    541 enum markers trymatch P((char const*));
    542 
    543 /* rcslex */
    544 extern FILE *foutptr;
    545 extern FILE *frewrite;
    546 extern RILE *finptr;
    547 extern char const *NextString;
    548 extern enum tokens nexttok;
    549 extern int hshenter;
    550 extern int nerror;
    551 extern int nextc;
    552 extern int quietflag;
    553 extern long rcsline;
    554 char const *getid P((void));
    555 void efaterror P((char const*)) exiting;
    556 void enfaterror P((int,char const*)) exiting;
    557 void fatcleanup P((int)) exiting;
    558 void faterror P((char const*,...)) printf_string_exiting(1,2);
    559 void fatserror P((char const*,...)) printf_string_exiting(1,2);
    560 void rcsfaterror P((char const*,...)) printf_string_exiting(1,2);
    561 void Ieof P((void)) exiting;
    562 void Ierror P((void)) exiting;
    563 void Oerror P((void)) exiting;
    564 char *checkid P((char*,int));
    565 char *checksym P((char*,int));
    566 int eoflex P((void));
    567 int getkeyopt P((char const*));
    568 int getlex P((enum tokens));
    569 struct cbuf getphrases P((char const*));
    570 struct cbuf savestring P((struct buf*));
    571 struct hshentry *getnum P((void));
    572 void Ifclose P((RILE*));
    573 void Izclose P((RILE**));
    574 void Lexinit P((void));
    575 void Ofclose P((FILE*));
    576 void Orewind P((FILE*));
    577 void Ozclose P((FILE**));
    578 void aflush P((FILE*));
    579 void afputc P((int,FILE*));
    580 void aprintf P((FILE*,char const*,...)) printf_string(2,3);
    581 void aputs P((char const*,FILE*));
    582 void checksid P((char*));
    583 void checkssym P((char*));
    584 void diagnose P((char const*,...)) printf_string(1,2);
    585 void eerror P((char const*));
    586 void eflush P((void));
    587 void enerror P((int,char const*));
    588 void error P((char const*,...)) printf_string(1,2);
    589 void fvfprintf P((FILE*,char const*,va_list));
    590 void getkey P((char const*));
    591 void getkeystring P((char const*));
    592 void nextlex P((void));
    593 void oflush P((void));
    594 void printstring P((void));
    595 void readstring P((void));
    596 void redefined P((int));
    597 void rcserror P((char const*,...)) printf_string(1,2);
    598 void rcswarn P((char const*,...)) printf_string(1,2);
    599 void testIerror P((FILE*));
    600 void testOerror P((FILE*));
    601 void warn P((char const*,...)) printf_string(1,2);
    602 void warnignore P((void));
    603 void workerror P((char const*,...)) printf_string(1,2);
    604 void workwarn P((char const*,...)) printf_string(1,2);
    605 #if has_madvise && has_mmap && large_memory
    606 	void advise_access P((RILE*,int));
    607 #	define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
    608 #else
    609 #	define advise_access(f,advice)
    610 #	define if_advise_access(p,f,advice)
    611 #endif
    612 #if large_memory && maps_memory
    613 	RILE *I_open P((char const*,struct stat*));
    614 #	define Iopen(f,m,s) I_open(f,s)
    615 #else
    616 	RILE *Iopen P((char const*,char const*,struct stat*));
    617 #endif
    618 #if !large_memory
    619 	void testIeof P((FILE*));
    620 	void Irewind P((RILE*));
    621 #endif
    622 
    623 /* rcsmap */
    624 extern enum tokens const ctab[];
    625 
    626 /* rcsrev */
    627 char *partialno P((struct buf*,char const*,int));
    628 char const *namedrev P((char const*,struct hshentry*));
    629 char const *tiprev P((void));
    630 int cmpdate P((char const*,char const*));
    631 int cmpnum P((char const*,char const*));
    632 int cmpnumfld P((char const*,char const*,int));
    633 int compartial P((char const*,char const*,int));
    634 int expandsym P((char const*,struct buf*));
    635 int fexpandsym P((char const*,struct buf*,RILE*));
    636 struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
    637 int countnumflds P((char const*));
    638 void getbranchno P((char const*,struct buf*));
    639 
    640 /* rcssyn */
    641 /* These expand modes must agree with Expand_names[] in rcssyn.c.  */
    642 #define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
    643 #define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
    644 #define KEY_EXPAND 2 /* -kk `$Keyword$' */
    645 #define VAL_EXPAND 3 /* -kv `value' */
    646 #define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
    647 #define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
    648 #define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
    649 #define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND)
    650 			/* min value guaranteed to yield an identical file */
    651 struct diffcmd {
    652 	long
    653 		line1, /* number of first line */
    654 		nlines, /* number of lines affected */
    655 		adprev, /* previous 'a' line1+1 or 'd' line1 */
    656 		dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
    657 };
    658 extern char const      * Dbranch;
    659 extern struct access   * AccessList;
    660 extern struct assoc    * Symbols;
    661 extern struct cbuf Comment;
    662 extern struct cbuf Ignored;
    663 extern struct rcslock *Locks;
    664 extern struct hshentry * Head;
    665 extern int		 Expand;
    666 extern int               StrictLocks;
    667 extern int               TotalDeltas;
    668 extern char const *const expand_names[];
    669 extern char const
    670 	Kaccess[], Kauthor[], Kbranch[], Kcomment[],
    671 	Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
    672 	Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
    673 void unexpected_EOF P((void)) exiting;
    674 int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
    675 int str2expmode P((char const*));
    676 void getadmin P((void));
    677 void getdesc P((int));
    678 void gettree P((void));
    679 void ignorephrases P((char const*));
    680 void initdiffcmd P((struct diffcmd*));
    681 void putadmin P((void));
    682 void putstring P((FILE*,int,struct cbuf,int));
    683 void puttree P((struct hshentry const*,FILE*));
    684 
    685 /* rcstime */
    686 #define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
    687 char const *date2str P((char const[datesize],char[datesize + zonelenmax]));
    688 time_t date2time P((char const[datesize]));
    689 void str2date P((char const*,char[datesize]));
    690 void time2date P((time_t,char[datesize]));
    691 void zone_set P((char const*));
    692 
    693 /* rcsutil */
    694 extern int RCSversion;
    695 FILE *fopenSafer P((char const*,char const*));
    696 char *cgetenv P((char const*));
    697 char *fstr_save P((char const*));
    698 char *str_save P((char const*));
    699 char const *getusername P((int));
    700 int fdSafer P((int));
    701 int getRCSINIT P((int,char**,char***));
    702 int run P((int,char const*,...));
    703 int runv P((int,char const*,char const**));
    704 malloc_type fremember P((malloc_type));
    705 malloc_type ftestalloc P((size_t));
    706 malloc_type testalloc P((size_t));
    707 malloc_type testrealloc P((malloc_type,size_t));
    708 #define ftalloc(T) ftnalloc(T,1)
    709 #define talloc(T) tnalloc(T,1)
    710 #if RCS_lint
    711 	extern malloc_type lintalloc;
    712 #	define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
    713 #	define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
    714 #	define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
    715 #	define tfree(p)
    716 #else
    717 #	define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
    718 #	define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
    719 #	define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
    720 #	define tfree(p) free((malloc_type)(p))
    721 #endif
    722 time_t now P((void));
    723 void awrite P((char const*,size_t,FILE*));
    724 void fastcopy P((RILE*,FILE*));
    725 void ffree P((void));
    726 void ffree1 P((char const*));
    727 void setRCSversion P((char const*));
    728 #if has_signal
    729 	void catchints P((void));
    730 	void ignoreints P((void));
    731 	void restoreints P((void));
    732 #else
    733 #	define catchints()
    734 #	define ignoreints()
    735 #	define restoreints()
    736 #endif
    737 #if has_mmap && large_memory
    738 #   if has_NFS && mmap_signal
    739 	void catchmmapints P((void));
    740 	void readAccessFilenameBuffer P((char const*,unsigned char const*));
    741 #   else
    742 #	define catchmmapints()
    743 #   endif
    744 #endif
    745 #if has_getuid
    746 	uid_t ruid P((void));
    747 #	define myself(u) ((u) == ruid())
    748 #else
    749 #	define myself(u) true
    750 #endif
    751 #if has_setuid
    752 	uid_t euid P((void));
    753 	void nosetid P((void));
    754 	void seteid P((void));
    755 	void setrid P((void));
    756 #else
    757 #	define nosetid()
    758 #	define seteid()
    759 #	define setrid()
    760 #endif
    761 
    762 /* version */
    763 extern char const RCS_version_string[];
    764