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