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