cvs.h revision 36418
18871Srgrimes/*
21558Srgrimes * Copyright (c) 1992, Brian Berliner and Jeff Polk
31558Srgrimes * Copyright (c) 1989-1992, Brian Berliner
41558Srgrimes *
51558Srgrimes * You may distribute under the terms of the GNU General Public License as
61558Srgrimes * specified in the README file that comes with the CVS kit.
71558Srgrimes */
81558Srgrimes
91558Srgrimes/*
101558Srgrimes * basic information used in all source files
111558Srgrimes *
121558Srgrimes */
131558Srgrimes
141558Srgrimes
151558Srgrimes#include "config.h"		/* this is stuff found via autoconf */
161558Srgrimes#include "options.h"		/* these are some larger questions which
171558Srgrimes				   can't easily be automatically checked
181558Srgrimes				   for */
191558Srgrimes
201558Srgrimes/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
211558Srgrimes
221558Srgrimes#ifdef __STDC__
231558Srgrimes#define	PTR	void *
241558Srgrimes#else
251558Srgrimes#define	PTR	char *
261558Srgrimes#endif
271558Srgrimes
281558Srgrimes/* Add prototype support.  */
291558Srgrimes#ifndef PROTO
301558Srgrimes#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
311558Srgrimes#define PROTO(ARGS) ARGS
321558Srgrimes#else
331558Srgrimes#define PROTO(ARGS) ()
341558Srgrimes#endif
357585Sbde#endif
361558Srgrimes
371558Srgrimes#include <stdio.h>
381558Srgrimes
391558Srgrimes/* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
401558Srgrimes#ifdef USE_OWN_POPEN
411558Srgrimes#include "popen.h"
421558Srgrimes#endif
437585Sbde
441558Srgrimes#ifdef STDC_HEADERS
451558Srgrimes#include <stdlib.h>
461558Srgrimes#else
471558Srgrimesextern void exit ();
481558Srgrimesextern char *getenv();
491558Srgrimes#endif
501558Srgrimes
517585Sbde#ifdef HAVE_UNISTD_H
527585Sbde#include <unistd.h>
537585Sbde#endif
541558Srgrimes
551558Srgrimes#ifdef HAVE_STRING_H
561558Srgrimes#include <string.h>
571558Srgrimes#else
581558Srgrimes#include <strings.h>
591558Srgrimes#endif
601558Srgrimes
611558Srgrimes#ifdef SERVER_SUPPORT
621558Srgrimes/* If the system doesn't provide strerror, it won't be declared in
631558Srgrimes   string.h.  */
641558Srgrimeschar *strerror ();
651558Srgrimes#endif
661558Srgrimes
671558Srgrimes#include <fnmatch.h> /* This is supposed to be available on Posix systems */
681558Srgrimes
691558Srgrimes#include <ctype.h>
701558Srgrimes#include <pwd.h>
711558Srgrimes#include <signal.h>
721558Srgrimes
731558Srgrimes#ifdef HAVE_ERRNO_H
741558Srgrimes#include <errno.h>
751558Srgrimes#else
761558Srgrimes#ifndef errno
771558Srgrimesextern int errno;
781558Srgrimes#endif /* !errno */
791558Srgrimes#endif /* HAVE_ERRNO_H */
801558Srgrimes
811558Srgrimes#include "system.h"
821558Srgrimes
831558Srgrimes#include "hash.h"
841558Srgrimes#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
851558Srgrimes#include "client.h"
861558Srgrimes#endif
871558Srgrimes
881558Srgrimes#ifdef MY_NDBM
891558Srgrimes#include "myndbm.h"
901558Srgrimes#else
911558Srgrimes#include <ndbm.h>
927585Sbde#endif /* MY_NDBM */
931558Srgrimes
941558Srgrimes#include "regex.h"
951558Srgrimes#include "getopt.h"
961558Srgrimes#include "wait.h"
971558Srgrimes
981558Srgrimes#include "rcs.h"
991558Srgrimes
1001558Srgrimes
1012603Sdg/* This actually gets set in system.h.  Note that the _ONLY_ reason for
1021558Srgrimes   this is if various system calls (getwd, getcwd, readlink) require/want
1031558Srgrimes   us to use it.  All other parts of CVS allocate pathname buffers
1041558Srgrimes   dynamically, and we want to keep it that way.  */
1051558Srgrimes#ifndef PATH_MAX
1061558Srgrimes#ifdef MAXPATHLEN
1071558Srgrimes#define	PATH_MAX MAXPATHLEN+2
1081558Srgrimes#else
1091558Srgrimes#define	PATH_MAX 1024+2
1101558Srgrimes#endif
1111558Srgrimes#endif /* PATH_MAX */
1121558Srgrimes
1131558Srgrimes/* Definitions for the CVS Administrative directory and the files it contains.
1141558Srgrimes   Here as #define's to make changing the names a simple task.  */
1151558Srgrimes
1161558Srgrimes#ifdef USE_VMS_FILENAMES
1171558Srgrimes#define CVSADM          "CVS"
1181558Srgrimes#define CVSADM_ENT      "CVS/Entries."
1191558Srgrimes#define CVSADM_ENTBAK   "CVS/Entries.Backup"
1201558Srgrimes#define CVSADM_ENTLOG   "CVS/Entries.Log"
1211558Srgrimes#define CVSADM_ENTSTAT  "CVS/Entries.Static"
1221558Srgrimes#define CVSADM_REP      "CVS/Repository."
1231558Srgrimes#define CVSADM_ROOT     "CVS/Root."
1241558Srgrimes#define CVSADM_CIPROG   "CVS/Checkin.prog"
1251558Srgrimes#define CVSADM_UPROG    "CVS/Update.prog"
1261558Srgrimes#define CVSADM_TAG      "CVS/Tag."
1271558Srgrimes#define CVSADM_NOTIFY   "CVS/Notify."
1281558Srgrimes#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
1291558Srgrimes#define CVSADM_BASE      "CVS/Base"
1301558Srgrimes#define CVSADM_BASEREV   "CVS/Baserev."
1311558Srgrimes#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
1321558Srgrimes#define CVSADM_TEMPLATE "CVS/Template."
1331558Srgrimes#else /* USE_VMS_FILENAMES */
1341558Srgrimes#define	CVSADM		"CVS"
1351558Srgrimes#define	CVSADM_ENT	"CVS/Entries"
1361558Srgrimes#define	CVSADM_ENTBAK	"CVS/Entries.Backup"
1371558Srgrimes#define CVSADM_ENTLOG	"CVS/Entries.Log"
1381558Srgrimes#define	CVSADM_ENTSTAT	"CVS/Entries.Static"
1391558Srgrimes#define	CVSADM_REP	"CVS/Repository"
1401558Srgrimes#define	CVSADM_ROOT	"CVS/Root"
1411558Srgrimes#define	CVSADM_CIPROG	"CVS/Checkin.prog"
1421558Srgrimes#define	CVSADM_UPROG	"CVS/Update.prog"
1431558Srgrimes#define	CVSADM_TAG	"CVS/Tag"
1441558Srgrimes#define CVSADM_NOTIFY	"CVS/Notify"
1451558Srgrimes#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
1461558Srgrimes/* A directory in which we store base versions of files we currently are
1472603Sdg   editing with "cvs edit".  */
1481558Srgrimes#define CVSADM_BASE     "CVS/Base"
1491558Srgrimes#define CVSADM_BASEREV  "CVS/Baserev"
1502603Sdg#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
1511558Srgrimes/* File which contains the template for use in log messages.  */
1521558Srgrimes#define CVSADM_TEMPLATE "CVS/Template"
1531558Srgrimes#endif /* USE_VMS_FILENAMES */
1547585Sbde
1551558Srgrimes/* This is the special directory which we use to store various extra
1561558Srgrimes   per-directory information in the repository.  It must be the same as
1571558Srgrimes   CVSADM to avoid creating a new reserved directory name which users cannot
1581558Srgrimes   use, but is a separate #define because if anyone changes it (which I don't
1591558Srgrimes   recommend), one needs to deal with old, unconverted, repositories.
1601558Srgrimes
1611558Srgrimes   See fileattr.h for details about file attributes, the only thing stored
1621558Srgrimes   in CVSREP currently.  */
1631558Srgrimes#define CVSREP "CVS"
1641558Srgrimes
1651558Srgrimes/*
1661558Srgrimes * Definitions for the CVSROOT Administrative directory and the files it
1671820Sdg * contains.  This directory is created as a sub-directory of the $CVSROOT
1681558Srgrimes * environment variable, and holds global administration information for the
1691558Srgrimes * entire source repository beginning at $CVSROOT.
1701558Srgrimes */
1711558Srgrimes#define	CVSROOTADM		"CVSROOT"
1721558Srgrimes#define	CVSROOTADM_MODULES	"modules"
1731558Srgrimes#define	CVSROOTADM_LOGINFO	"loginfo"
1741558Srgrimes#define	CVSROOTADM_RCSINFO	"rcsinfo"
1751558Srgrimes#define CVSROOTADM_COMMITINFO	"commitinfo"
1761558Srgrimes#define CVSROOTADM_TAGINFO      "taginfo"
1771558Srgrimes#define	CVSROOTADM_EDITINFO	"editinfo"
1781558Srgrimes#define CVSROOTADM_VERIFYMSG    "verifymsg"
1791558Srgrimes#define	CVSROOTADM_HISTORY	"history"
1801558Srgrimes#define CVSROOTADM_VALTAGS	"val-tags"
1811558Srgrimes#define	CVSROOTADM_IGNORE	"cvsignore"
1821558Srgrimes#define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
1831558Srgrimes#define CVSROOTADM_WRAPPER	"cvswrappers"
1841558Srgrimes#define CVSROOTADM_NOTIFY	"notify"
1851558Srgrimes#define CVSROOTADM_USERS	"users"
1861558Srgrimes#define CVSROOTADM_READERS	"readers"
1871558Srgrimes#define CVSROOTADM_WRITERS	"writers"
1881558Srgrimes#define CVSROOTADM_PASSWD	"passwd"
1891558Srgrimes#define CVSROOTADM_CONFIG	"config"
1901558Srgrimes#define CVSROOTADM_OPTIONS	"options"
1911558Srgrimes
1921558Srgrimes#define CVSNULLREPOS		"Emptydir"	/* an empty directory */
1931558Srgrimes
1941558Srgrimes/* Other CVS file names */
1951558Srgrimes
1961558Srgrimes/* Files go in the attic if the head main branch revision is dead,
1971558Srgrimes   otherwise they go in the regular repository directories.  The whole
1981558Srgrimes   concept of having an attic is sort of a relic from before death
1991558Srgrimes   support but on the other hand, it probably does help the speed of
2001558Srgrimes   some operations (such as main branch checkouts and updates).  */
2011558Srgrimes#define	CVSATTIC	"Attic"
2021558Srgrimes
2031558Srgrimes#define	CVSLCK		"#cvs.lock"
2041558Srgrimes#define	CVSRFL		"#cvs.rfl"
2051558Srgrimes#define	CVSWFL		"#cvs.wfl"
2061558Srgrimes#define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
2071558Srgrimes#define	CVSEXT_LOG	",t"
2081558Srgrimes#define	CVSPREFIX	",,"
2091558Srgrimes#define CVSDOTIGNORE	".cvsignore"
2101558Srgrimes#define CVSDOTWRAPPER   ".cvswrappers"
2111558Srgrimes
2121558Srgrimes/* Command attributes -- see function lookup_command_attribute(). */
2131558Srgrimes#define CVS_CMD_IGNORE_ADMROOT        1
2141558Srgrimes
2151558Srgrimes/* Set if CVS needs to create a CVS/Root file upon completion of this
2161558Srgrimes   command.  The name may be slightly confusing, because the flag
2171558Srgrimes   isn't really as general purpose as it seems (it is not set for cvs
2181558Srgrimes   release).  */
2191558Srgrimes
2201558Srgrimes#define CVS_CMD_USES_WORK_DIR         2
2211558Srgrimes
2221558Srgrimes#define CVS_CMD_MODIFIES_REPOSITORY   4
2231558Srgrimes
2241558Srgrimes/* miscellaneous CVS defines */
2251558Srgrimes
2261558Srgrimes/* This is the string which is at the start of the non-log-message lines
2271558Srgrimes   that we put up for the user when they edit the log message.  */
2281558Srgrimes#define	CVSEDITPREFIX	"CVS: "
2291558Srgrimes/* Number of characters in CVSEDITPREFIX to compare when deciding to strip
2301558Srgrimes   off those lines.  We don't check for the space, to accomodate users who
2311558Srgrimes   have editors which strip trailing spaces.  */
2321558Srgrimes#define CVSEDITPREFIXLEN 4
2331558Srgrimes
2341558Srgrimes#define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
2351558Srgrimes#define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
2361558Srgrimes#define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
2371558Srgrimes
2381558Srgrimes#ifdef USE_VMS_FILENAMES
2391558Srgrimes#define BAKPREFIX       "_$"
2401558Srgrimes#define DEVNULL         "NLA0:"
2411558Srgrimes#else /* USE_VMS_FILENAMES */
2421558Srgrimes#define	BAKPREFIX	".#"		/* when rcsmerge'ing */
2431558Srgrimes#ifndef DEVNULL
2441558Srgrimes#define	DEVNULL		"/dev/null"
2451558Srgrimes#endif
2461558Srgrimes#endif /* USE_VMS_FILENAMES */
2471558Srgrimes
2481558Srgrimes/*
2491558Srgrimes * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
2501558Srgrimes * sticky tags. -rBASE	refers to the current revision the user has checked
2511558Srgrimes * out This mimics the behaviour of RCS.
2521558Srgrimes */
2537585Sbde#define	TAG_HEAD	"HEAD"
2541558Srgrimes#define	TAG_BASE	"BASE"
2551558Srgrimes
2561558Srgrimes/* Environment variable used by CVS */
2571558Srgrimes#define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
2581558Srgrimes#define	CVSREAD_DFLT	0		/* writable files by default */
2591558Srgrimes
2601558Srgrimes#define	CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
2611558Srgrimes
2621558Srgrimes#define	TMPDIR_ENV	"TMPDIR"	/* Temporary directory */
2631558Srgrimes/* #define	TMPDIR_DFLT		   Set by options.h */
2641558Srgrimes
2651558Srgrimes#define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
2661558Srgrimes#define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
2671558Srgrimes#define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
2681558Srgrimes/* #define	EDITOR_DFLT		   Set by options.h */
2691558Srgrimes
2701558Srgrimes#define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
2711558Srgrimes#define	CVSROOT_DFLT	NULL		/* No dflt; must set for checkout */
2721558Srgrimes
2731558Srgrimes#define	IGNORE_ENV	"CVSIGNORE"	/* More files to ignore */
2741558Srgrimes#define WRAPPER_ENV     "CVSWRAPPERS"   /* name of the wrapper file */
2751558Srgrimes
2761558Srgrimes#define	CVSUMASK_ENV	"CVSUMASK"	/* Effective umask for repository */
2771558Srgrimes/* #define	CVSUMASK_DFLT		   Set by options.h */
2781558Srgrimes
2791558Srgrimes/*
2801558Srgrimes * If the beginning of the Repository matches the following string, strip it
2811558Srgrimes * so that the output to the logfile does not contain a full pathname.
2821558Srgrimes *
2831558Srgrimes * If the CVSROOT environment variable is set, it overrides this define.
2841558Srgrimes */
2851558Srgrimes#define	REPOS_STRIP	"/master/"
2861558Srgrimes
2871558Srgrimes/* Large enough to hold DATEFORM.  Not an arbitrary limit as long as
2881558Srgrimes   it is used for that purpose, and not to hold a string from the
2891558Srgrimes   command line, the client, etc.  */
2901558Srgrimes#define MAXDATELEN	50
2911558Srgrimes
2921558Srgrimes/* The type of an entnode.  */
2931558Srgrimesenum ent_type
2941558Srgrimes{
2951558Srgrimes    ENT_FILE, ENT_SUBDIR
2961558Srgrimes};
2971558Srgrimes
2981558Srgrimes/* structure of a entry record */
2991558Srgrimesstruct entnode
3001558Srgrimes{
3011558Srgrimes    enum ent_type type;
3021558Srgrimes    char *user;
3031558Srgrimes    char *version;
3041558Srgrimes
3051558Srgrimes    /* Timestamp, or "" if none (never NULL).  */
3061558Srgrimes    char *timestamp;
3071558Srgrimes
3081558Srgrimes    /* Keyword expansion options, or "" if none (never NULL).  */
3091558Srgrimes    char *options;
3101558Srgrimes
3111558Srgrimes    char *tag;
3121558Srgrimes    char *date;
3131558Srgrimes    char *conflict;
3141558Srgrimes};
3151558Srgrimestypedef struct entnode Entnode;
3161558Srgrimes
3171558Srgrimes/* The type of request that is being done in do_module() */
3181558Srgrimesenum mtype
3191558Srgrimes{
320    CHECKOUT, TAG, PATCH, EXPORT
321};
322
323/*
324 * structure used for list-private storage by Entries_Open() and
325 * Version_TS() and Find_Directories().
326 */
327struct stickydirtag
328{
329    /* These fields pass sticky tag information from Entries_Open() to
330       Version_TS().  */
331    int aflag;
332    char *tag;
333    char *date;
334    int nonbranch;
335
336    /* This field is set by Entries_Open() if there was subdirectory
337       information; Find_Directories() uses it to see whether it needs
338       to scan the directory itself.  */
339    int subdirs;
340};
341
342/* Flags for find_{names,dirs} routines */
343#define W_LOCAL			0x01	/* look for files locally */
344#define W_REPOS			0x02	/* look for files in the repository */
345#define W_ATTIC			0x04	/* look for files in the attic */
346
347/* Flags for return values of direnter procs for the recursion processor */
348enum direnter_type
349{
350    R_PROCESS = 1,			/* process files and maybe dirs */
351    R_SKIP_FILES,			/* don't process files in this dir */
352    R_SKIP_DIRS,			/* don't process sub-dirs */
353    R_SKIP_ALL				/* don't process files or dirs */
354};
355#ifdef ENUMS_CAN_BE_TROUBLE
356typedef int Dtype;
357#else
358typedef enum direnter_type Dtype;
359#endif
360
361extern char *program_name, *program_path, *command_name;
362extern char *Tmpdir, *Editor;
363extern int cvsadmin_root;
364extern char *CurDir;
365extern int really_quiet, quiet;
366extern int use_editor;
367extern int cvswrite;
368extern mode_t cvsumask;
369extern char *RCS_citag;
370
371/* Access method specified in CVSroot. */
372typedef enum {
373  local_method, server_method, pserver_method, kserver_method, gserver_method,
374  ext_method
375} CVSmethod;
376extern char *method_names[];	/* change this in root.c if you change
377				   the enum above */
378
379extern char *CVSroot_original;	/* the active, complete CVSroot string */
380extern int client_active;	/* nonzero if we are doing remote access */
381extern CVSmethod CVSroot_method; /* one of the enum values above */
382extern char *CVSroot_username;	/* the username or NULL if method == local */
383extern char *CVSroot_hostname;	/* the hostname or NULL if method == local */
384extern char *CVSroot_directory;	/* the directory name */
385
386extern char *emptydir_name PROTO ((void));
387
388extern int trace;		/* Show all commands */
389extern int noexec;		/* Don't modify disk anywhere */
390extern int readonlyfs;		/* fail on all write locks; succeed all read locks */
391extern int logoff;		/* Don't write history entry */
392extern int require_real_user;	/* skip CVSROOT/passwd, /etc/passwd users only*/
393
394#ifdef AUTH_SERVER_SUPPORT
395extern char *Pserver_Repos;     /* used to check that same repos is
396                                   transmitted in pserver auth and in
397                                   CVS protocol. */
398#endif /* AUTH_SERVER_SUPPORT */
399
400extern char hostname[];
401
402/* Externs that are included directly in the CVS sources */
403
404int RCS_merge PROTO((RCSNode *, char *, char *, char *, char *, char *));
405/* Flags used by RCS_* functions.  See the description of the individual
406   functions for which flags mean what for each function.  */
407#define RCS_FLAGS_FORCE 1
408#define RCS_FLAGS_DEAD 2
409#define RCS_FLAGS_QUIET 4
410#define RCS_FLAGS_MODTIME 8
411#define RCS_FLAGS_KEEPFILE 16
412
413extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
414				    char *opts, char *options,
415				    char *rev1, char *rev2,
416				    char *label1, char *label2,
417				    char *workfile));
418extern int diff_exec PROTO ((char *file1, char *file2, char *options,
419			     char *out));
420extern int diff_execv PROTO ((char *file1, char *file2,
421			      char *label1, char *label2,
422			      char *options, char *out));
423
424
425
426#include "error.h"
427
428DBM *open_module PROTO((void));
429FILE *open_file PROTO((const char *, const char *));
430List *Find_Directories PROTO((char *repository, int which, List *entries));
431void Entries_Close PROTO((List *entries));
432List *Entries_Open PROTO ((int aflag, char *update_dir));
433void Subdirs_Known PROTO((List *entries));
434void Subdir_Register PROTO((List *, const char *, const char *));
435void Subdir_Deregister PROTO((List *, const char *, const char *));
436
437char *Make_Date PROTO((char *rawdate));
438char *Name_Repository PROTO((char *dir, char *update_dir));
439char *Short_Repository PROTO((char *repository));
440void Sanitize_Repository_Name PROTO((char *repository));
441
442char *Name_Root PROTO((char *dir, char *update_dir));
443int parse_cvsroot PROTO((char *CVSroot));
444void set_local_cvsroot PROTO((char *dir));
445void Create_Root PROTO((char *dir, char *rootdir));
446void root_allow_add PROTO ((char *));
447void root_allow_free PROTO ((void));
448int root_allow_ok PROTO ((char *));
449
450char *gca PROTO((const char *rev1, const char *rev2));
451extern void check_numeric PROTO ((const char *, int, char **));
452char *getcaller PROTO((void));
453char *time_stamp PROTO((char *file));
454
455char *xmalloc PROTO((size_t bytes));
456void *xrealloc PROTO((void *ptr, size_t bytes));
457void expand_string PROTO ((char **, size_t *, size_t));
458char *xstrdup PROTO((const char *str));
459void strip_trailing_newlines PROTO((char *str));
460int pathname_levels PROTO ((char *path));
461
462typedef	int (*CALLPROC)	PROTO((char *repository, char *value));
463int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
464extern int parse_config PROTO ((char *));
465
466typedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
467int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
468int isdir PROTO((const char *file));
469int isfile PROTO((const char *file));
470int islink PROTO((const char *file));
471int isdevice PROTO ((const char *));
472int isreadable PROTO((const char *file));
473int iswritable PROTO((const char *file));
474int isaccessible PROTO((const char *file, const int mode));
475int isabsolute PROTO((const char *filename));
476char *xreadlink PROTO((const char *link));
477char *last_component PROTO((char *path));
478char *get_homedir PROTO ((void));
479char *cvs_temp_name PROTO ((void));
480void parseopts PROTO ((const char *root));
481
482int numdots PROTO((const char *s));
483char *increment_revnum PROTO ((const char *));
484int compare_revnums PROTO ((const char *, const char *));
485int unlink_file PROTO((const char *f));
486int link_file PROTO ((const char *from, const char *to));
487int unlink_file_dir PROTO((const char *f));
488int update PROTO((int argc, char *argv[]));
489int xcmp PROTO((const char *file1, const char *file2));
490int yesno PROTO((void));
491void *valloc PROTO((size_t bytes));
492time_t get_date PROTO((char *date, struct timeb *now));
493extern int Create_Admin PROTO ((char *dir, char *update_dir,
494				char *repository, char *tag, char *date,
495				int nonbranch, int warn));
496extern int expand_at_signs PROTO ((char *, off_t, FILE *));
497
498/* Locking subsystem (implemented in lock.c).  */
499
500int Reader_Lock PROTO((char *xrepository));
501void Lock_Cleanup PROTO((void));
502
503/* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
504   and AFLAG, anyway.  */
505void lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag));
506
507/* See lock.c for description.  */
508extern void lock_dir_for_write PROTO ((char *));
509
510void Scratch_Entry PROTO((List * list, char *fname));
511void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
512void WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
513		      char *update_dir, char *repository));
514void cat_module PROTO((int status));
515void check_entries PROTO((char *dir));
516void close_module PROTO((DBM * db));
517void copy_file PROTO((const char *from, const char *to));
518void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
519void free_names PROTO((int *pargc, char *argv[]));
520
521extern int ign_name PROTO ((char *name));
522void ign_add PROTO((char *ign, int hold));
523void ign_add_file PROTO((char *file, int hold));
524void ign_setup PROTO((void));
525void ign_dir_add PROTO((char *name));
526int ignore_directory PROTO((char *name));
527typedef void (*Ignore_proc) PROTO ((char *, char *));
528extern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
529extern int ign_inhibit_server;
530extern int ign_case;
531
532#include "update.h"
533
534void line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars));
535void make_directories PROTO((const char *name));
536void make_directory PROTO((const char *name));
537extern int mkdir_if_needed PROTO ((char *name));
538void rename_file PROTO((const char *from, const char *to));
539/* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
540   files which exist in the current directory, and accordingly to OS-specific
541   conventions regarding wildcard syntax.  It might be desirable to change the
542   former in the future (e.g. "cvs status *.h" including files which don't exist
543   in the working directory).  The result is placed in *PARGC and *PARGV;
544   the *PARGV array itself and all the strings it contains are newly
545   malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
546extern void expand_wild PROTO ((int argc, char **argv,
547                                int *pargc, char ***pargv));
548
549#ifdef SERVER_SUPPORT
550extern int cvs_casecmp PROTO ((char *, char *));
551extern int fopen_case PROTO ((char *, char *, FILE **, char **));
552#endif
553
554void strip_trailing_slashes PROTO((char *path));
555void update_delproc PROTO((Node * p));
556void usage PROTO((const char *const *cpp));
557void xchmod PROTO((char *fname, int writable));
558char *xgetwd PROTO((void));
559List *Find_Names PROTO((char *repository, int which, int aflag,
560		  List ** optentries));
561void Register PROTO((List * list, char *fname, char *vn, char *ts,
562	       char *options, char *tag, char *date, char *ts_conflict));
563void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
564		     List * xchanges));
565void do_editor PROTO((char *dir, char **messagep,
566		      char *repository, List * changes));
567
568void do_verify PROTO((char **messagep, char *repository));
569
570typedef	int (*CALLBACKPROC)	PROTO((int *pargc, char *argv[], char *where,
571	char *mwhere, char *mfile, int shorten, int local_specified,
572	char *omodule, char *msg));
573
574/* This is the structure that the recursion processor passes to the
575   fileproc to tell it about a particular file.  */
576struct file_info
577{
578    /* Name of the file, without any directory component.  */
579    char *file;
580
581    /* Name of the directory we are in, relative to the directory in
582       which this command was issued.  We have cd'd to this directory
583       (either in the working directory or in the repository, depending
584       on which sort of recursion we are doing).  If we are in the directory
585       in which the command was issued, this is "".  */
586    char *update_dir;
587
588    /* update_dir and file put together, with a slash between them as
589       necessary.  This is the proper way to refer to the file in user
590       messages.  */
591    char *fullname;
592
593    /* Name of the directory corresponding to the repository which contains
594       this file.  */
595    char *repository;
596
597    /* The pre-parsed entries for this directory.  */
598    List *entries;
599
600    RCSNode *rcs;
601};
602
603typedef	int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
604typedef	int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
605				     char *repository, char *update_dir,
606				     List *entries));
607typedef	Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
608				    char *repos, char *update_dir,
609				    List *entries));
610typedef	int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
611				    char *update_dir, List *entries));
612
613extern int mkmodules PROTO ((char *dir));
614extern int init PROTO ((int argc, char **argv));
615
616int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
617		CALLBACKPROC callback_proc, char *where, int shorten,
618		int local_specified, int run_module_prog, char *extra_arg));
619void history_write PROTO((int type, char *update_dir, char *revs, char *name,
620		    char *repository));
621int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
622		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
623		     void *callerdat,
624		     int argc, char *argv[], int local, int which,
625		     int aflag, int readlock, char *update_preload,
626		     int dosrcs));
627void SIG_beginCrSect PROTO((void));
628void SIG_endCrSect PROTO((void));
629void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
630
631char *make_message_rcslegal PROTO((char *message));
632extern int file_has_markers PROTO ((const struct file_info *));
633extern void get_file PROTO ((const char *, const char *, const char *,
634			     char **, size_t *, size_t *));
635
636/* flags for run_exec(), the fast system() for CVS */
637#define	RUN_NORMAL		0x0000	/* no special behaviour */
638#define	RUN_COMBINED		0x0001	/* stdout is duped to stderr */
639#define	RUN_REALLY		0x0002	/* do the exec, even if noexec is on */
640#define	RUN_STDOUT_APPEND	0x0004	/* append to stdout, don't truncate */
641#define	RUN_STDERR_APPEND	0x0008	/* append to stderr, don't truncate */
642#define	RUN_SIGIGNORE		0x0010	/* ignore interrupts for command */
643#define	RUN_TTY		(char *)0	/* for the benefit of lint */
644
645void run_arg PROTO((const char *s));
646void run_print PROTO((FILE * fp));
647void run_setup PROTO ((const char *prog));
648int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
649		    int flags));
650
651/* other similar-minded stuff from run.c.  */
652FILE *run_popen PROTO((const char *, const char *));
653int piped_child PROTO((char **, int *, int *));
654void close_on_exec PROTO((int));
655int filter_stream_through_program PROTO((int, int, char **, pid_t *));
656
657pid_t waitpid PROTO((pid_t, int *, int));
658
659/*
660 * a struct vers_ts contains all the information about a file including the
661 * user and rcs file names, and the version checked out and the head.
662 *
663 * this is usually obtained from a call to Version_TS which takes a
664 * tag argument for the RCS file if desired
665 */
666struct vers_ts
667{
668    /* rcs version user file derives from, from CVS/Entries.
669       It can have the following special values:
670
671       NULL = file is not mentioned in Entries (this is also used for a
672	      directory).
673       "" = ILLEGAL!  The comment used to say that it meant "no user file"
674	    but as far as I know CVS didn't actually use it that way.
675	    Note that according to cvs.texinfo, "" is not legal in the
676	    Entries file.
677       0 = user file is new
678       -vers = user file to be removed.  */
679    char *vn_user;
680
681    /* Numeric revision number corresponding to ->vn_tag (->vn_tag
682       will often be symbolic).  */
683    char *vn_rcs;
684    /* If ->tag is a simple tag in the RCS file--a tag which really
685       exists which is not a magic revision--and if ->date is NULL,
686       then this is a copy of ->tag.  Otherwise, it is a copy of
687       ->vn_rcs.  */
688    char *vn_tag;
689
690    /* This is the timestamp from stating the file in the working directory.
691       It is NULL if there is no file in the working directory.  It is
692       "Is-modified" if we know the file is modified but don't have its
693       contents.  */
694    char *ts_user;
695    /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
696       are computed in a slightly different way, but the fact remains that
697       if they are equal the file in the working directory is unmodified
698       and if they differ it is modified.  */
699    char *ts_rcs;
700
701    /* Options from CVS/Entries (keyword expansion), malloc'd.  If none,
702       then it is an empty string (never NULL).  */
703    char *options;
704
705    /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
706       and the time stamp in this field is the time stamp of the working
707       directory file which was created with the conflict markers in it.
708       This is from CVS/Entries.  */
709    char *ts_conflict;
710
711    /* Tag specified on the command line, or if none, tag stored in
712       CVS/Entries.  */
713    char *tag;
714    /* Date specified on the command line, or if none, date stored in
715       CVS/Entries.  */
716    char *date;
717    /* If this is 1, then tag is not a branch tag.  If this is 0, then
718       tag may or may not be a branch tag.  */
719    int nonbranch;
720
721    /* Pointer to entries file node  */
722    Entnode *entdata;
723
724    /* Pointer to parsed src file info */
725    RCSNode *srcfile;
726};
727typedef struct vers_ts Vers_TS;
728
729Vers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
730			    char *date, int force_tag_match,
731			    int set_time));
732void freevers_ts PROTO ((Vers_TS ** versp));
733
734/* Miscellaneous CVS infrastructure which layers on top of the recursion
735   processor (for example, needs struct file_info).  */
736
737int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
738		    char *tag, char *options, char *message));
739int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
740/* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
741int special_file_mismatch PROTO ((struct file_info *finfo,
742				  char *rev1, char *rev2));
743
744/* CVSADM_BASEREV stuff, from entries.c.  */
745extern char *base_get PROTO ((struct file_info *));
746extern void base_register PROTO ((struct file_info *, char *));
747extern void base_deregister PROTO ((struct file_info *));
748
749/*
750 * defines for Classify_File() to determine the current state of a file.
751 * These are also used as types in the data field for the list we make for
752 * Update_Logfile in commit, import, and add.
753 */
754enum classify_type
755{
756    T_UNKNOWN = 1,			/* no old-style analog existed	 */
757    T_CONFLICT,				/* C (conflict) list		 */
758    T_NEEDS_MERGE,			/* G (needs merging) list	 */
759    T_MODIFIED,				/* M (needs checked in) list 	 */
760    T_CHECKOUT,				/* O (needs checkout) list	 */
761    T_ADDED,				/* A (added file) list		 */
762    T_REMOVED,				/* R (removed file) list	 */
763    T_REMOVE_ENTRY,			/* W (removed entry) list	 */
764    T_UPTODATE,				/* File is up-to-date		 */
765#ifdef SERVER_SUPPORT
766    T_PATCH,				/* P Like C, but can patch	 */
767#endif
768    T_TITLE				/* title for node type 		 */
769};
770typedef enum classify_type Ctype;
771
772Ctype Classify_File PROTO
773    ((struct file_info *finfo, char *tag, char *date, char *options,
774      int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
775
776/*
777 * structure used for list nodes passed to Update_Logfile() and
778 * do_editor().
779 */
780struct logfile_info
781{
782  enum classify_type type;
783  char *tag;
784  char *rev_old;		/* rev number before a commit/modify,
785				   NULL for add or import */
786  char *rev_new;		/* rev number after a commit/modify,
787				   add, or import, NULL for remove */
788};
789
790/* Wrappers.  */
791
792typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
793typedef enum {
794    /* -t and -f wrapper options.  Treating directories as single files.  */
795    WRAP_TOCVS,
796    WRAP_FROMCVS,
797    /* -k wrapper option.  Default keyword expansion options.  */
798    WRAP_RCSOPTION
799} WrapMergeHas;
800
801void  wrap_setup PROTO((void));
802int   wrap_name_has PROTO((const char *name,WrapMergeHas has));
803char *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
804char *wrap_tocvs_process_file PROTO((const char *fileName));
805int   wrap_merge_is_copy PROTO((const char *fileName));
806void wrap_fromcvs_process_file PROTO ((const char *fileName));
807void wrap_add_file PROTO((const char *file,int temp));
808void wrap_add PROTO((char *line,int temp));
809void wrap_send PROTO ((void));
810#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
811void wrap_unparse_rcs_options PROTO ((char **, int));
812#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
813
814/* Pathname expansion */
815char *expand_path PROTO((char *name, char *file, int line));
816
817/* User variables.  */
818extern List *variable_list;
819
820extern void variable_set PROTO ((char *nameval));
821
822int watch PROTO ((int argc, char **argv));
823int edit PROTO ((int argc, char **argv));
824int unedit PROTO ((int argc, char **argv));
825int editors PROTO ((int argc, char **argv));
826int watchers PROTO ((int argc, char **argv));
827extern int annotate PROTO ((int argc, char **argv));
828extern int add PROTO ((int argc, char **argv));
829extern int admin PROTO ((int argc, char **argv));
830extern int checkout PROTO ((int argc, char **argv));
831extern int commit PROTO ((int argc, char **argv));
832extern int diff PROTO ((int argc, char **argv));
833extern int history PROTO ((int argc, char **argv));
834extern int import PROTO ((int argc, char **argv));
835extern int cvslog PROTO ((int argc, char **argv));
836#ifdef AUTH_CLIENT_SUPPORT
837extern int login PROTO((int argc, char **argv));
838int logout PROTO((int argc, char **argv));
839#endif /* AUTH_CLIENT_SUPPORT */
840extern int patch PROTO((int argc, char **argv));
841extern int release PROTO((int argc, char **argv));
842extern int cvsremove PROTO((int argc, char **argv));
843extern int rtag PROTO((int argc, char **argv));
844extern int status PROTO((int argc, char **argv));
845extern int cvstag PROTO((int argc, char **argv));
846
847extern unsigned long int lookup_command_attribute PROTO((char *));
848
849#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
850char *scramble PROTO ((char *str));
851char *descramble PROTO ((char *str));
852#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
853
854#ifdef AUTH_CLIENT_SUPPORT
855char *get_cvs_password PROTO((void));
856#endif /* AUTH_CLIENT_SUPPORT */
857
858extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
859extern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
860					 char *));
861
862/* From server.c and documented there.  */
863extern void cvs_output PROTO ((const char *, size_t));
864extern void cvs_output_binary PROTO ((char *, size_t));
865extern void cvs_outerr PROTO ((const char *, size_t));
866extern void cvs_flusherr PROTO ((void));
867extern void cvs_flushout PROTO ((void));
868extern void cvs_output_tagged PROTO ((char *, char *));
869
870#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
871#include "server.h"
872#endif
873