111894Speter/* RCS common definitions and data structures */ 29Sjkh 350472Speter#define RCSBASE "$FreeBSD$" 49Sjkh 511894Speter/* Copyright 1982, 1988, 1989 Walter Tichy 611894Speter Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert 79Sjkh Distributed under license by the Free Software Foundation, Inc. 89Sjkh 99SjkhThis file is part of RCS. 109Sjkh 119SjkhRCS is free software; you can redistribute it and/or modify 129Sjkhit under the terms of the GNU General Public License as published by 139Sjkhthe Free Software Foundation; either version 2, or (at your option) 149Sjkhany later version. 159Sjkh 169SjkhRCS is distributed in the hope that it will be useful, 179Sjkhbut WITHOUT ANY WARRANTY; without even the implied warranty of 189SjkhMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 199SjkhGNU General Public License for more details. 209Sjkh 219SjkhYou should have received a copy of the GNU General Public License 2211894Speteralong with RCS; see the file COPYING. 2311894SpeterIf not, write to the Free Software Foundation, 2411894Speter59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 259Sjkh 269SjkhReport problems and direct all questions to: 279Sjkh 289Sjkh rcs-bugs@cs.purdue.edu 299Sjkh 309Sjkh*/ 319Sjkh 3211894Speter/* 3311894Speter * Revision 5.20 1995/06/16 06:19:24 eggert 3411894Speter * Update FSF address. 358858Srgrimes * 3611894Speter * Revision 5.19 1995/06/01 16:23:43 eggert 3711894Speter * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring. 3811894Speter * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros. 3911894Speter * (maps_memory): New macro; replaces many instances of `has_mmap'. 4011894Speter * (cacheptr): Renamed from cachetell. 4111894Speter * (struct RILE): New alternate name for RILE; the type is now recursive. 4211894Speter * (deallocate): New member for RILE, used for generic buffer deallocation. 4311894Speter * (cacheunget_): No longer take a failure arg; just call Ierror on failure. 4411894Speter * (struct rcslock): Renamed from struct lock, to avoid collisions with 4511894Speter * system headers on some hosts. All users changed. 4611894Speter * (basefilename): Renamed from basename, likewise. 4711894Speter * (dirtpname): Remove; no longer external. 4811894Speter * (dirlen, dateform): Remove; no longer used. 4911894Speter * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions. 5011894Speter * (zonelenmax): Increase to 9 for full ISO 8601 format. 5111894Speter * (catchmmapints): Depend on has_NFS. 521494Srgrimes * 5311894Speter * Revision 5.18 1994/03/17 14:05:48 eggert 5411894Speter * Add primitives for reading backwards from a RILE; 5511894Speter * this is needed to go back and find the $Log prefix. 5611894Speter * Specify subprocess input via file descriptor, not file name. Remove lint. 5711894Speter * 5811894Speter * Revision 5.17 1993/11/09 17:40:15 eggert 5911894Speter * Move RCS-specific time handling into rcstime.c. 6011894Speter * printf_string now takes two arguments, alas. 6111894Speter * 6211894Speter * Revision 5.16 1993/11/03 17:42:27 eggert 6311894Speter * Don't arbitrarily limit the number of joins. Remove `nil'. 6411894Speter * Add Name keyword. Don't discard ignored phrases. 6511894Speter * Add support for merge -A vs -E, and allow up to three labels. 6611894Speter * Improve quality of diagnostics and prototypes. 6711894Speter * 6811894Speter * Revision 5.15 1992/07/28 16:12:44 eggert 6911894Speter * Statement macro names now end in _. 7011894Speter * 7111894Speter * Revision 5.14 1992/02/17 23:02:22 eggert 7211894Speter * Add -T support. Work around NFS mmap SIGBUS problem. 7311894Speter * 7411894Speter * Revision 5.13 1992/01/24 18:44:19 eggert 7511894Speter * Add support for bad_creat0. lint -> RCS_lint 7611894Speter * 7711894Speter * Revision 5.12 1992/01/06 02:42:34 eggert 7811894Speter * while (E) ; -> while (E) continue; 7911894Speter * 809Sjkh * Revision 5.11 1991/10/07 17:32:46 eggert 819Sjkh * Support piece tables even if !has_mmap. 829Sjkh * 839Sjkh * Revision 5.10 1991/09/24 00:28:39 eggert 849Sjkh * Remove unexported functions. 859Sjkh * 869Sjkh * Revision 5.9 1991/08/19 03:13:55 eggert 879Sjkh * Add piece tables and other tuneups, and NFS workarounds. 889Sjkh * 899Sjkh * Revision 5.8 1991/04/21 11:58:20 eggert 909Sjkh * Add -x, RCSINIT, MS-DOS support. 919Sjkh * 929Sjkh * Revision 5.7 1991/02/28 19:18:50 eggert 939Sjkh * Try setuid() if seteuid() doesn't work. 949Sjkh * 959Sjkh * Revision 5.6 1991/02/26 17:48:37 eggert 969Sjkh * Support new link behavior. Move ANSI C / Posix declarations into conf.sh. 979Sjkh * 989Sjkh * Revision 5.5 1990/12/04 05:18:43 eggert 999Sjkh * Use -I for prompts and -q for diagnostics. 1009Sjkh * 1019Sjkh * Revision 5.4 1990/11/01 05:03:35 eggert 1029Sjkh * Don't assume that builtins are functions; they may be macros. 1039Sjkh * Permit arbitrary data in logs. 1049Sjkh * 1059Sjkh * Revision 5.3 1990/09/26 23:36:58 eggert 1069Sjkh * Port wait() to non-Posix ANSI C hosts. 1079Sjkh * 1089Sjkh * Revision 5.2 1990/09/04 08:02:20 eggert 1099Sjkh * Don't redefine NAME_MAX, PATH_MAX. 1109Sjkh * Improve incomplete line handling. Standardize yes-or-no procedure. 1119Sjkh * 1129Sjkh * Revision 5.1 1990/08/29 07:13:53 eggert 1139Sjkh * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too. 1149Sjkh * 1159Sjkh * Revision 5.0 1990/08/22 08:12:44 eggert 1169Sjkh * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access(). 1179Sjkh * Remove compile-time limits; use malloc instead. 1189Sjkh * Ansify and Posixate. Add support for ISO 8859. 1199Sjkh * Remove snoop and v2 support. 1209Sjkh * 1219Sjkh * Revision 4.9 89/05/01 15:17:14 narten 1228858Srgrimes * botched previous USG fix 1238858Srgrimes * 1249Sjkh * Revision 4.8 89/05/01 14:53:05 narten 1259Sjkh * changed #include <strings.h> -> string.h for USG systems. 1268858Srgrimes * 1279Sjkh * Revision 4.7 88/11/08 15:58:45 narten 1289Sjkh * removed defs for functions loaded from libraries 1298858Srgrimes * 1309Sjkh * Revision 4.6 88/08/09 19:12:36 eggert 1319Sjkh * Shrink stdio code size; remove lint; permit -Dhshsize=nn. 1328858Srgrimes * 1339Sjkh * Revision 4.5 87/12/18 17:06:41 narten 1349Sjkh * made removed BSD ifdef, now uses V4_2BSD 1358858Srgrimes * 1369Sjkh * Revision 4.4 87/10/18 10:29:49 narten 1379Sjkh * Updating version numbers 1389Sjkh * Changes relative to 1.1 are actually relative to 4.2 1398858Srgrimes * 1409Sjkh * Revision 1.3 87/09/24 14:02:25 narten 1419Sjkh * changes for lint 1428858Srgrimes * 1439Sjkh * Revision 1.2 87/03/27 14:22:02 jenkins 1449Sjkh * Port to suns 1458858Srgrimes * 1469Sjkh * Revision 4.2 83/12/20 16:04:20 wft 1479Sjkh * merged 3.6.1.1 and 4.1 (SMALLOG, logsize). 1489Sjkh * moved setting of STRICT_LOCKING to Makefile. 1499Sjkh * changed DOLLAR to UNKN (conflict with KDELIM). 1508858Srgrimes * 1519Sjkh * Revision 4.1 83/05/04 09:12:41 wft 1529Sjkh * Added markers Id and RCSfile. 1539Sjkh * Added Dbranch for default branches. 1548858Srgrimes * 1559Sjkh * Revision 3.6.1.1 83/12/02 21:56:22 wft 1569Sjkh * Increased logsize, added macro SMALLOG. 1578858Srgrimes * 1589Sjkh * Revision 3.6 83/01/15 16:43:28 wft 1599Sjkh * 4.2 prerelease 1608858Srgrimes * 1619Sjkh * Revision 3.6 83/01/15 16:43:28 wft 1629Sjkh * Replaced dbm.h with BYTESIZ, fixed definition of rindex(). 1639Sjkh * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD. 1649Sjkh * Added macro DELNUMFORM to have uniform format for printing delta text nodes. 1659Sjkh * Added macro DELETE to mark deleted deltas. 1669Sjkh * 1679Sjkh * Revision 3.5 82/12/10 12:16:56 wft 1689Sjkh * Added two forms of DATEFORM, one using %02d, the other %.2d. 1699Sjkh * 1709Sjkh * Revision 3.4 82/12/04 20:01:25 wft 1719Sjkh * added LOCKER, Locker, and USG (redefinition of rindex). 1729Sjkh * 1739Sjkh * Revision 3.3 82/12/03 12:22:04 wft 1749Sjkh * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3, 1759Sjkh * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength 1769Sjkh * using NCPPN. Changed putc() to abort on write error. 1779Sjkh * 1789Sjkh * Revision 3.2 82/10/18 15:03:52 wft 1799Sjkh * added macro STRICT_LOCKING, removed RCSUMASK. 1809Sjkh * renamed JOINFILE[1,2] to JOINFIL[1,2]. 1819Sjkh * 1829Sjkh * Revision 3.1 82/10/11 19:41:17 wft 1839Sjkh * removed NBPW, NBPC, NCPW. 1849Sjkh * added typdef int void to aid compiling 1859Sjkh */ 1869Sjkh 1879Sjkh 1889Sjkh#include "conf.h" 1899Sjkh 1909Sjkh 1919Sjkh#define EXIT_TROUBLE DIFF_TROUBLE 1929Sjkh 19311894Speter#ifdef _POSIX_PATH_MAX 19411894Speter# define SIZEABLE_PATH _POSIX_PATH_MAX 1959Sjkh#else 19611894Speter# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */ 1979Sjkh#endif 1989Sjkh 1999Sjkh/* for traditional C hosts with unusual size arguments */ 2009Sjkh#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f) 2019Sjkh#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f) 2029Sjkh 2039Sjkh 2049Sjkh/* 2059Sjkh * Parameters 2069Sjkh */ 2079Sjkh 2089Sjkh/* backwards compatibility with old versions of RCS */ 2099Sjkh#define VERSION_min 3 /* old output RCS format supported */ 2109Sjkh#define VERSION_max 5 /* newest output RCS format supported */ 2119Sjkh#ifndef VERSION_DEFAULT /* default RCS output format */ 2129Sjkh# define VERSION_DEFAULT VERSION_max 2139Sjkh#endif 2149Sjkh#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */ 2159Sjkh 2169Sjkh#ifndef STRICT_LOCKING 2179Sjkh#define STRICT_LOCKING 1 2189Sjkh#endif 2199Sjkh /* 0 sets the default locking to non-strict; */ 2209Sjkh /* used in experimental environments. */ 2219Sjkh /* 1 sets the default locking to strict; */ 2229Sjkh /* used in production environments. */ 2239Sjkh 2249Sjkh#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */ 22511894Speter#define datesize (yearlength+16) /* size of output of time2date */ 2269Sjkh#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */ 2279Sjkh#define KDELIM '$' /* delimiter for keywords */ 2289Sjkh#define VDELIM ':' /* separates keywords from values */ 2299Sjkh#define DEFAULTSTATE "Exp" /* default state of revisions */ 2309Sjkh 2319Sjkh 2329Sjkh 2339Sjkh#define true 1 2349Sjkh#define false 0 2359Sjkh 2369Sjkh 2379Sjkh/* 2389Sjkh * RILE - readonly file 2399Sjkh * declarecache; - declares local cache for RILE variable(s) 2409Sjkh * setupcache - sets up the local RILE cache, but does not initialize it 2419Sjkh * cache, uncache - caches and uncaches the local RILE; 2429Sjkh * (uncache,cache) is needed around functions that advance the RILE pointer 24311894Speter * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF 24411894Speter * cachegeteof_(c,s) - Igeteof_ applied to the local RILE 24511894Speter * Iget_(f,c) - like Igeteof_, except EOF is an error 24611894Speter * cacheget_(c) - Iget_ applied to the local RILE 24711894Speter * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF 24811894Speter * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines 24911894Speter * 25011894Speter * By conventions, macros whose names end in _ are statements, not expressions. 25111894Speter * Following such macros with `; else' results in a syntax error. 2529Sjkh */ 2539Sjkh 25411894Speter#define maps_memory (has_map_fd || has_mmap) 25511894Speter 2569Sjkh#if large_memory 2579Sjkh typedef unsigned char const *Iptr_type; 25811894Speter typedef struct RILE { 2599Sjkh Iptr_type ptr, lim; 26011894Speter unsigned char *base; /* not Iptr_type for lint's sake */ 26111894Speter unsigned char *readlim; 26211894Speter int fd; 26311894Speter# if maps_memory 26411894Speter void (*deallocate) P((struct RILE *)); 2659Sjkh# else 2669Sjkh FILE *stream; 2679Sjkh# endif 2689Sjkh } RILE; 26911894Speter# if maps_memory 2709Sjkh# define declarecache register Iptr_type ptr, lim 2719Sjkh# define setupcache(f) (lim = (f)->lim) 27211894Speter# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++; 27311894Speter# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++; 2749Sjkh# else 27511894Speter int Igetmore P((RILE*)); 2769Sjkh# define declarecache register Iptr_type ptr; register RILE *rRILE 2779Sjkh# define setupcache(f) (rRILE = (f)) 27811894Speter# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++; 27911894Speter# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++; 2809Sjkh# endif 2819Sjkh# define uncache(f) ((f)->ptr = ptr) 2829Sjkh# define cache(f) (ptr = (f)->ptr) 28311894Speter# define Iget_(f,c) Igeteof_(f,c,Ieof();) 28411894Speter# define cacheget_(c) cachegeteof_(c,Ieof();) 28511894Speter# define cacheunget_(f,c) (c)=(--ptr)[-1]; 28611894Speter# define Ioffset_type size_t 28711894Speter# define Itell(f) ((f)->ptr - (f)->base) 28811894Speter# define Irewind(f) ((f)->ptr = (f)->base) 28911894Speter# define cacheptr() ptr 29011894Speter# define Ifileno(f) ((f)->fd) 2919Sjkh#else 2929Sjkh# define RILE FILE 2939Sjkh# define declarecache register FILE *ptr 2949Sjkh# define setupcache(f) (ptr = (f)) 2959Sjkh# define uncache(f) 2969Sjkh# define cache(f) 29711894Speter# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}} 29811894Speter# define cachegeteof_(c,s) Igeteof_(ptr,c,s) 29911894Speter# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); } 30011894Speter# define cacheget_(c) Iget_(ptr,c) 30111894Speter# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c) 30211894Speter# define Ioffset_type long 30311894Speter# define Itell(f) ftell(f) 3049Sjkh# define Ifileno(f) fileno(f) 3059Sjkh#endif 3069Sjkh 3079Sjkh/* Print a char, but abort on write error. */ 30811894Speter#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); } 3099Sjkh 3109Sjkh/* Get a character from an RCS file, perhaps copying to a new RCS file. */ 31111894Speter#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) } 31211894Speter#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) } 3139Sjkh 3149Sjkh 31511894Speter#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0)) 3169Sjkh/* computes mode of working file: same as RCSmode, but write permission */ 3179Sjkh/* determined by writable */ 3189Sjkh 3199Sjkh 3209Sjkh/* character classes and token codes */ 3219Sjkhenum tokens { 3229Sjkh/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter, 3239Sjkh PERIOD, SBEGIN, SPACE, UNKN, 3249Sjkh/* tokens */ COLON, ID, NUM, SEMI, STRING 3259Sjkh}; 3269Sjkh 3279Sjkh#define SDELIM '@' /* the actual character is needed for string handling*/ 3289Sjkh/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN. 3299Sjkh * there should be no overlap among SDELIM, KDELIM, and VDELIM 3309Sjkh */ 3319Sjkh 33211894Speter#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */ 3339Sjkh 3349Sjkh 3359Sjkh 3369Sjkh 3379Sjkh 3389Sjkh/*************************************** 3399Sjkh * Data structures for the symbol table 3409Sjkh ***************************************/ 3419Sjkh 3429Sjkh/* Buffer of arbitrary data */ 3439Sjkhstruct buf { 3449Sjkh char *string; 3459Sjkh size_t size; 3469Sjkh}; 3479Sjkhstruct cbuf { 3489Sjkh char const *string; 3499Sjkh size_t size; 3509Sjkh}; 3519Sjkh 3529Sjkh/* Hash table entry */ 3539Sjkhstruct hshentry { 3549Sjkh char const * num; /* pointer to revision number (ASCIZ) */ 3559Sjkh char const * date; /* pointer to date of checkin */ 3569Sjkh char const * author; /* login of person checking in */ 3579Sjkh char const * lockedby; /* who locks the revision */ 3589Sjkh char const * state; /* state of revision (Exp by default) */ 35911894Speter char const * name; /* name (if any) by which retrieved */ 3609Sjkh struct cbuf log; /* log message requested at checkin */ 3619Sjkh struct branchhead * branches; /* list of first revisions on branches*/ 36211894Speter struct cbuf ig; /* ignored phrases in admin part */ 36311894Speter struct cbuf igtext; /* ignored phrases in deltatext part */ 3649Sjkh struct hshentry * next; /* next revision on same branch */ 3659Sjkh struct hshentry * nexthsh; /* next revision with same hash value */ 36611894Speter long insertlns;/* lines inserted (computed by rlog) */ 36711894Speter long deletelns;/* lines deleted (computed by rlog) */ 3689Sjkh char selector; /* true if selected, false if deleted */ 3699Sjkh}; 3709Sjkh 3719Sjkh/* list of hash entries */ 3729Sjkhstruct hshentries { 3739Sjkh struct hshentries *rest; 3749Sjkh struct hshentry *first; 3759Sjkh}; 3769Sjkh 3779Sjkh/* list element for branch lists */ 3789Sjkhstruct branchhead { 3799Sjkh struct hshentry * hsh; 3809Sjkh struct branchhead * nextbranch; 3819Sjkh}; 3829Sjkh 3839Sjkh/* accesslist element */ 3849Sjkhstruct access { 3859Sjkh char const * login; 3869Sjkh struct access * nextaccess; 3879Sjkh}; 3889Sjkh 3899Sjkh/* list element for locks */ 39011894Speterstruct rcslock { 3919Sjkh char const * login; 3929Sjkh struct hshentry * delta; 39311894Speter struct rcslock * nextlock; 3949Sjkh}; 3959Sjkh 3969Sjkh/* list element for symbolic names */ 3979Sjkhstruct assoc { 3989Sjkh char const * symbol; 3999Sjkh char const * num; 4009Sjkh struct assoc * nextassoc; 4019Sjkh}; 4029Sjkh 4039Sjkh 4049Sjkh#define mainArgs (argc,argv) int argc; char **argv; 4059Sjkh 40611894Speter#if RCS_lint 4079Sjkh# define libId(name,rcsid) 4089Sjkh# define mainProg(name,cmd,rcsid) int name mainArgs 4099Sjkh#else 4109Sjkh# define libId(name,rcsid) char const name[] = rcsid; 41111894Speter# 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 4129Sjkh#endif 4139Sjkh 4149Sjkh/* 4159Sjkh * Markers for keyword expansion (used in co and ident) 4169Sjkh * Every byte must have class LETTER or Letter. 4179Sjkh */ 4189Sjkh#define AUTHOR "Author" 4199Sjkh#define DATE "Date" 4209Sjkh#define HEADER "Header" 4219Sjkh#define IDH "Id" 4229Sjkh#define LOCKER "Locker" 4239Sjkh#define LOG "Log" 42411894Speter#define NAME "Name" 4259Sjkh#define RCSFILE "RCSfile" 4269Sjkh#define REVISION "Revision" 4279Sjkh#define SOURCE "Source" 4289Sjkh#define STATE "State" 42925699Speter#define CVSHEADER "CVSHeader" 43025699Speter#define keylength 9 /* max length of any of the above keywords */ 4319Sjkh 4329Sjkhenum markers { Nomatch, Author, Date, Header, Id, 43325699Speter Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader, 43425699Speter LocalId }; 4359Sjkh /* This must be in the same order as rcskeys.c's Keyword[] array. */ 4369Sjkh 4379Sjkh#define DELNUMFORM "\n\n%s\n%s\n" 4389Sjkh/* used by putdtext and scanlogtext */ 4399Sjkh 4409Sjkh#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */ 4419Sjkh 4429Sjkh/* main program */ 4439Sjkhextern char const cmdid[]; 44411894Spetervoid exiterr P((void)) exiting; 4459Sjkh 4469Sjkh/* merge */ 44711894Speterint merge P((int,char const*,char const*const[3],char const*const[3])); 4489Sjkh 4499Sjkh/* rcsedit */ 4509Sjkh#define ciklogsize 23 /* sizeof("checked in with -k by ") */ 4519Sjkhextern FILE *fcopy; 45211894Speterextern char const *resultname; 4539Sjkhextern char const ciklog[ciklogsize]; 4549Sjkhextern int locker_expansion; 4559SjkhRILE *rcswriteopen P((struct buf*,struct stat*,int)); 45611894Speterchar const *makedirtemp P((int)); 4579Sjkhchar const *getcaller P((void)); 45811894Speterint addlock P((struct hshentry*,int)); 4599Sjkhint addsymbol P((char const*,char const*,int)); 4609Sjkhint checkaccesslist P((void)); 46111894Speterint chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t)); 46211894Speterint donerewrite P((int,time_t)); 4639Sjkhint dorewrite P((int,int)); 46411894Speterint expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int)); 4659Sjkhint findlock P((int,struct hshentry**)); 46611894Speterint setmtime P((char const*,time_t)); 46711894Spetervoid ORCSclose P((void)); 46811894Spetervoid ORCSerror P((void)); 4699Sjkhvoid copystring P((void)); 4709Sjkhvoid dirtempunlink P((void)); 4719Sjkhvoid enterstring P((void)); 4729Sjkhvoid finishedit P((struct hshentry const*,FILE*,int)); 4739Sjkhvoid keepdirtemp P((char const*)); 4749Sjkhvoid openfcopy P((FILE*)); 4759Sjkhvoid snapshotedit P((FILE*)); 4769Sjkhvoid xpandstring P((struct hshentry const*)); 4779Sjkh#if has_NFS || bad_unlink 4789Sjkh int un_link P((char const*)); 4799Sjkh#else 4809Sjkh# define un_link(s) unlink(s) 4819Sjkh#endif 4829Sjkh#if large_memory 4839Sjkh void edit_string P((void)); 4849Sjkh# define editstring(delta) edit_string() 4859Sjkh#else 4869Sjkh void editstring P((struct hshentry const*)); 4879Sjkh#endif 4889Sjkh 4899Sjkh/* rcsfcmp */ 4909Sjkhint rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*)); 4919Sjkh 4929Sjkh/* rcsfnms */ 49311894Speter#define bufautobegin(b) clear_buf(b) 49411894Speter#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0)) 4959Sjkhextern FILE *workstdout; 49611894Speterextern char *workname; 49711894Speterextern char const *RCSname; 4989Sjkhextern char const *suffixes; 49911894Speterextern int fdlock; 5009Sjkhextern struct stat RCSstat; 5019SjkhRILE *rcsreadopen P((struct buf*,struct stat*,int)); 5029Sjkhchar *bufenlarge P((struct buf*,char const**)); 50311894Speterchar const *basefilename P((char const*)); 5049Sjkhchar const *getfullRCSname P((void)); 50525699Speterchar const *getfullCVSname P((void)); 5069Sjkhchar const *maketemp P((int)); 5079Sjkhchar const *rcssuffix P((char const*)); 50811894Speterint pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int)); 5099Sjkhstruct cbuf bufremember P((struct buf*,size_t)); 5109Sjkhvoid bufalloc P((struct buf*,size_t)); 5119Sjkhvoid bufautoend P((struct buf*)); 5129Sjkhvoid bufrealloc P((struct buf*,size_t)); 5139Sjkhvoid bufscat P((struct buf*,char const*)); 5149Sjkhvoid bufscpy P((struct buf*,char const*)); 5159Sjkhvoid tempunlink P((void)); 5169Sjkh 5179Sjkh/* rcsgen */ 5189Sjkhextern int interactiveflag; 5199Sjkhextern struct buf curlogbuf; 5209Sjkhchar const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int)); 5219Sjkhint getcstdin P((void)); 52211894Speterint putdtext P((struct hshentry const*,char const*,FILE*,int)); 5239Sjkhint ttystdin P((void)); 52411894Speterint yesorno P((int,char const*,...)) printf_string(2,3); 5259Sjkhstruct cbuf cleanlogmsg P((char*,size_t)); 5269Sjkhstruct cbuf getsstdin P((char const*,char const*,char const*,struct buf*)); 5279Sjkhvoid putdesc P((int,char*)); 52811894Spetervoid putdftext P((struct hshentry const*,RILE*,FILE*,int)); 5299Sjkh 5309Sjkh/* rcskeep */ 5319Sjkhextern int prevkeys; 53211894Speterextern struct buf prevauthor, prevdate, prevname, prevrev, prevstate; 5339Sjkhint getoldkeys P((RILE*)); 5349Sjkh 5359Sjkh/* rcskeys */ 53625699Speterextern char const *Keyword[]; 53725699Speterextern enum markers LocalIdMode; 5389Sjkhenum markers trymatch P((char const*)); 53925699Spetervoid setRCSLocalId(char const *); 54025699Spetervoid setIncExc(char const *); 5419Sjkh 5429Sjkh/* rcslex */ 5439Sjkhextern FILE *foutptr; 5449Sjkhextern FILE *frewrite; 5459Sjkhextern RILE *finptr; 5469Sjkhextern char const *NextString; 5479Sjkhextern enum tokens nexttok; 5489Sjkhextern int hshenter; 5499Sjkhextern int nerror; 5509Sjkhextern int nextc; 5519Sjkhextern int quietflag; 55211894Speterextern long rcsline; 5539Sjkhchar const *getid P((void)); 55411894Spetervoid efaterror P((char const*)) exiting; 55511894Spetervoid enfaterror P((int,char const*)) exiting; 55611894Spetervoid fatcleanup P((int)) exiting; 55711894Spetervoid faterror P((char const*,...)) printf_string_exiting(1,2); 55811894Spetervoid fatserror P((char const*,...)) printf_string_exiting(1,2); 55911894Spetervoid rcsfaterror P((char const*,...)) printf_string_exiting(1,2); 56011894Spetervoid Ieof P((void)) exiting; 56111894Spetervoid Ierror P((void)) exiting; 56211894Spetervoid Oerror P((void)) exiting; 5639Sjkhchar *checkid P((char*,int)); 56411894Speterchar *checksym P((char*,int)); 5659Sjkhint eoflex P((void)); 5669Sjkhint getkeyopt P((char const*)); 5679Sjkhint getlex P((enum tokens)); 5689Sjkhstruct cbuf getphrases P((char const*)); 5699Sjkhstruct cbuf savestring P((struct buf*)); 5709Sjkhstruct hshentry *getnum P((void)); 5719Sjkhvoid Ifclose P((RILE*)); 5729Sjkhvoid Izclose P((RILE**)); 5739Sjkhvoid Lexinit P((void)); 5749Sjkhvoid Ofclose P((FILE*)); 57511894Spetervoid Orewind P((FILE*)); 5769Sjkhvoid Ozclose P((FILE**)); 57711894Spetervoid aflush P((FILE*)); 5789Sjkhvoid afputc P((int,FILE*)); 57911894Spetervoid aprintf P((FILE*,char const*,...)) printf_string(2,3); 5809Sjkhvoid aputs P((char const*,FILE*)); 5819Sjkhvoid checksid P((char*)); 58211894Spetervoid checkssym P((char*)); 58311894Spetervoid diagnose P((char const*,...)) printf_string(1,2); 5849Sjkhvoid eerror P((char const*)); 5859Sjkhvoid eflush P((void)); 5869Sjkhvoid enerror P((int,char const*)); 58711894Spetervoid error P((char const*,...)) printf_string(1,2); 5889Sjkhvoid fvfprintf P((FILE*,char const*,va_list)); 5899Sjkhvoid getkey P((char const*)); 5909Sjkhvoid getkeystring P((char const*)); 5919Sjkhvoid nextlex P((void)); 5929Sjkhvoid oflush P((void)); 5939Sjkhvoid printstring P((void)); 5949Sjkhvoid readstring P((void)); 5959Sjkhvoid redefined P((int)); 59611894Spetervoid rcserror P((char const*,...)) printf_string(1,2); 59711894Spetervoid rcswarn P((char const*,...)) printf_string(1,2); 5989Sjkhvoid testIerror P((FILE*)); 5999Sjkhvoid testOerror P((FILE*)); 60011894Spetervoid warn P((char const*,...)) printf_string(1,2); 6019Sjkhvoid warnignore P((void)); 60211894Spetervoid workerror P((char const*,...)) printf_string(1,2); 60311894Spetervoid workwarn P((char const*,...)) printf_string(1,2); 6049Sjkh#if has_madvise && has_mmap && large_memory 6059Sjkh void advise_access P((RILE*,int)); 6069Sjkh# define if_advise_access(p,f,advice) if (p) advise_access(f,advice) 6079Sjkh#else 6089Sjkh# define advise_access(f,advice) 6099Sjkh# define if_advise_access(p,f,advice) 6109Sjkh#endif 61111894Speter#if large_memory && maps_memory 6129Sjkh RILE *I_open P((char const*,struct stat*)); 6139Sjkh# define Iopen(f,m,s) I_open(f,s) 6149Sjkh#else 6159Sjkh RILE *Iopen P((char const*,char const*,struct stat*)); 6169Sjkh#endif 6179Sjkh#if !large_memory 6189Sjkh void testIeof P((FILE*)); 6199Sjkh void Irewind P((RILE*)); 6209Sjkh#endif 6219Sjkh 6229Sjkh/* rcsmap */ 62311894Speterextern enum tokens const ctab[]; 6249Sjkh 6259Sjkh/* rcsrev */ 62611894Speterchar *partialno P((struct buf*,char const*,int)); 62711894Speterchar const *namedrev P((char const*,struct hshentry*)); 6289Sjkhchar const *tiprev P((void)); 62911894Speterint cmpdate P((char const*,char const*)); 6309Sjkhint cmpnum P((char const*,char const*)); 63111894Speterint cmpnumfld P((char const*,char const*,int)); 63211894Speterint compartial P((char const*,char const*,int)); 6339Sjkhint expandsym P((char const*,struct buf*)); 6349Sjkhint fexpandsym P((char const*,struct buf*,RILE*)); 6359Sjkhstruct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**)); 63611894Speterint countnumflds P((char const*)); 6379Sjkhvoid getbranchno P((char const*,struct buf*)); 6389Sjkh 6399Sjkh/* rcssyn */ 6409Sjkh/* These expand modes must agree with Expand_names[] in rcssyn.c. */ 6419Sjkh#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */ 6429Sjkh#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */ 6439Sjkh#define KEY_EXPAND 2 /* -kk `$Keyword$' */ 6449Sjkh#define VAL_EXPAND 3 /* -kv `value' */ 6459Sjkh#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */ 64611894Speter#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */ 64711894Speter#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */ 64811894Speter#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND) 64911894Speter /* min value guaranteed to yield an identical file */ 6509Sjkhstruct diffcmd { 65111894Speter long 6529Sjkh line1, /* number of first line */ 6539Sjkh nlines, /* number of lines affected */ 6549Sjkh adprev, /* previous 'a' line1+1 or 'd' line1 */ 6559Sjkh dafter; /* sum of previous 'd' line1 and previous 'd' nlines */ 6569Sjkh}; 6579Sjkhextern char const * Dbranch; 6589Sjkhextern struct access * AccessList; 6599Sjkhextern struct assoc * Symbols; 6609Sjkhextern struct cbuf Comment; 66111894Speterextern struct cbuf Ignored; 66211894Speterextern struct rcslock *Locks; 6639Sjkhextern struct hshentry * Head; 6649Sjkhextern int Expand; 6659Sjkhextern int StrictLocks; 66611894Speterextern int TotalDeltas; 6679Sjkhextern char const *const expand_names[]; 66811894Speterextern char const 66911894Speter Kaccess[], Kauthor[], Kbranch[], Kcomment[], 67011894Speter Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[], 67111894Speter Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[]; 67211894Spetervoid unexpected_EOF P((void)) exiting; 6739Sjkhint getdiffcmd P((RILE*,int,FILE*,struct diffcmd*)); 6749Sjkhint str2expmode P((char const*)); 6759Sjkhvoid getadmin P((void)); 6769Sjkhvoid getdesc P((int)); 6779Sjkhvoid gettree P((void)); 67811894Spetervoid ignorephrases P((char const*)); 6799Sjkhvoid initdiffcmd P((struct diffcmd*)); 68011894Spetervoid putadmin P((void)); 6819Sjkhvoid putstring P((FILE*,int,struct cbuf,int)); 6829Sjkhvoid puttree P((struct hshentry const*,FILE*)); 6839Sjkh 68411894Speter/* rcstime */ 68511894Speter#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */ 68611894Speterchar const *date2str P((char const[datesize],char[datesize + zonelenmax])); 68711894Spetertime_t date2time P((char const[datesize])); 68811894Spetervoid str2date P((char const*,char[datesize])); 68911894Spetervoid time2date P((time_t,char[datesize])); 69011894Spetervoid zone_set P((char const*)); 69111894Speter 6929Sjkh/* rcsutil */ 6939Sjkhextern int RCSversion; 69411894SpeterFILE *fopenSafer P((char const*,char const*)); 6959Sjkhchar *cgetenv P((char const*)); 6969Sjkhchar *fstr_save P((char const*)); 6979Sjkhchar *str_save P((char const*)); 6989Sjkhchar const *getusername P((int)); 69911894Speterint fdSafer P((int)); 7009Sjkhint getRCSINIT P((int,char**,char***)); 70111894Speterint run P((int,char const*,...)); 70211894Speterint runv P((int,char const*,char const**)); 7039Sjkhmalloc_type fremember P((malloc_type)); 7049Sjkhmalloc_type ftestalloc P((size_t)); 7059Sjkhmalloc_type testalloc P((size_t)); 7069Sjkhmalloc_type testrealloc P((malloc_type,size_t)); 7079Sjkh#define ftalloc(T) ftnalloc(T,1) 7089Sjkh#define talloc(T) tnalloc(T,1) 70911894Speter#if RCS_lint 7109Sjkh extern malloc_type lintalloc; 7119Sjkh# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0) 7129Sjkh# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0) 7139Sjkh# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p) 7149Sjkh# define tfree(p) 7159Sjkh#else 7169Sjkh# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n))) 7179Sjkh# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n))) 7189Sjkh# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n))) 7199Sjkh# define tfree(p) free((malloc_type)(p)) 7209Sjkh#endif 72111894Spetertime_t now P((void)); 7229Sjkhvoid awrite P((char const*,size_t,FILE*)); 7239Sjkhvoid fastcopy P((RILE*,FILE*)); 7249Sjkhvoid ffree P((void)); 7259Sjkhvoid ffree1 P((char const*)); 7269Sjkhvoid setRCSversion P((char const*)); 7279Sjkh#if has_signal 7289Sjkh void catchints P((void)); 7299Sjkh void ignoreints P((void)); 7309Sjkh void restoreints P((void)); 7319Sjkh#else 7329Sjkh# define catchints() 7339Sjkh# define ignoreints() 7349Sjkh# define restoreints() 7359Sjkh#endif 73611894Speter#if has_mmap && large_memory 73711894Speter# if has_NFS && mmap_signal 73811894Speter void catchmmapints P((void)); 73911894Speter void readAccessFilenameBuffer P((char const*,unsigned char const*)); 74011894Speter# else 74111894Speter# define catchmmapints() 74211894Speter# endif 74311894Speter#endif 7449Sjkh#if has_getuid 7459Sjkh uid_t ruid P((void)); 7469Sjkh# define myself(u) ((u) == ruid()) 7479Sjkh#else 7489Sjkh# define myself(u) true 7499Sjkh#endif 7509Sjkh#if has_setuid 7519Sjkh uid_t euid P((void)); 7529Sjkh void nosetid P((void)); 7539Sjkh void seteid P((void)); 7549Sjkh void setrid P((void)); 7559Sjkh#else 7569Sjkh# define nosetid() 7579Sjkh# define seteid() 7589Sjkh# define setrid() 7599Sjkh#endif 76011894Speter 76111894Speter/* version */ 76211894Speterextern char const RCS_version_string[]; 763