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