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