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