xref: /netbsd/external/gpl2/xcvs/dist/src/cvs.h (revision 3feae4e4)
1 /*
2  * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
3  *
4  * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5  *                                  and others.
6  *
7  * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8  * Portions Copyright (C) 1989-1992, Brian Berliner
9  *
10  * You may distribute under the terms of the GNU General Public License as
11  * specified in the README file that comes with the CVS kit.
12  */
13 
14 /*
15  * basic information used in all source files
16  *
17  */
18 
19 
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>		/* this is stuff found via autoconf */
22 #endif /* HAVE_CONFIG_H */
23 
24 /* Add GNU attribute suppport.  */
25 #ifndef __attribute__
26 /* This feature is available in gcc versions 2.5 and later.  */
27 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
28 #  define __attribute__(Spec) /* empty */
29 # else
30 #   if __GNUC__ == 2 && __GNUC_MINOR__ < 96
31 #    define __pure__	/* empty */
32 #   endif
33 #   if __GNUC__ < 3
34 #    define __malloc__	/* empty */
35 #   endif
36 # endif
37 /* The __-protected variants of `format' and `printf' attributes
38    are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
39 # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
40 #  define __const__	const
41 #  define __format__	format
42 #  define __noreturn__	noreturn
43 #  define __printf__	printf
44 # endif
45 #endif /* __attribute__ */
46 
47 /* Some GNULIB headers require that we include system headers first.  */
48 #include "system.h"
49 
50 /* begin GNULIB headers */
51 #include "dirname.h"
52 #include "exit.h"
53 #include "getdate.h"
54 #include "minmax.h"
55 #include "regex.h"
56 #include "strcase.h"
57 #include "stat-macros.h"
58 #include "timespec.h"
59 #include "unlocked-io.h"
60 #include "xalloc.h"
61 #include "xgetcwd.h"
62 #include "xreadlink.h"
63 #include "xsize.h"
64 /* end GNULIB headers */
65 
66 #if ! STDC_HEADERS
67 char *getenv();
68 #endif /* ! STDC_HEADERS */
69 
70 /* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
71 #ifdef USE_OWN_POPEN
72 #include "popen.h"
73 #endif
74 
75 #ifdef SERVER_SUPPORT
76 /* If the system doesn't provide strerror, it won't be declared in
77    string.h.  */
78 char *strerror (int);
79 #endif
80 
81 #include "hash.h"
82 #include "stack.h"
83 
84 #include "root.h"
85 
86 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
87 # include "client.h"
88 #endif
89 
90 #ifdef MY_NDBM
91 #include "myndbm.h"
92 #else
93 #include <ndbm.h>
94 #endif /* MY_NDBM */
95 
96 #include "wait.h"
97 
98 #include "rcs.h"
99 
100 
101 
102 /* Note that the _ONLY_ reason for PATH_MAX is if various system calls (getwd,
103  * getcwd, readlink) require/want us to use it.  All other parts of CVS
104  * allocate pathname buffers dynamically, and we want to keep it that way.
105  */
106 #include "pathmax.h"
107 
108 
109 
110 /* Definitions for the CVS Administrative directory and the files it contains.
111    Here as #define's to make changing the names a simple task.  */
112 
113 #ifdef USE_VMS_FILENAMES
114 #define CVSADM          getCVSDir("")
115 #define CVSADM_ENT      getCVSDir("/Entries.")
116 #define CVSADM_ENTBAK   getCVSDir("/Entries.Backup")
117 #define CVSADM_ENTLOG   getCVSDir("/Entries.Log")
118 #define CVSADM_ENTSTAT  getCVSDir("/Entries.Static")
119 #define CVSADM_REP      getCVSDir("/Repository.")
120 #define CVSADM_ROOT     getCVSDir("/Root.")
121 #define CVSADM_CIPROG   getCVSDir("/Checkin.prog")
122 #define CVSADM_UPROG    getCVSDir("/Update.prog")
123 #define CVSADM_TAG      getCVSDir("/Tag.")
124 #define CVSADM_NOTIFY   getCVSDir("/Notify.")
125 #define CVSADM_NOTIFYTMP getCVSDir("/Notify.tmp")
126 #define CVSADM_BASE      getCVSDir("/Base")
127 #define CVSADM_BASEREV   getCVSDir("/Baserev.")
128 #define CVSADM_BASEREVTMP getCVSDir("/Baserev.tmp")
129 #define CVSADM_TEMPLATE getCVSDir("/Template.")
130 #else /* USE_VMS_FILENAMES */
131 #define	CVSADM		getCVSDir("")
132 #define	CVSADM_ENT	getCVSDir("/Entries")
133 #define	CVSADM_ENTBAK	getCVSDir("/Entries.Backup")
134 #define CVSADM_ENTLOG	getCVSDir("/Entries.Log")
135 #define	CVSADM_ENTSTAT	getCVSDir("/Entries.Static")
136 #define	CVSADM_REP	getCVSDir("/Repository")
137 #define	CVSADM_ROOT	getCVSDir("/Root")
138 #define	CVSADM_CIPROG	getCVSDir("/Checkin.prog")
139 #define	CVSADM_UPROG	getCVSDir("/Update.prog")
140 #define	CVSADM_TAG	getCVSDir("/Tag")
141 #define CVSADM_NOTIFY	getCVSDir("/Notify")
142 #define CVSADM_NOTIFYTMP getCVSDir("/Notify.tmp")
143 /* A directory in which we store base versions of files we currently are
144    editing with "cvs edit".  */
145 #define CVSADM_BASE     getCVSDir("/Base")
146 #define CVSADM_BASEREV  getCVSDir("/Baserev")
147 #define CVSADM_BASEREVTMP getCVSDir("/Baserev.tmp")
148 /* File which contains the template for use in log messages.  */
149 #define CVSADM_TEMPLATE getCVSDir("/Template")
150 #endif /* USE_VMS_FILENAMES */
151 
152 /* This is the special directory which we use to store various extra
153    per-directory information in the repository.  It must be the same as
154    CVSADM to avoid creating a new reserved directory name which users cannot
155    use, but is a separate #define because if anyone changes it (which I don't
156    recommend), one needs to deal with old, unconverted, repositories.
157 
158    See fileattr.h for details about file attributes, the only thing stored
159    in CVSREP currently.  */
160 #define CVSREP getCVSDir("")
161 
162 /*
163  * Definitions for the CVSROOT Administrative directory and the files it
164  * contains.  This directory is created as a sub-directory of the $CVSROOT
165  * environment variable, and holds global administration information for the
166  * entire source repository beginning at $CVSROOT.
167  */
168 #define	CVSROOTADM		"CVSROOT"
169 #define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
170 #define CVSROOTADM_COMMITINFO	"commitinfo"
171 #define CVSROOTADM_CONFIG	"config"
172 #define	CVSROOTADM_HISTORY	"history"
173 #define	CVSROOTADM_IGNORE	"cvsignore"
174 #define	CVSROOTADM_LOGINFO	"loginfo"
175 #define	CVSROOTADM_MODULES	"modules"
176 #define CVSROOTADM_NOTIFY	"notify"
177 #define CVSROOTADM_PASSWD	"passwd"
178 #define CVSROOTADM_POSTADMIN	"postadmin"
179 #define CVSROOTADM_POSTPROXY	"postproxy"
180 #define CVSROOTADM_POSTTAG	"posttag"
181 #define CVSROOTADM_POSTWATCH	"postwatch"
182 #define CVSROOTADM_PREPROXY	"preproxy"
183 #define	CVSROOTADM_RCSINFO	"rcsinfo"
184 #define CVSROOTADM_READERS	"readers"
185 #define CVSROOTADM_TAGINFO      "taginfo"
186 #define CVSROOTADM_USERS	"users"
187 #define CVSROOTADM_VALTAGS	"val-tags"
188 #define CVSROOTADM_VERIFYMSG    "verifymsg"
189 #define CVSROOTADM_WRAPPER	"cvswrappers"
190 #define CVSROOTADM_WRITERS	"writers"
191 
192 /* cvsacl patch */
193 #define CVSROOTADM_ACLCONFIG	"aclconfig"
194 #define CVSROOTADM_ACCESS	"access"
195 #define CVSROOTADM_GROUP	"group"
196 
197 #define CVSNULLREPOS		"Emptydir"	/* an empty directory */
198 
199 /* Other CVS file names */
200 
201 /* Files go in the attic if the head main branch revision is dead,
202    otherwise they go in the regular repository directories.  The whole
203    concept of having an attic is sort of a relic from before death
204    support but on the other hand, it probably does help the speed of
205    some operations (such as main branch checkouts and updates).  */
206 #define	CVSATTIC	"Attic"
207 
208 #define	CVSLCK		"#cvs.lock"
209 #define	CVSHISTORYLCK	"#cvs.history.lock"
210 #define	CVSVALTAGSLCK	"#cvs.val-tags.lock"
211 #define	CVSRFL		"#cvs.rfl"
212 #define	CVSPFL		"#cvs.pfl"
213 #define	CVSWFL		"#cvs.wfl"
214 #define CVSPFLPAT	"#cvs.pfl.*"	/* wildcard expr to match plocks */
215 #define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
216 #define	CVSEXT_LOG	",t"
217 #define	CVSPREFIX	",,"
218 #define CVSDOTIGNORE	".cvsignore"
219 #define CVSDOTWRAPPER   ".cvswrappers"
220 
221 /* Command attributes -- see function lookup_command_attribute(). */
222 #define CVS_CMD_IGNORE_ADMROOT        1
223 
224 /* Set if CVS needs to create a CVS/Root file upon completion of this
225    command.  The name may be slightly confusing, because the flag
226    isn't really as general purpose as it seems (it is not set for cvs
227    release).  */
228 
229 #define CVS_CMD_USES_WORK_DIR         2
230 
231 #define CVS_CMD_MODIFIES_REPOSITORY   4
232 
233 /* miscellaneous CVS defines */
234 
235 /* This is the string which is at the start of the non-log-message lines
236    that we put up for the user when they edit the log message.  */
237 #define	CVSEDITPREFIX	"CVS: "
238 /* Number of characters in CVSEDITPREFIX to compare when deciding to strip
239    off those lines.  We don't check for the space, to accomodate users who
240    have editors which strip trailing spaces.  */
241 #define CVSEDITPREFIXLEN 4
242 
243 #define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
244 #define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
245 #define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
246 
247 #ifdef USE_VMS_FILENAMES
248 # define BAKPREFIX	"_$"
249 #else /* USE_VMS_FILENAMES */
250 # define BAKPREFIX	".#"		/* when rcsmerge'ing */
251 #endif /* USE_VMS_FILENAMES */
252 
253 /*
254  * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
255  * sticky tags. -rBASE	refers to the current revision the user has checked
256  * out This mimics the behaviour of RCS.
257  */
258 #define	TAG_HEAD	"HEAD"
259 #define	TAG_BASE	"BASE"
260 
261 /* Environment variable used by CVS */
262 #define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
263 #define	CVSREAD_DFLT	0		/* writable files by default */
264 
265 #define	CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
266 
267 #define	TMPDIR_ENV	"TMPDIR"	/* Temporary directory */
268 #define	CVS_PID_ENV	"CVS_PID"	/* pid of running cvs */
269 
270 #define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
271 #define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
272 #define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
273 
274 #define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
275 /* Define CVSROOT_DFLT to a fallback value for CVSROOT.
276  *
277 #undef	CVSROOT_DFL
278  */
279 
280 #define	IGNORE_ENV	"CVSIGNORE"	/* More files to ignore */
281 #define WRAPPER_ENV     "CVSWRAPPERS"   /* name of the wrapper file */
282 
283 #define	CVSUMASK_ENV	"CVSUMASK"	/* Effective umask for repository */
284 
285 /*
286  * If the beginning of the Repository matches the following string, strip it
287  * so that the output to the logfile does not contain a full pathname.
288  *
289  * If the CVSROOT environment variable is set, it overrides this define.
290  */
291 #define	REPOS_STRIP	"/master/"
292 
293 /* Large enough to hold DATEFORM.  Not an arbitrary limit as long as
294    it is used for that purpose, and not to hold a string from the
295    command line, the client, etc.  */
296 #define MAXDATELEN	50
297 
298 /* The type of an entnode.  */
299 enum ent_type
300 {
301     ENT_FILE, ENT_SUBDIR
302 };
303 
304 /* structure of a entry record */
305 struct entnode
306 {
307     enum ent_type type;
308     char *user;
309     char *version;
310 
311     /* Timestamp, or "" if none (never NULL).  */
312     char *timestamp;
313 
314     /* Keyword expansion options, or "" if none (never NULL).  */
315     char *options;
316 
317     char *tag;
318     char *date;
319     char *conflict;
320 };
321 typedef struct entnode Entnode;
322 
323 /* The type of request that is being done in do_module() */
324 enum mtype
325 {
326     CHECKOUT, TAG, PATCH, EXPORT, MISC
327 };
328 
329 /*
330  * structure used for list-private storage by Entries_Open() and
331  * Version_TS() and Find_Directories().
332  */
333 struct stickydirtag
334 {
335     /* These fields pass sticky tag information from Entries_Open() to
336        Version_TS().  */
337     int aflag;
338     char *tag;
339     char *date;
340     int nonbranch;
341 
342     /* This field is set by Entries_Open() if there was subdirectory
343        information; Find_Directories() uses it to see whether it needs
344        to scan the directory itself.  */
345     int subdirs;
346 };
347 
348 /* Flags for find_{names,dirs} routines */
349 #define W_LOCAL			0x01	/* look for files locally */
350 #define W_REPOS			0x02	/* look for files in the repository */
351 #define W_ATTIC			0x04	/* look for files in the attic */
352 
353 /* Flags for return values of direnter procs for the recursion processor */
354 enum direnter_type
355 {
356     R_PROCESS = 1,			/* process files and maybe dirs */
357     R_SKIP_FILES,			/* don't process files in this dir */
358     R_SKIP_DIRS,			/* don't process sub-dirs */
359     R_SKIP_ALL				/* don't process files or dirs */
360 };
361 #ifdef ENUMS_CAN_BE_TROUBLE
362 typedef int Dtype;
363 #else
364 typedef enum direnter_type Dtype;
365 #endif
366 
367 /* Recursion processor lock types */
368 #define CVS_LOCK_NONE	0
369 #define CVS_LOCK_READ	1
370 #define CVS_LOCK_WRITE	2
371 
372 /* Option flags for Parse_Info() */
373 #define PIOPT_ALL 1	/* accept "all" keyword */
374 
375 extern const char *program_name, *program_path, *cvs_cmd_name;
376 extern char *Editor;
377 extern int cvsadmin_root;
378 extern char *CurDir;
379 extern int really_quiet, quiet;
380 extern int use_editor;
381 extern int cvswrite;
382 extern mode_t cvsumask;
383 
384 /* Temp dir abstraction.  */
385 /* From main.c.  */
386 const char *get_cvs_tmp_dir (void);
387 /* From filesubr.c.  */
388 const char *get_system_temp_dir (void);
389 void push_env_temp_dir (void);
390 
391 
392 /* This global variable holds the global -d option.  It is NULL if -d
393    was not used, which means that we must get the CVSroot information
394    from the CVSROOT environment variable or from a CVS/Root file.  */
395 extern char *CVSroot_cmdline;
396 
397 /* This variable keeps track of all of the CVSROOT directories that
398  * have been seen by the client.
399  */
400 extern List *root_directories;
401 
402 char *emptydir_name (void);
403 int safe_location (char *);
404 
405 extern int trace;		/* Show all commands */
406 extern int noexec;		/* Don't modify disk anywhere */
407 extern int nolock;		/* Don't create locks */
408 extern int readonlyfs;		/* fail on all write locks; succeed all read locks */
409 extern int logoff;		/* Don't write history entry */
410 
411 
412 
413 #define LOGMSG_REREAD_NEVER 0	/* do_verify - never  reread message */
414 #define LOGMSG_REREAD_ALWAYS 1	/* do_verify - always reread message */
415 #define LOGMSG_REREAD_STAT 2	/* do_verify - reread message if changed */
416 
417 /* This header needs the LOGMSG_* defns above.  */
418 #include "parseinfo.h"
419 
420 /* This structure holds the global configuration data.  */
421 extern struct config *config;
422 
423 #ifdef CLIENT_SUPPORT
424 extern List *dirs_sent_to_server; /* used to decide which "Argument
425 				     xxx" commands to send to each
426 				     server in multiroot mode. */
427 #endif
428 
429 extern char *hostname;
430 
431 /* Externs that are included directly in the CVS sources */
432 
433 int RCS_merge (RCSNode *, const char *, const char *, const char *,
434                const char *, const char *);
435 /* Flags used by RCS_* functions.  See the description of the individual
436    functions for which flags mean what for each function.  */
437 #define RCS_FLAGS_FORCE 1
438 #define RCS_FLAGS_DEAD 2
439 #define RCS_FLAGS_QUIET 4
440 #define RCS_FLAGS_MODTIME 8
441 #define RCS_FLAGS_KEEPFILE 16
442 #define RCS_FLAGS_USETIME 32
443 
444 int RCS_exec_rcsdiff (RCSNode *rcsfile, int diff_argc,
445                       char * const *diff_argv, const char *options,
446                       const char *rev1, const char *rev1_cache,
447                       const char *rev2,
448                       const char *label1, const char *label2,
449                       const char *workfile);
450 int diff_exec (const char *file1, const char *file2,
451                const char *label1, const char *label2,
452                int iargc, char * const *iargv, const char *out);
453 
454 
455 #include "error.h"
456 
457 /* If non-zero, error will use the CVS protocol to report error
458  * messages.  This will only be set in the CVS server parent process;
459  * most other code is run via do_cvs_command, which forks off a child
460  * process and packages up its stderr in the protocol.
461  *
462  * This needs to be here rather than in error.h in order to use an unforked
463  * error.h from GNULIB.
464  */
465 extern int error_use_protocol;
466 
467 /* cvsacl patch */
468 /* ACL Patch settings from CVSROOT/config */
469 extern int use_cvs_acl;
470 extern char *cvs_acl_default_permissions;
471 extern int use_cvs_groups;
472 extern int use_system_groups;
473 extern int use_separate_acl_file_for_each_dir;
474 extern char *cvs_acl_file_location;
475 extern char *cvs_groups_file_location;
476 extern char *cvs_server_run_as;
477 extern int stop_at_first_permission_denied;
478 
479 int given_perms_valid (const char *cperms);
480 int
481 access_allowed (const char *file, const char *repos, const char *tag,
482 		int perm, char **mline, int *mpos, int usecache);
483 
484 DBM *open_module (void);
485 List *Find_Directories (char *repository, int which, List *entries);
486 void Entries_Close (List *entries);
487 List *Entries_Open (int aflag, char *update_dir);
488 void Subdirs_Known (List *entries);
489 void Subdir_Register (List *, const char *, const char *);
490 void Subdir_Deregister (List *, const char *, const char *);
491 const char *getCVSDir (const char *);
492 
493 void parse_tagdate (char **tag, char **date, const char *input);
494 char *Make_Date (const char *rawdate);
495 char *date_from_time_t (time_t);
496 void date_to_internet (char *, const char *);
497 void date_to_tm (struct tm *, const char *);
498 void tm_to_internet (char *, const struct tm *);
499 char *gmformat_time_t (time_t unixtime);
500 char *format_date_alloc (char *text);
501 
502 char *Name_Repository (const char *dir, const char *update_dir);
503 const char *Short_Repository (const char *repository);
504 void Sanitize_Repository_Name (char *repository);
505 
506 char *entries_time (time_t unixtime);
507 time_t unix_time_stamp (const char *file);
508 char *time_stamp (const char *file);
509 
510 typedef	int (*CALLPROC)	(const char *repository, const char *value,
511                          void *closure);
512 int Parse_Info (const char *infofile, const char *repository,
513                 CALLPROC callproc, int opt, void *closure);
514 
515 typedef	RETSIGTYPE (*SIGCLEANUPPROC)	(int);
516 int SIG_register (int sig, SIGCLEANUPPROC sigcleanup);
517 bool isdir (const char *file);
518 bool isfile (const char *file);
519 ssize_t islink (const char *file, struct stat *stp);
520 bool isdevice (const char *file);
521 bool isreadable (const char *file);
522 bool iswritable (const char *file);
523 bool isaccessible (const char *file, const int mode);
524 const char *last_component (const char *path);
525 char *get_homedir (void);
526 char *strcat_filename_onto_homedir (const char *, const char *);
527 char *cvs_temp_name (void);
528 FILE *cvs_temp_file (char **filename);
529 
530 int ls (int argc, char *argv[]);
531 int unlink_file (const char *f);
532 int unlink_file_dir (const char *f);
533 
534 /* This is the structure that the recursion processor passes to the
535    fileproc to tell it about a particular file.  */
536 struct file_info
537 {
538     /* Name of the file, without any directory component.  */
539     const char *file;
540 
541     /* Name of the directory we are in, relative to the directory in
542        which this command was issued.  We have cd'd to this directory
543        (either in the working directory or in the repository, depending
544        on which sort of recursion we are doing).  If we are in the directory
545        in which the command was issued, this is "".  */
546     const char *update_dir;
547 
548     /* update_dir and file put together, with a slash between them as
549        necessary.  This is the proper way to refer to the file in user
550        messages.  */
551     const char *fullname;
552 
553     /* Name of the directory corresponding to the repository which contains
554        this file.  */
555     const char *repository;
556 
557     /* The pre-parsed entries for this directory.  */
558     List *entries;
559 
560     RCSNode *rcs;
561 };
562 
563 /* This needs to be included after the struct file_info definition since some
564  * of the functions subr.h defines refer to struct file_info.
565  */
566 #include "subr.h"
567 
568 int update (int argc, char *argv[]);
569 /* The only place this is currently used outside of update.c is add.c.
570  * Restricting its use to update.c seems to be in the best interest of
571  * modularity, but I can't think of a good way to get an update of a
572  * resurrected file done and print the fact otherwise.
573  */
574 void write_letter (struct file_info *finfo, int letter);
575 int xcmp (const char *file1, const char *file2);
576 void *valloc (size_t bytes);
577 
578 int Create_Admin (const char *dir, const char *update_dir,
579                   const char *repository, const char *tag, const char *date,
580                   int nonbranch, int warn, int dotemplate);
581 int expand_at_signs (const char *, size_t, FILE *);
582 
583 /* Locking subsystem (implemented in lock.c).  */
584 
585 int Reader_Lock (char *xrepository);
586 void Simple_Lock_Cleanup (void);
587 void Lock_Cleanup (void);
588 
589 /* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
590    and AFLAG, anyway.  */
591 void lock_tree_promotably (int argc, char **argv, int local, int which,
592 			   int aflag);
593 
594 /* See lock.c for description.  */
595 void lock_dir_for_write (const char *);
596 
597 /* Get a write lock for the history file.  */
598 int history_lock (const char *);
599 void clear_history_lock (void);
600 
601 /* Get a write lock for the val-tags file.  */
602 int val_tags_lock (const char *);
603 void clear_val_tags_lock (void);
604 
605 void Scratch_Entry (List * list, const char *fname);
606 void ParseTag (char **tagp, char **datep, int *nonbranchp);
607 void WriteTag (const char *dir, const char *tag, const char *date,
608                int nonbranch, const char *update_dir, const char *repository);
609 void WriteTemplate (const char *update_dir, int dotemplate,
610                     const char *repository);
611 void cat_module (int status);
612 void check_entries (char *dir);
613 void close_module (DBM * db);
614 void copy_file (const char *from, const char *to);
615 void fperrmsg (FILE * fp, int status, int errnum, char *message,...);
616 
617 int ign_name (char *name);
618 void ign_add (char *ign, int hold);
619 void ign_add_file (char *file, int hold);
620 void ign_setup (void);
621 void ign_dir_add (char *name);
622 int ignore_directory (const char *name);
623 typedef void (*Ignore_proc) (const char *, const char *);
624 void ignore_files (List *, List *, const char *, Ignore_proc);
625 extern int ign_inhibit_server;
626 
627 #include "update.h"
628 
629 void make_directories (const char *name);
630 void make_directory (const char *name);
631 int mkdir_if_needed (const char *name);
632 void rename_file (const char *from, const char *to);
633 /* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
634    files which exist in the current directory, and accordingly to OS-specific
635    conventions regarding wildcard syntax.  It might be desirable to change the
636    former in the future (e.g. "cvs status *.h" including files which don't exist
637    in the working directory).  The result is placed in *PARGC and *PARGV;
638    the *PARGV array itself and all the strings it contains are newly
639    malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
640 void expand_wild (int argc, char **argv,
641                   int *pargc, char ***pargv);
642 
643 /* exithandle.c */
644 void signals_register (RETSIGTYPE (*handler)(int));
645 void cleanup_register (void (*handler) (void));
646 
647 void update_delproc (Node * p);
648 void usage (const char *const *cpp);
649 void xchmod (const char *fname, int writable);
650 List *Find_Names (char *repository, int which, int aflag,
651 		  List ** optentries);
652 void Register (List * list, const char *fname, const char *vn, const char *ts,
653                const char *options, const char *tag, const char *date,
654                const char *ts_conflict);
655 void Update_Logfile (const char *repository, const char *xmessage,
656                      FILE *xlogfp, List *xchanges);
657 void do_editor (const char *dir, char **messagep,
658                 const char *repository, List *changes);
659 
660 void do_verify (char **messagep, const char *repository, List *changes);
661 
662 typedef	int (*CALLBACKPROC)	(int argc, char *argv[], char *where,
663 	char *mwhere, char *mfile, int shorten, int local_specified,
664 	char *omodule, char *msg);
665 
666 
667 typedef	int (*FILEPROC) (void *callerdat, struct file_info *finfo);
668 typedef	int (*FILESDONEPROC) (void *callerdat, int err,
669                               const char *repository, const char *update_dir,
670                               List *entries);
671 typedef	Dtype (*DIRENTPROC) (void *callerdat, const char *dir,
672                              const char *repos, const char *update_dir,
673                              List *entries);
674 typedef	int (*DIRLEAVEPROC) (void *callerdat, const char *dir, int err,
675                              const char *update_dir, List *entries);
676 
677 int mkmodules (char *dir);
678 int init (int argc, char **argv);
679 
680 int do_module (DBM * db, char *mname, enum mtype m_type, char *msg,
681 		CALLBACKPROC callback_proc, char *where, int shorten,
682 		int local_specified, int run_module_prog, int build_dirs,
683 		char *extra_arg);
684 void history_write (int type, const char *update_dir, const char *revs,
685                     const char *name, const char *repository);
686 int start_recursion (FILEPROC fileproc, FILESDONEPROC filesdoneproc,
687 		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
688 		     void *callerdat,
689 		     int argc, char *argv[], int local, int which,
690 		     int aflag, int locktype, char *update_preload,
691 		     int dosrcs, char *repository);
692 void SIG_beginCrSect (void);
693 void SIG_endCrSect (void);
694 int SIG_inCrSect (void);
695 void read_cvsrc (int *argc, char ***argv, const char *cmdname);
696 
697 /* flags for run_exec(), the fast system() for CVS */
698 #define	RUN_NORMAL            0x0000    /* no special behaviour */
699 #define	RUN_COMBINED          0x0001    /* stdout is duped to stderr */
700 #define	RUN_REALLY            0x0002    /* do the exec, even if noexec is on */
701 #define	RUN_STDOUT_APPEND     0x0004    /* append to stdout, don't truncate */
702 #define	RUN_STDERR_APPEND     0x0008    /* append to stderr, don't truncate */
703 #define	RUN_SIGIGNORE         0x0010    /* ignore interrupts for command */
704 #define	RUN_UNSETXID          0x0020	/* undo setxid in child */
705 #define	RUN_TTY               (char *)0 /* for the benefit of lint */
706 
707 void run_add_arg_p (int *, size_t *, char ***, const char *s);
708 void run_arg_free_p (int, char **);
709 void run_add_arg (const char *s);
710 void run_print (FILE * fp);
711 void run_setup (const char *prog);
712 int run_exec (const char *stin, const char *stout, const char *sterr,
713               int flags);
714 int run_piped (int *, int *);
715 
716 /* other similar-minded stuff from run.c.  */
717 FILE *run_popen (const char *, const char *);
718 int piped_child (char *const *, int *, int *, bool);
719 void close_on_exec (int);
720 
721 pid_t waitpid (pid_t, int *, int);
722 
723 /*
724  * a struct vers_ts contains all the information about a file including the
725  * user and rcs file names, and the version checked out and the head.
726  *
727  * this is usually obtained from a call to Version_TS which takes a
728  * tag argument for the RCS file if desired
729  */
730 struct vers_ts
731 {
732     /* rcs version user file derives from, from CVS/Entries.
733        It can have the following special values:
734 
735        NULL = file is not mentioned in Entries (this is also used for a
736 	      directory).
737        "" = INVALID!  The comment used to say that it meant "no user file"
738 	    but as far as I know CVS didn't actually use it that way.
739 	    Note that according to cvs.texinfo, "" is not valid in the
740 	    Entries file.
741        0 = user file is new
742        -vers = user file to be removed.  */
743     char *vn_user;
744 
745     /* Numeric revision number corresponding to ->vn_tag (->vn_tag
746        will often be symbolic).  */
747     char *vn_rcs;
748     /* If ->tag is a simple tag in the RCS file--a tag which really
749        exists which is not a magic revision--and if ->date is NULL,
750        then this is a copy of ->tag.  Otherwise, it is a copy of
751        ->vn_rcs.  */
752     char *vn_tag;
753 
754     /* This is the timestamp from stating the file in the working directory.
755        It is NULL if there is no file in the working directory.  It is
756        "Is-modified" if we know the file is modified but don't have its
757        contents.  */
758     char *ts_user;
759     /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
760        are computed in a slightly different way, but the fact remains that
761        if they are equal the file in the working directory is unmodified
762        and if they differ it is modified.  */
763     char *ts_rcs;
764 
765     /* Options from CVS/Entries (keyword expansion), malloc'd.  If none,
766        then it is an empty string (never NULL).  */
767     char *options;
768 
769     /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
770        and the time stamp in this field is the time stamp of the working
771        directory file which was created with the conflict markers in it.
772        This is from CVS/Entries.  */
773     char *ts_conflict;
774 
775     /* Tag specified on the command line, or if none, tag stored in
776        CVS/Entries.  */
777     char *tag;
778     /* Date specified on the command line, or if none, date stored in
779        CVS/Entries.  */
780     char *date;
781     /* If this is 1, then tag is not a branch tag.  If this is 0, then
782        tag may or may not be a branch tag.  */
783     int nonbranch;
784 
785     /* Pointer to entries file node  */
786     Entnode *entdata;
787 
788     /* Pointer to parsed src file info */
789     RCSNode *srcfile;
790 };
791 typedef struct vers_ts Vers_TS;
792 
793 Vers_TS *Version_TS (struct file_info *finfo, char *options, char *tag,
794 			    char *date, int force_tag_match,
795 			    int set_time);
796 void freevers_ts (Vers_TS ** versp);
797 
798 /* Miscellaneous CVS infrastructure which layers on top of the recursion
799    processor (for example, needs struct file_info).  */
800 
801 int Checkin (int type, struct file_info *finfo, char *rev,
802 	     char *tag, char *options, char *message);
803 int No_Difference (struct file_info *finfo, Vers_TS *vers);
804 /* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
805 int special_file_mismatch (struct file_info *finfo,
806 				  char *rev1, char *rev2);
807 
808 /* CVSADM_BASEREV stuff, from entries.c.  */
809 char *base_get (struct file_info *);
810 void base_register (struct file_info *, char *);
811 void base_deregister (struct file_info *);
812 
813 /*
814  * defines for Classify_File() to determine the current state of a file.
815  * These are also used as types in the data field for the list we make for
816  * Update_Logfile in commit, import, and add.
817  */
818 enum classify_type
819 {
820     T_UNKNOWN = 1,			/* no old-style analog existed	 */
821     T_CONFLICT,				/* C (conflict) list		 */
822     T_NEEDS_MERGE,			/* G (needs merging) list	 */
823     T_MODIFIED,				/* M (needs checked in) list 	 */
824     T_CHECKOUT,				/* O (needs checkout) list	 */
825     T_ADDED,				/* A (added file) list		 */
826     T_REMOVED,				/* R (removed file) list	 */
827     T_REMOVE_ENTRY,			/* W (removed entry) list	 */
828     T_UPTODATE,				/* File is up-to-date		 */
829     T_PATCH,				/* P Like C, but can patch	 */
830     T_TITLE				/* title for node type 		 */
831 };
832 typedef enum classify_type Ctype;
833 
834 Ctype Classify_File (struct file_info *finfo, char *tag, char *date, char *options,
835       int force_tag_match, int aflag, Vers_TS **versp, int pipeout);
836 
837 /*
838  * structure used for list nodes passed to Update_Logfile() and
839  * do_editor().
840  */
841 struct logfile_info
842 {
843   enum classify_type type;
844   char *tag;
845   char *rev_old;		/* rev number before a commit/modify,
846 				   NULL for add or import */
847   char *rev_new;		/* rev number after a commit/modify,
848 				   add, or import, NULL for remove */
849 };
850 
851 /* Wrappers.  */
852 
853 typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
854 typedef enum {
855     /* -t and -f wrapper options.  Treating directories as single files.  */
856     WRAP_TOCVS,
857     WRAP_FROMCVS,
858     /* -k wrapper option.  Default keyword expansion options.  */
859     WRAP_RCSOPTION
860 } WrapMergeHas;
861 
862 void  wrap_setup (void);
863 int   wrap_name_has (const char *name,WrapMergeHas has);
864 char *wrap_rcsoption (const char *fileName, int asFlag);
865 char *wrap_tocvs_process_file (const char *fileName);
866 int   wrap_merge_is_copy (const char *fileName);
867 void wrap_fromcvs_process_file (const char *fileName);
868 void wrap_add_file (const char *file,int temp);
869 void wrap_add (char *line,int temp);
870 void wrap_send (void);
871 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
872 void wrap_unparse_rcs_options (char **, int);
873 #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
874 
875 /* Pathname expansion */
876 char *expand_path (const char *name, const char *cvsroot, bool formatsafe,
877 		   const char *file, int line);
878 
879 /* User variables.  */
880 extern List *variable_list;
881 
882 /* cvsacl patch */
883 extern int cvsacl (int argc, char **argv);
884 
885 void variable_set (char *nameval);
886 
887 int watch (int argc, char **argv);
888 int edit (int argc, char **argv);
889 int unedit (int argc, char **argv);
890 int editors (int argc, char **argv);
891 int watchers (int argc, char **argv);
892 int annotate (int argc, char **argv);
893 int add (int argc, char **argv);
894 int admin (int argc, char **argv);
895 int checkout (int argc, char **argv);
896 int commit (int argc, char **argv);
897 int diff (int argc, char **argv);
898 int history (int argc, char **argv);
899 int import (int argc, char **argv);
900 int cvslog (int argc, char **argv);
901 #ifdef AUTH_CLIENT_SUPPORT
902 /* Some systems (namely Mac OS X) have conflicting definitions for these
903  * functions.  Avoid them.
904  */
905 #ifdef HAVE_LOGIN
906 # define login		cvs_login
907 #endif /* HAVE_LOGIN */
908 #ifdef HAVE_LOGOUT
909 # define logout		cvs_logout
910 #endif /* HAVE_LOGOUT */
911 int login (int argc, char **argv);
912 int logout (int argc, char **argv);
913 #endif /* AUTH_CLIENT_SUPPORT */
914 int patch (int argc, char **argv);
915 int release (int argc, char **argv);
916 int cvsremove (int argc, char **argv);
917 int rtag (int argc, char **argv);
918 int cvsstatus (int argc, char **argv);
919 int cvstag (int argc, char **argv);
920 int version (int argc, char **argv);
921 int admin_group_member (void);
922 void free_cvs_password (char *);
923 void getoptreset (void);
924 
925 unsigned long int lookup_command_attribute (const char *);
926 
927 #if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
928 char *scramble (char *str);
929 char *descramble (char *str);
930 #endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
931 
932 #ifdef AUTH_CLIENT_SUPPORT
933 char *get_cvs_password (void);
934 /* get_cvs_port_number() is not pure since the /etc/services file could change
935  * between calls.  */
936 int get_cvs_port_number (const cvsroot_t *root);
937 /* normalize_cvsroot() is not pure since it calls get_cvs_port_number.  */
938 char *normalize_cvsroot (const cvsroot_t *root)
939 	__attribute__ ((__malloc__));
940 #endif /* AUTH_CLIENT_SUPPORT */
941 
942 void tag_check_valid (const char *, int, char **, int, int, char *, bool);
943 
944 #include "server.h"
945 
946 /* From server.c and documented there.  */
947 void cvs_output (const char *, size_t);
948 void cvs_output_binary (char *, size_t);
949 void cvs_outerr (const char *, size_t);
950 void cvs_flusherr (void);
951 void cvs_flushout (void);
952 void cvs_output_tagged (const char *, const char *);
953 
954 extern const char *global_session_id;
955 
956 /* From find_names.c.  */
957 List *find_files (const char *dir, const char *pat);
958