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