xref: /openbsd-src/gnu/usr.bin/cvs/src/cvs.h (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /*
2  * Copyright (c) 1992, Brian Berliner and Jeff Polk
3  * Copyright (c) 1989-1992, Brian Berliner
4  *
5  * You may distribute under the terms of the GNU General Public License as
6  * specified in the README file that comes with the CVS kit.
7  */
8 
9 /*
10  * basic information used in all source files
11  *
12  */
13 
14 
15 #include "config.h"		/* this is stuff found via autoconf */
16 #include "options.h"		/* these are some larger questions which
17 				   can't easily be automatically checked
18 				   for */
19 
20 /* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
21 
22 #ifdef __STDC__
23 #define	PTR	void *
24 #else
25 #define	PTR	char *
26 #endif
27 
28 /* Add prototype support.  */
29 #ifndef PROTO
30 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
31 #define PROTO(ARGS) ARGS
32 #else
33 #define PROTO(ARGS) ()
34 #endif
35 #endif
36 
37 #include <stdio.h>
38 
39 /* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
40 #ifdef USE_OWN_POPEN
41 #include "popen.h"
42 #endif
43 
44 #ifdef STDC_HEADERS
45 #include <stdlib.h>
46 #else
47 extern void exit ();
48 extern char *getenv();
49 #endif
50 
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 
55 #ifdef HAVE_STRING_H
56 #include <string.h>
57 #else
58 #include <strings.h>
59 #endif
60 
61 #ifdef SERVER_SUPPORT
62 /* If the system doesn't provide strerror, it won't be declared in
63    string.h.  */
64 char *strerror ();
65 #endif
66 
67 #include <fnmatch.h> /* This is supposed to be available on Posix systems */
68 
69 #include <ctype.h>
70 #include <pwd.h>
71 #include <signal.h>
72 
73 #ifdef HAVE_ERRNO_H
74 #include <errno.h>
75 #else
76 #ifndef errno
77 extern int errno;
78 #endif /* !errno */
79 #endif /* HAVE_ERRNO_H */
80 
81 #include "system.h"
82 
83 #include "hash.h"
84 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
85 #include "client.h"
86 #endif
87 
88 #ifdef MY_NDBM
89 #include "myndbm.h"
90 #else
91 #include <ndbm.h>
92 #endif /* MY_NDBM */
93 
94 #include "regex.h"
95 #include "getopt.h"
96 #include "wait.h"
97 
98 #include "rcs.h"
99 
100 
101 /* This actually gets set in system.h.  Note that the _ONLY_ reason for
102    this is if various system calls (getwd, getcwd, readlink) require/want
103    us to use it.  All other parts of CVS allocate pathname buffers
104    dynamically, and we want to keep it that way.  */
105 #ifndef PATH_MAX
106 #ifdef MAXPATHLEN
107 #define	PATH_MAX MAXPATHLEN+2
108 #else
109 #define	PATH_MAX 1024+2
110 #endif
111 #endif /* PATH_MAX */
112 
113 /* Definitions for the CVS Administrative directory and the files it contains.
114    Here as #define's to make changing the names a simple task.  */
115 
116 #ifdef USE_VMS_FILENAMES
117 #define CVSADM          "CVS"
118 #define CVSADM_ENT      "CVS/Entries."
119 #define CVSADM_ENTBAK   "CVS/Entries.Backup"
120 #define CVSADM_ENTLOG   "CVS/Entries.Log"
121 #define CVSADM_ENTSTAT  "CVS/Entries.Static"
122 #define CVSADM_REP      "CVS/Repository."
123 #define CVSADM_ROOT     "CVS/Root."
124 #define CVSADM_CIPROG   "CVS/Checkin.prog"
125 #define CVSADM_UPROG    "CVS/Update.prog"
126 #define CVSADM_TAG      "CVS/Tag."
127 #define CVSADM_NOTIFY   "CVS/Notify."
128 #define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
129 #define CVSADM_BASE      "CVS/Base"
130 #define CVSADM_BASEREV   "CVS/Baserev."
131 #define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
132 #define CVSADM_TEMPLATE "CVS/Template."
133 #else /* USE_VMS_FILENAMES */
134 #define	CVSADM		"CVS"
135 #define	CVSADM_ENT	"CVS/Entries"
136 #define	CVSADM_ENTBAK	"CVS/Entries.Backup"
137 #define CVSADM_ENTLOG	"CVS/Entries.Log"
138 #define	CVSADM_ENTSTAT	"CVS/Entries.Static"
139 #define	CVSADM_REP	"CVS/Repository"
140 #define	CVSADM_ROOT	"CVS/Root"
141 #define	CVSADM_CIPROG	"CVS/Checkin.prog"
142 #define	CVSADM_UPROG	"CVS/Update.prog"
143 #define	CVSADM_TAG	"CVS/Tag"
144 #define CVSADM_NOTIFY	"CVS/Notify"
145 #define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
146 /* A directory in which we store base versions of files we currently are
147    editing with "cvs edit".  */
148 #define CVSADM_BASE     "CVS/Base"
149 #define CVSADM_BASEREV  "CVS/Baserev"
150 #define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
151 /* File which contains the template for use in log messages.  */
152 #define CVSADM_TEMPLATE "CVS/Template"
153 #endif /* USE_VMS_FILENAMES */
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_MODULES	"modules"
173 #define	CVSROOTADM_LOGINFO	"loginfo"
174 #define	CVSROOTADM_RCSINFO	"rcsinfo"
175 #define CVSROOTADM_COMMITINFO	"commitinfo"
176 #define CVSROOTADM_TAGINFO      "taginfo"
177 #define	CVSROOTADM_EDITINFO	"editinfo"
178 #define CVSROOTADM_VERIFYMSG    "verifymsg"
179 #define	CVSROOTADM_HISTORY	"history"
180 #define CVSROOTADM_VALTAGS	"val-tags"
181 #define	CVSROOTADM_IGNORE	"cvsignore"
182 #define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
183 #define CVSROOTADM_WRAPPER	"cvswrappers"
184 #define CVSROOTADM_NOTIFY	"notify"
185 #define CVSROOTADM_USERS	"users"
186 #define CVSROOTADM_READERS	"readers"
187 #define CVSROOTADM_WRITERS	"writers"
188 #define CVSROOTADM_PASSWD	"passwd"
189 #define CVSROOTADM_CONFIG	"config"
190 
191 #define CVSNULLREPOS		"Emptydir"	/* an empty directory */
192 
193 /* Other CVS file names */
194 
195 /* Files go in the attic if the head main branch revision is dead,
196    otherwise they go in the regular repository directories.  The whole
197    concept of having an attic is sort of a relic from before death
198    support but on the other hand, it probably does help the speed of
199    some operations (such as main branch checkouts and updates).  */
200 #define	CVSATTIC	"Attic"
201 
202 #define	CVSLCK		"#cvs.lock"
203 #define	CVSRFL		"#cvs.rfl"
204 #define	CVSWFL		"#cvs.wfl"
205 #define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
206 #define	CVSEXT_LOG	",t"
207 #define	CVSPREFIX	",,"
208 #define CVSDOTIGNORE	".cvsignore"
209 #define CVSDOTWRAPPER   ".cvswrappers"
210 
211 /* Command attributes -- see function lookup_command_attribute(). */
212 #define CVS_CMD_IGNORE_ADMROOT        1
213 
214 /* Set if CVS needs to create a CVS/Root file upon completion of this
215    command.  The name may be slightly confusing, because the flag
216    isn't really as general purpose as it seems (it is not set for cvs
217    release).  */
218 
219 #define CVS_CMD_USES_WORK_DIR         2
220 
221 #define CVS_CMD_MODIFIES_REPOSITORY   4
222 
223 /* miscellaneous CVS defines */
224 
225 /* This is the string which is at the start of the non-log-message lines
226    that we put up for the user when they edit the log message.  */
227 #define	CVSEDITPREFIX	"CVS: "
228 /* Number of characters in CVSEDITPREFIX to compare when deciding to strip
229    off those lines.  We don't check for the space, to accomodate users who
230    have editors which strip trailing spaces.  */
231 #define CVSEDITPREFIXLEN 4
232 
233 #define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
234 #define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
235 #define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
236 
237 #ifdef USE_VMS_FILENAMES
238 #define BAKPREFIX       "_$"
239 #define DEVNULL         "NLA0:"
240 #else /* USE_VMS_FILENAMES */
241 #define	BAKPREFIX	".#"		/* when rcsmerge'ing */
242 #ifndef DEVNULL
243 #define	DEVNULL		"/dev/null"
244 #endif
245 #endif /* USE_VMS_FILENAMES */
246 
247 /*
248  * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
249  * sticky tags. -rBASE	refers to the current revision the user has checked
250  * out This mimics the behaviour of RCS.
251  */
252 #define	TAG_HEAD	"HEAD"
253 #define	TAG_BASE	"BASE"
254 
255 /* Environment variable used by CVS */
256 #define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
257 #define	CVSREAD_DFLT	0		/* writable files by default */
258 
259 #define	CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
260 
261 #define	TMPDIR_ENV	"TMPDIR"	/* Temporary directory */
262 /* #define	TMPDIR_DFLT		   Set by options.h */
263 
264 #define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
265 #define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
266 #define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
267 /* #define	EDITOR_DFLT		   Set by options.h */
268 
269 #define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
270 #define	CVSROOT_DFLT	NULL		/* No dflt; must set for checkout */
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 /* #define	CVSUMASK_DFLT		   Set by options.h */
277 
278 /*
279  * If the beginning of the Repository matches the following string, strip it
280  * so that the output to the logfile does not contain a full pathname.
281  *
282  * If the CVSROOT environment variable is set, it overrides this define.
283  */
284 #define	REPOS_STRIP	"/master/"
285 
286 /* Large enough to hold DATEFORM.  Not an arbitrary limit as long as
287    it is used for that purpose, and not to hold a string from the
288    command line, the client, etc.  */
289 #define MAXDATELEN	50
290 
291 /* The type of an entnode.  */
292 enum ent_type
293 {
294     ENT_FILE, ENT_SUBDIR
295 };
296 
297 /* structure of a entry record */
298 struct entnode
299 {
300     enum ent_type type;
301     char *user;
302     char *version;
303 
304     /* Timestamp, or "" if none (never NULL).  */
305     char *timestamp;
306 
307     /* Keyword expansion options, or "" if none (never NULL).  */
308     char *options;
309 
310     char *tag;
311     char *date;
312     char *conflict;
313 };
314 typedef struct entnode Entnode;
315 
316 /* The type of request that is being done in do_module() */
317 enum mtype
318 {
319     CHECKOUT, TAG, PATCH, EXPORT, MISC
320 };
321 
322 /*
323  * structure used for list-private storage by Entries_Open() and
324  * Version_TS() and Find_Directories().
325  */
326 struct stickydirtag
327 {
328     /* These fields pass sticky tag information from Entries_Open() to
329        Version_TS().  */
330     int aflag;
331     char *tag;
332     char *date;
333     int nonbranch;
334 
335     /* This field is set by Entries_Open() if there was subdirectory
336        information; Find_Directories() uses it to see whether it needs
337        to scan the directory itself.  */
338     int subdirs;
339 };
340 
341 /* Flags for find_{names,dirs} routines */
342 #define W_LOCAL			0x01	/* look for files locally */
343 #define W_REPOS			0x02	/* look for files in the repository */
344 #define W_ATTIC			0x04	/* look for files in the attic */
345 
346 /* Flags for return values of direnter procs for the recursion processor */
347 enum direnter_type
348 {
349     R_PROCESS = 1,			/* process files and maybe dirs */
350     R_SKIP_FILES,			/* don't process files in this dir */
351     R_SKIP_DIRS,			/* don't process sub-dirs */
352     R_SKIP_ALL				/* don't process files or dirs */
353 };
354 #ifdef ENUMS_CAN_BE_TROUBLE
355 typedef int Dtype;
356 #else
357 typedef enum direnter_type Dtype;
358 #endif
359 
360 extern char *program_name, *program_path, *command_name;
361 extern char *Tmpdir, *Editor;
362 extern int cvsadmin_root;
363 extern char *CurDir;
364 extern int really_quiet, quiet;
365 extern int use_editor;
366 extern int cvswrite;
367 extern mode_t cvsumask;
368 extern char *RCS_citag;
369 
370 /* Access method specified in CVSroot. */
371 typedef enum {
372   null_method, local_method, server_method, pserver_method, kserver_method, gserver_method,
373   ext_method, fork_method
374 } CVSmethod;
375 extern char *method_names[];	/* change this in root.c if you change
376 				   the enum above */
377 
378 typedef struct cvsroot_s {
379     char *original;		/* the complete source CVSroot string */
380     CVSmethod method;		/* one of the enum values above */
381     char *username;		/* the username or NULL if method == local */
382     char *password;		/* the username or NULL if method == local */
383     char *hostname;		/* the hostname or NULL if method == local */
384     int port;			/* the port or zero if method == local */
385     char *directory;		/* the directory name */
386 #ifdef CLIENT_SUPPORT
387     unsigned char isremote;	/* nonzero if we are doing remote access */
388 #endif /* CLIENT_SUPPORT */
389 } cvsroot_t;
390 
391 /* This global variable holds the global -d option.  It is NULL if -d
392    was not used, which means that we must get the CVSroot information
393    from the CVSROOT environment variable or from a CVS/Root file.  */
394 extern char *CVSroot_cmdline;
395 
396 /* These variables keep track of all of the CVSROOT directories that
397    have been seen by the client and the current one of those selected.  */
398 extern List *root_directories;
399 extern cvsroot_t *current_parsed_root;
400 
401 extern char *emptydir_name PROTO ((void));
402 extern int safe_location PROTO ((void));
403 
404 extern int trace;		/* Show all commands */
405 extern int noexec;		/* Don't modify disk anywhere */
406 extern int readonlyfs;		/* fail on all write locks; succeed all read locks */
407 extern int logoff;		/* Don't write history entry */
408 
409 extern int top_level_admin;
410 
411 #ifdef CLIENT_SUPPORT
412 extern List *dirs_sent_to_server; /* used to decide which "Argument
413 				     xxx" commands to send to each
414 				     server in multiroot mode. */
415 #endif
416 
417 extern char hostname[];
418 
419 /* Externs that are included directly in the CVS sources */
420 
421 int RCS_merge PROTO((RCSNode *, char *, char *, char *, char *, char *));
422 /* Flags used by RCS_* functions.  See the description of the individual
423    functions for which flags mean what for each function.  */
424 #define RCS_FLAGS_FORCE 1
425 #define RCS_FLAGS_DEAD 2
426 #define RCS_FLAGS_QUIET 4
427 #define RCS_FLAGS_MODTIME 8
428 #define RCS_FLAGS_KEEPFILE 16
429 
430 extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
431 				    char *opts, char *options,
432 				    char *rev1, char *rev2,
433 				    char *label1, char *label2,
434 				    char *workfile));
435 extern int diff_exec PROTO ((char *file1, char *file2,
436 			     char *label1, char *label2,
437 			     char *options, char *out));
438 extern int diff_execv PROTO ((char *file1, char *file2,
439 			      char *label1, char *label2,
440 			      char *options, char *out));
441 
442 
443 
444 #include "error.h"
445 
446 DBM *open_module PROTO((void));
447 FILE *open_file PROTO((const char *, const char *));
448 List *Find_Directories PROTO((char *repository, int which, List *entries));
449 void Entries_Close PROTO((List *entries));
450 List *Entries_Open PROTO ((int aflag, char *update_dir));
451 void Subdirs_Known PROTO((List *entries));
452 void Subdir_Register PROTO((List *, const char *, const char *));
453 void Subdir_Deregister PROTO((List *, const char *, const char *));
454 
455 char *Make_Date PROTO((char *rawdate));
456 char *date_from_time_t PROTO ((time_t));
457 void date_to_internet PROTO ((char *, const char *));
458 void date_to_tm PROTO ((struct tm *, const char *));
459 void tm_to_internet PROTO ((char *, const struct tm *));
460 
461 char *Name_Repository PROTO((char *dir, char *update_dir));
462 char *Short_Repository PROTO((char *repository));
463 void Sanitize_Repository_Name PROTO((char *repository));
464 
465 char *Name_Root PROTO((char *dir, char *update_dir));
466 void free_cvsroot_t PROTO((cvsroot_t *root_in));
467 cvsroot_t *parse_cvsroot PROTO((char *root));
468 cvsroot_t *local_cvsroot PROTO((char *dir));
469 void Create_Root PROTO((char *dir, char *rootdir));
470 void root_allow_add PROTO ((char *));
471 void root_allow_free PROTO ((void));
472 int root_allow_ok PROTO ((char *));
473 
474 char *gca PROTO((const char *rev1, const char *rev2));
475 extern void check_numeric PROTO ((const char *, int, char **));
476 char *getcaller PROTO((void));
477 char *time_stamp PROTO((char *file));
478 
479 void *xmalloc PROTO((size_t bytes));
480 void *xrealloc PROTO((void *ptr, size_t bytes));
481 void expand_string PROTO ((char **, size_t *, size_t));
482 void allocate_and_strcat PROTO ((char **, size_t *, const char *));
483 char *xstrdup PROTO((const char *str));
484 void strip_trailing_newlines PROTO((char *str));
485 int pathname_levels PROTO ((char *path));
486 
487 typedef	int (*CALLPROC)	PROTO((char *repository, char *value));
488 int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
489 extern int parse_config PROTO ((char *));
490 
491 typedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
492 int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
493 int isdir PROTO((const char *file));
494 int isfile PROTO((const char *file));
495 int islink PROTO((const char *file));
496 int isdevice PROTO ((const char *));
497 int isreadable PROTO((const char *file));
498 int iswritable PROTO((const char *file));
499 int isaccessible PROTO((const char *file, const int mode));
500 int isabsolute PROTO((const char *filename));
501 char *xreadlink PROTO((const char *link));
502 char *last_component PROTO((char *path));
503 char *get_homedir PROTO ((void));
504 char *cvs_temp_name PROTO ((void));
505 FILE *cvs_temp_file PROTO ((char **filename));
506 
507 int numdots PROTO((const char *s));
508 char *increment_revnum PROTO ((const char *));
509 int compare_revnums PROTO ((const char *, const char *));
510 int unlink_file PROTO((const char *f));
511 int unlink_file_dir PROTO((const char *f));
512 int update PROTO((int argc, char *argv[]));
513 int xcmp PROTO((const char *file1, const char *file2));
514 int yesno PROTO((void));
515 void *valloc PROTO((size_t bytes));
516 time_t get_date PROTO((char *date, struct timeb *now));
517 extern int Create_Admin PROTO ((char *dir, char *update_dir,
518 				char *repository, char *tag, char *date,
519 				int nonbranch, int warn, int dotemplate));
520 extern int expand_at_signs PROTO ((char *, off_t, FILE *));
521 
522 /* Locking subsystem (implemented in lock.c).  */
523 
524 int Reader_Lock PROTO((char *xrepository));
525 void Lock_Cleanup PROTO((void));
526 
527 /* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
528    and AFLAG, anyway.  */
529 void lock_tree_for_write PROTO ((int argc, char **argv, int local, int which,
530 				 int aflag));
531 
532 /* See lock.c for description.  */
533 extern void lock_dir_for_write PROTO ((char *));
534 
535 /* LockDir setting from CVSROOT/config.  */
536 extern char *lock_dir;
537 
538 void Scratch_Entry PROTO((List * list, char *fname));
539 void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
540 void WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
541 		      char *update_dir, char *repository));
542 void cat_module PROTO((int status));
543 void check_entries PROTO((char *dir));
544 void close_module PROTO((DBM * db));
545 void copy_file PROTO((const char *from, const char *to));
546 void fperrmsg PROTO((FILE * fp, int status, int errnum, char *message,...));
547 void free_names PROTO((int *pargc, char *argv[]));
548 
549 extern int ign_name PROTO ((char *name));
550 void ign_add PROTO((char *ign, int hold));
551 void ign_add_file PROTO((char *file, int hold));
552 void ign_setup PROTO((void));
553 void ign_dir_add PROTO((char *name));
554 int ignore_directory PROTO((char *name));
555 typedef void (*Ignore_proc) PROTO ((char *, char *));
556 extern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
557 extern int ign_inhibit_server;
558 extern int ign_case;
559 
560 #include "update.h"
561 
562 void line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars));
563 void make_directories PROTO((const char *name));
564 void make_directory PROTO((const char *name));
565 extern int mkdir_if_needed PROTO ((char *name));
566 void rename_file PROTO((const char *from, const char *to));
567 /* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
568    files which exist in the current directory, and accordingly to OS-specific
569    conventions regarding wildcard syntax.  It might be desirable to change the
570    former in the future (e.g. "cvs status *.h" including files which don't exist
571    in the working directory).  The result is placed in *PARGC and *PARGV;
572    the *PARGV array itself and all the strings it contains are newly
573    malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
574 extern void expand_wild PROTO ((int argc, char **argv,
575                                 int *pargc, char ***pargv));
576 
577 #ifdef SERVER_SUPPORT
578 extern int cvs_casecmp PROTO ((char *, char *));
579 extern int fopen_case PROTO ((char *, char *, FILE **, char **));
580 #endif
581 
582 void strip_trailing_slashes PROTO((char *path));
583 void update_delproc PROTO((Node * p));
584 void usage PROTO((const char *const *cpp));
585 void xchmod PROTO((char *fname, int writable));
586 char *xgetwd PROTO((void));
587 List *Find_Names PROTO((char *repository, int which, int aflag,
588 		  List ** optentries));
589 void Register PROTO((List * list, char *fname, char *vn, char *ts,
590 	       char *options, char *tag, char *date, char *ts_conflict));
591 void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
592 		     List * xchanges));
593 void do_editor PROTO((char *dir, char **messagep,
594 		      char *repository, List * changes));
595 
596 void do_verify PROTO((char *message, char *repository));
597 
598 typedef	int (*CALLBACKPROC)	PROTO((int argc, char *argv[], char *where,
599 	char *mwhere, char *mfile, int shorten, int local_specified,
600 	char *omodule, char *msg));
601 
602 /* This is the structure that the recursion processor passes to the
603    fileproc to tell it about a particular file.  */
604 struct file_info
605 {
606     /* Name of the file, without any directory component.  */
607     char *file;
608 
609     /* Name of the directory we are in, relative to the directory in
610        which this command was issued.  We have cd'd to this directory
611        (either in the working directory or in the repository, depending
612        on which sort of recursion we are doing).  If we are in the directory
613        in which the command was issued, this is "".  */
614     char *update_dir;
615 
616     /* update_dir and file put together, with a slash between them as
617        necessary.  This is the proper way to refer to the file in user
618        messages.  */
619     char *fullname;
620 
621     /* Name of the directory corresponding to the repository which contains
622        this file.  */
623     char *repository;
624 
625     /* The pre-parsed entries for this directory.  */
626     List *entries;
627 
628     RCSNode *rcs;
629 };
630 
631 typedef	int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
632 typedef	int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
633 				     char *repository, char *update_dir,
634 				     List *entries));
635 typedef	Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
636 				    char *repos, char *update_dir,
637 				    List *entries));
638 typedef	int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
639 				    char *update_dir, List *entries));
640 
641 extern int mkmodules PROTO ((char *dir));
642 extern int init PROTO ((int argc, char **argv));
643 
644 int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
645 		CALLBACKPROC callback_proc, char *where, int shorten,
646 		int local_specified, int run_module_prog, int build_dirs,
647 		char *extra_arg));
648 void history_write PROTO((int type, char *update_dir, char *revs, char *name,
649 		    char *repository));
650 int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
651 		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
652 		     void *callerdat,
653 		     int argc, char *argv[], int local, int which,
654 		     int aflag, int readlock, char *update_preload,
655 		     int dosrcs));
656 void SIG_beginCrSect PROTO((void));
657 void SIG_endCrSect PROTO((void));
658 int SIG_inCrSect PROTO((void));
659 void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
660 
661 char *make_message_rcslegal PROTO((char *message));
662 extern int file_has_markers PROTO ((const struct file_info *));
663 extern void get_file PROTO ((const char *, const char *, const char *,
664 			     char **, size_t *, size_t *));
665 extern char *shell_escape PROTO((char *buf, const char *str));
666 char *backup_file PROTO((const char *file, const char *suffix));
667 extern void resolve_symlink PROTO ((char **filename));
668 void sleep_past PROTO ((time_t desttime));
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_arg PROTO((const char *s));
680 void run_print PROTO((FILE * fp));
681 void run_setup PROTO ((const char *prog));
682 int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
683 		    int flags));
684 
685 /* other similar-minded stuff from run.c.  */
686 FILE *run_popen PROTO((const char *, const char *));
687 int piped_child PROTO((char **, int *, int *));
688 void close_on_exec PROTO((int));
689 
690 pid_t waitpid PROTO((pid_t, int *, int));
691 
692 /*
693  * a struct vers_ts contains all the information about a file including the
694  * user and rcs file names, and the version checked out and the head.
695  *
696  * this is usually obtained from a call to Version_TS which takes a
697  * tag argument for the RCS file if desired
698  */
699 struct vers_ts
700 {
701     /* rcs version user file derives from, from CVS/Entries.
702        It can have the following special values:
703 
704        NULL = file is not mentioned in Entries (this is also used for a
705 	      directory).
706        "" = ILLEGAL!  The comment used to say that it meant "no user file"
707 	    but as far as I know CVS didn't actually use it that way.
708 	    Note that according to cvs.texinfo, "" is not legal in the
709 	    Entries file.
710        0 = user file is new
711        -vers = user file to be removed.  */
712     char *vn_user;
713 
714     /* Numeric revision number corresponding to ->vn_tag (->vn_tag
715        will often be symbolic).  */
716     char *vn_rcs;
717     /* If ->tag is a simple tag in the RCS file--a tag which really
718        exists which is not a magic revision--and if ->date is NULL,
719        then this is a copy of ->tag.  Otherwise, it is a copy of
720        ->vn_rcs.  */
721     char *vn_tag;
722 
723     /* This is the timestamp from stating the file in the working directory.
724        It is NULL if there is no file in the working directory.  It is
725        "Is-modified" if we know the file is modified but don't have its
726        contents.  */
727     char *ts_user;
728     /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
729        are computed in a slightly different way, but the fact remains that
730        if they are equal the file in the working directory is unmodified
731        and if they differ it is modified.  */
732     char *ts_rcs;
733 
734     /* Options from CVS/Entries (keyword expansion), malloc'd.  If none,
735        then it is an empty string (never NULL).  */
736     char *options;
737 
738     /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
739        and the time stamp in this field is the time stamp of the working
740        directory file which was created with the conflict markers in it.
741        This is from CVS/Entries.  */
742     char *ts_conflict;
743 
744     /* Tag specified on the command line, or if none, tag stored in
745        CVS/Entries.  */
746     char *tag;
747     /* Date specified on the command line, or if none, date stored in
748        CVS/Entries.  */
749     char *date;
750     /* If this is 1, then tag is not a branch tag.  If this is 0, then
751        tag may or may not be a branch tag.  */
752     int nonbranch;
753 
754     /* Pointer to entries file node  */
755     Entnode *entdata;
756 
757     /* Pointer to parsed src file info */
758     RCSNode *srcfile;
759 };
760 typedef struct vers_ts Vers_TS;
761 
762 Vers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
763 			    char *date, int force_tag_match,
764 			    int set_time));
765 void freevers_ts PROTO ((Vers_TS ** versp));
766 
767 /* Miscellaneous CVS infrastructure which layers on top of the recursion
768    processor (for example, needs struct file_info).  */
769 
770 int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
771 		    char *tag, char *options, char *message));
772 int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
773 /* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
774 int special_file_mismatch PROTO ((struct file_info *finfo,
775 				  char *rev1, char *rev2));
776 
777 /* CVSADM_BASEREV stuff, from entries.c.  */
778 extern char *base_get PROTO ((struct file_info *));
779 extern void base_register PROTO ((struct file_info *, char *));
780 extern void base_deregister PROTO ((struct file_info *));
781 
782 /*
783  * defines for Classify_File() to determine the current state of a file.
784  * These are also used as types in the data field for the list we make for
785  * Update_Logfile in commit, import, and add.
786  */
787 enum classify_type
788 {
789     T_UNKNOWN = 1,			/* no old-style analog existed	 */
790     T_CONFLICT,				/* C (conflict) list		 */
791     T_NEEDS_MERGE,			/* G (needs merging) list	 */
792     T_MODIFIED,				/* M (needs checked in) list 	 */
793     T_CHECKOUT,				/* O (needs checkout) list	 */
794     T_ADDED,				/* A (added file) list		 */
795     T_REMOVED,				/* R (removed file) list	 */
796     T_REMOVE_ENTRY,			/* W (removed entry) list	 */
797     T_UPTODATE,				/* File is up-to-date		 */
798     T_PATCH,				/* P Like C, but can patch	 */
799     T_TITLE				/* title for node type 		 */
800 };
801 typedef enum classify_type Ctype;
802 
803 Ctype Classify_File PROTO
804     ((struct file_info *finfo, char *tag, char *date, char *options,
805       int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
806 
807 /*
808  * structure used for list nodes passed to Update_Logfile() and
809  * do_editor().
810  */
811 struct logfile_info
812 {
813   enum classify_type type;
814   char *tag;
815   char *rev_old;		/* rev number before a commit/modify,
816 				   NULL for add or import */
817   char *rev_new;		/* rev number after a commit/modify,
818 				   add, or import, NULL for remove */
819 };
820 
821 /* Wrappers.  */
822 
823 typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
824 typedef enum {
825     /* -t and -f wrapper options.  Treating directories as single files.  */
826     WRAP_TOCVS,
827     WRAP_FROMCVS,
828     /* -k wrapper option.  Default keyword expansion options.  */
829     WRAP_RCSOPTION
830 } WrapMergeHas;
831 
832 void  wrap_setup PROTO((void));
833 int   wrap_name_has PROTO((const char *name,WrapMergeHas has));
834 char *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
835 char *wrap_tocvs_process_file PROTO((const char *fileName));
836 int   wrap_merge_is_copy PROTO((const char *fileName));
837 void wrap_fromcvs_process_file PROTO ((const char *fileName));
838 void wrap_add_file PROTO((const char *file,int temp));
839 void wrap_add PROTO((char *line,int temp));
840 void wrap_send PROTO ((void));
841 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
842 void wrap_unparse_rcs_options PROTO ((char **, int));
843 #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
844 
845 /* Pathname expansion */
846 char *expand_path PROTO((char *name, char *file, int line));
847 
848 /* User variables.  */
849 extern List *variable_list;
850 
851 extern void variable_set PROTO ((char *nameval));
852 
853 int watch PROTO ((int argc, char **argv));
854 int edit PROTO ((int argc, char **argv));
855 int unedit PROTO ((int argc, char **argv));
856 int editors PROTO ((int argc, char **argv));
857 int watchers PROTO ((int argc, char **argv));
858 extern int annotate PROTO ((int argc, char **argv));
859 extern int add PROTO ((int argc, char **argv));
860 extern int admin PROTO ((int argc, char **argv));
861 extern int checkout PROTO ((int argc, char **argv));
862 extern int commit PROTO ((int argc, char **argv));
863 extern int diff PROTO ((int argc, char **argv));
864 extern int history PROTO ((int argc, char **argv));
865 extern int import PROTO ((int argc, char **argv));
866 extern int cvslog PROTO ((int argc, char **argv));
867 #ifdef AUTH_CLIENT_SUPPORT
868 extern int login PROTO((int argc, char **argv));
869 int logout PROTO((int argc, char **argv));
870 #endif /* AUTH_CLIENT_SUPPORT */
871 extern int patch PROTO((int argc, char **argv));
872 extern int release PROTO((int argc, char **argv));
873 extern int cvsremove PROTO((int argc, char **argv));
874 extern int rtag PROTO((int argc, char **argv));
875 extern int cvsstatus PROTO((int argc, char **argv));
876 extern int cvstag PROTO((int argc, char **argv));
877 extern int version PROTO((int argc, char **argv));
878 
879 extern unsigned long int lookup_command_attribute PROTO((char *));
880 
881 #if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
882 char *scramble PROTO ((char *str));
883 char *descramble PROTO ((char *str));
884 #endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
885 
886 #ifdef AUTH_CLIENT_SUPPORT
887 char *get_cvs_password PROTO((void));
888 int get_cvs_port_number PROTO((const cvsroot_t *root));
889 char *normalize_cvsroot PROTO((const cvsroot_t *root));
890 #endif /* AUTH_CLIENT_SUPPORT */
891 
892 extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
893 extern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
894 					 char *));
895 
896 #include "server.h"
897 
898 /* From server.c and documented there.  */
899 extern void cvs_output PROTO ((const char *, size_t));
900 extern void cvs_output_binary PROTO ((char *, size_t));
901 extern void cvs_outerr PROTO ((const char *, size_t));
902 extern void cvs_flusherr PROTO ((void));
903 extern void cvs_flushout PROTO ((void));
904 extern void cvs_output_tagged PROTO ((char *, char *));
905