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