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