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