cvs.h revision 25847
125839Speter/*
225839Speter * Copyright (c) 1992, Brian Berliner and Jeff Polk
325839Speter * Copyright (c) 1989-1992, Brian Berliner
425839Speter *
525839Speter * You may distribute under the terms of the GNU General Public License as
625839Speter * specified in the README file that comes with the CVS kit.
725839Speter */
817721Speter
917721Speter/*
1017721Speter * basic information used in all source files
1117721Speter *
1217721Speter */
1317721Speter
1417721Speter
1517721Speter#include "config.h"		/* this is stuff found via autoconf */
1617721Speter#include "options.h"		/* these are some larger questions which
1717721Speter				   can't easily be automatically checked
1817721Speter				   for */
1917721Speter
2017721Speter/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
2117721Speter
2217721Speter#ifdef __STDC__
2317721Speter#define	PTR	void *
2417721Speter#else
2517721Speter#define	PTR	char *
2617721Speter#endif
2717721Speter
2817721Speter/* Add prototype support.  */
2917721Speter#ifndef PROTO
3017721Speter#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
3117721Speter#define PROTO(ARGS) ARGS
3217721Speter#else
3317721Speter#define PROTO(ARGS) ()
3417721Speter#endif
3517721Speter#endif
3617721Speter
3717721Speter#include <stdio.h>
3817721Speter
3917721Speter/* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
4017721Speter#ifdef USE_OWN_POPEN
4117721Speter#include "popen.h"
4217721Speter#endif
4317721Speter
4417721Speter#ifdef STDC_HEADERS
4517721Speter#include <stdlib.h>
4617721Speter#else
4717721Speterextern void exit ();
4817721Speterextern char *getenv();
4917721Speter#endif
5017721Speter
5117721Speter#ifdef HAVE_UNISTD_H
5217721Speter#include <unistd.h>
5317721Speter#endif
5417721Speter
5517721Speter#ifdef HAVE_STRING_H
5617721Speter#include <string.h>
5717721Speter#else
5817721Speter#include <strings.h>
5917721Speter#endif
6017721Speter
6117721Speter#ifdef SERVER_SUPPORT
6217721Speter/* If the system doesn't provide strerror, it won't be declared in
6317721Speter   string.h.  */
6417721Speterchar *strerror ();
6517721Speter#endif
6617721Speter
6717721Speter#include <fnmatch.h> /* This is supposed to be available on Posix systems */
6817721Speter
6917721Speter#include <ctype.h>
7017721Speter#include <pwd.h>
7117721Speter#include <signal.h>
7217721Speter
7317721Speter#ifdef HAVE_ERRNO_H
7417721Speter#include <errno.h>
7517721Speter#else
7617721Speter#ifndef errno
7717721Speterextern int errno;
7817721Speter#endif /* !errno */
7917721Speter#endif /* HAVE_ERRNO_H */
8017721Speter
8117721Speter#include "system.h"
8217721Speter
8317721Speter#include "hash.h"
8417721Speter#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
8517721Speter#include "client.h"
8617721Speter#endif
8717721Speter
8817721Speter#ifdef MY_NDBM
8917721Speter#include "myndbm.h"
9017721Speter#else
9117721Speter#include <ndbm.h>
9217721Speter#endif /* MY_NDBM */
9317721Speter
9417721Speter#include "regex.h"
9517721Speter#include "getopt.h"
9617721Speter#include "wait.h"
9717721Speter
9817721Speter#include "rcs.h"
9917721Speter
10017721Speter
10125839Speter/* This actually gets set in system.h.  Note that the _ONLY_ reason for
10225839Speter   this is if various system calls (getwd, getcwd, readlink) require/want
10325839Speter   us to use it.  All other parts of CVS allocate pathname buffers
10425839Speter   dynamically, and we want to keep it that way.  */
10517721Speter#ifndef PATH_MAX
10617721Speter#ifdef MAXPATHLEN
10717721Speter#define	PATH_MAX MAXPATHLEN+2
10817721Speter#else
10917721Speter#define	PATH_MAX 1024+2
11017721Speter#endif
11117721Speter#endif /* PATH_MAX */
11217721Speter
11325839Speter/* Definitions for the CVS Administrative directory and the files it contains.
11425839Speter   Here as #define's to make changing the names a simple task.  */
11517721Speter
11617721Speter#ifdef USE_VMS_FILENAMES
11717721Speter#define CVSADM          "CVS"
11817721Speter#define CVSADM_ENT      "CVS/Entries."
11917721Speter#define CVSADM_ENTBAK   "CVS/Entries.Backup"
12017721Speter#define CVSADM_ENTLOG   "CVS/Entries.Log"
12117721Speter#define CVSADM_ENTSTAT  "CVS/Entries.Static"
12217721Speter#define CVSADM_REP      "CVS/Repository."
12317721Speter#define CVSADM_ROOT     "CVS/Root."
12417721Speter#define CVSADM_CIPROG   "CVS/Checkin.prog"
12517721Speter#define CVSADM_UPROG    "CVS/Update.prog"
12617721Speter#define CVSADM_TAG      "CVS/Tag."
12717721Speter#define CVSADM_NOTIFY   "CVS/Notify."
12817721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
12917721Speter#define CVSADM_BASE      "CVS/Base"
13017721Speter#define CVSADM_TEMPLATE "CVS/Template."
13117721Speter#else /* USE_VMS_FILENAMES */
13217721Speter#define	CVSADM		"CVS"
13317721Speter#define	CVSADM_ENT	"CVS/Entries"
13417721Speter#define	CVSADM_ENTBAK	"CVS/Entries.Backup"
13517721Speter#define CVSADM_ENTLOG	"CVS/Entries.Log"
13617721Speter#define	CVSADM_ENTSTAT	"CVS/Entries.Static"
13717721Speter#define	CVSADM_REP	"CVS/Repository"
13817721Speter#define	CVSADM_ROOT	"CVS/Root"
13917721Speter#define	CVSADM_CIPROG	"CVS/Checkin.prog"
14017721Speter#define	CVSADM_UPROG	"CVS/Update.prog"
14117721Speter#define	CVSADM_TAG	"CVS/Tag"
14217721Speter#define CVSADM_NOTIFY	"CVS/Notify"
14317721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
14417721Speter/* A directory in which we store base versions of files we currently are
14517721Speter   editing with "cvs edit".  */
14617721Speter#define CVSADM_BASE     "CVS/Base"
14717721Speter/* File which contains the template for use in log messages.  */
14817721Speter#define CVSADM_TEMPLATE "CVS/Template"
14917721Speter#endif /* USE_VMS_FILENAMES */
15017721Speter
15117721Speter/* This is the special directory which we use to store various extra
15217721Speter   per-directory information in the repository.  It must be the same as
15317721Speter   CVSADM to avoid creating a new reserved directory name which users cannot
15417721Speter   use, but is a separate #define because if anyone changes it (which I don't
15517721Speter   recommend), one needs to deal with old, unconverted, repositories.
15617721Speter
15717721Speter   See fileattr.h for details about file attributes, the only thing stored
15817721Speter   in CVSREP currently.  */
15917721Speter#define CVSREP "CVS"
16017721Speter
16117721Speter/*
16217721Speter * Definitions for the CVSROOT Administrative directory and the files it
16317721Speter * contains.  This directory is created as a sub-directory of the $CVSROOT
16417721Speter * environment variable, and holds global administration information for the
16517721Speter * entire source repository beginning at $CVSROOT.
16617721Speter */
16717721Speter#define	CVSROOTADM		"CVSROOT"
16817721Speter#define	CVSROOTADM_MODULES	"modules"
16917721Speter#define	CVSROOTADM_LOGINFO	"loginfo"
17017721Speter#define	CVSROOTADM_RCSINFO	"rcsinfo"
17117721Speter#define CVSROOTADM_COMMITINFO	"commitinfo"
17217721Speter#define CVSROOTADM_TAGINFO      "taginfo"
17317721Speter#define	CVSROOTADM_EDITINFO	"editinfo"
17425839Speter#define CVSROOTADM_VERIFYMSG    "verifymsg"
17517721Speter#define	CVSROOTADM_HISTORY	"history"
17617721Speter#define CVSROOTADM_VALTAGS	"val-tags"
17717721Speter#define	CVSROOTADM_IGNORE	"cvsignore"
17817721Speter#define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
17917721Speter#define CVSROOTADM_WRAPPER	"cvswrappers"
18017721Speter#define CVSROOTADM_NOTIFY	"notify"
18117721Speter#define CVSROOTADM_USERS	"users"
18225839Speter#define CVSROOTADM_READERS	"readers"
18325839Speter#define CVSROOTADM_WRITERS	"writers"
18425839Speter#define CVSROOTADM_PASSWD	"passwd"
18525847Speter#define CVSROOTADM_OPTIONS	"options"
18617721Speter
18717721Speter#define CVSNULLREPOS		"Emptydir"	/* an empty directory */
18817721Speter
18917721Speter/* Other CVS file names */
19017721Speter
19117721Speter/* Files go in the attic if the head main branch revision is dead,
19217721Speter   otherwise they go in the regular repository directories.  The whole
19317721Speter   concept of having an attic is sort of a relic from before death
19417721Speter   support but on the other hand, it probably does help the speed of
19517721Speter   some operations (such as main branch checkouts and updates).  */
19617721Speter#define	CVSATTIC	"Attic"
19717721Speter
19817721Speter#define	CVSLCK		"#cvs.lock"
19917721Speter#define	CVSRFL		"#cvs.rfl"
20017721Speter#define	CVSWFL		"#cvs.wfl"
20117721Speter#define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
20217721Speter#define	CVSEXT_LOG	",t"
20317721Speter#define	CVSPREFIX	",,"
20417721Speter#define CVSDOTIGNORE	".cvsignore"
20517721Speter#define CVSDOTWRAPPER   ".cvswrappers"
20617721Speter
20725839Speter/* Command attributes -- see function lookup_command_attribute(). */
20825839Speter#define CVS_CMD_IGNORE_ADMROOT        1
20925839Speter
21025839Speter/* Set if CVS does _not_ need to create a CVS/Root file upon
21125839Speter   completion of this command.  The name is confusing, both because
21225839Speter   the meaning is closer to "does not use working directory" than
21325839Speter   "uses working directory" and because the flag isn't really as
21425839Speter   general purpose as it seems (cvs release sets it).  */
21525839Speter
21625839Speter#define CVS_CMD_USES_WORK_DIR         2
21725839Speter
21825839Speter#define CVS_CMD_MODIFIES_REPOSITORY   4
21925839Speter
22017721Speter/* miscellaneous CVS defines */
22125839Speter
22225839Speter/* This is the string which is at the start of the non-log-message lines
22325839Speter   that we put up for the user when they edit the log message.  */
22417721Speter#define	CVSEDITPREFIX	"CVS: "
22525839Speter/* Number of characters in CVSEDITPREFIX to compare when deciding to strip
22625839Speter   off those lines.  We don't check for the space, to accomodate users who
22725839Speter   have editors which strip trailing spaces.  */
22825839Speter#define CVSEDITPREFIXLEN 4
22925839Speter
23017721Speter#define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
23117721Speter#define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
23217721Speter#define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
23317721Speter
23417721Speter#ifdef USE_VMS_FILENAMES
23517721Speter#define BAKPREFIX       "_$"
23617721Speter#define DEVNULL         "NLA0:"
23717721Speter#else /* USE_VMS_FILENAMES */
23817721Speter#define	BAKPREFIX	".#"		/* when rcsmerge'ing */
23917721Speter#ifndef DEVNULL
24017721Speter#define	DEVNULL		"/dev/null"
24117721Speter#endif
24217721Speter#endif /* USE_VMS_FILENAMES */
24317721Speter
24417721Speter#define	FALSE		0
24517721Speter#define	TRUE		1
24617721Speter
24717721Speter/*
24817721Speter * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
24917721Speter * sticky tags. -rBASE	refers to the current revision the user has checked
25017721Speter * out This mimics the behaviour of RCS.
25117721Speter */
25217721Speter#define	TAG_HEAD	"HEAD"
25317721Speter#define	TAG_BASE	"BASE"
25417721Speter
25517721Speter/* Environment variable used by CVS */
25617721Speter#define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
25717721Speter#define	CVSREAD_DFLT	FALSE		/* writable files by default */
25817721Speter
25917721Speter#define	RCSBIN_ENV	"RCSBIN"	/* RCS binary directory */
26025839Speter/* #define	RCSBIN_DFLT		   Set by options.h */
26117721Speter
26225839Speter#define	TMPDIR_ENV	"TMPDIR"	/* Temporary directory */
26325839Speter/* #define	TMPDIR_DFLT		   Set by options.h */
26425839Speter
26517721Speter#define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
26617721Speter#define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
26717721Speter#define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
26825839Speter/* #define	EDITOR_DFLT		   Set by options.h */
26917721Speter
27017721Speter#define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
27117721Speter#define	CVSROOT_DFLT	NULL		/* No dflt; must set for checkout */
27217721Speter
27317721Speter#define	IGNORE_ENV	"CVSIGNORE"	/* More files to ignore */
27417721Speter#define WRAPPER_ENV     "CVSWRAPPERS"   /* name of the wrapper file */
27517721Speter
27617721Speter#define	CVSUMASK_ENV	"CVSUMASK"	/* Effective umask for repository */
27725839Speter/* #define	CVSUMASK_DFLT		   Set by options.h */
27817721Speter
27917721Speter/*
28017721Speter * If the beginning of the Repository matches the following string, strip it
28117721Speter * so that the output to the logfile does not contain a full pathname.
28217721Speter *
28317721Speter * If the CVSROOT environment variable is set, it overrides this define.
28417721Speter */
28517721Speter#define	REPOS_STRIP	"/master/"
28617721Speter
28725839Speter/* Large enough to hold DATEFORM.  Not an arbitrary limit as long as
28825839Speter   it is used for that purpose, and not to hold a string from the
28925839Speter   command line, the client, etc.  */
29025839Speter#define MAXDATELEN	50
29117721Speter
29225839Speter/* The type of an entnode.  */
29325839Speterenum ent_type
29425839Speter{
29525839Speter    ENT_FILE, ENT_SUBDIR
29625839Speter};
29725839Speter
29817721Speter/* structure of a entry record */
29917721Speterstruct entnode
30017721Speter{
30125839Speter    enum ent_type type;
30217721Speter    char *user;
30317721Speter    char *version;
30417721Speter    char *timestamp;
30517721Speter    char *options;
30617721Speter    char *tag;
30717721Speter    char *date;
30817721Speter    char *conflict;
30917721Speter};
31017721Spetertypedef struct entnode Entnode;
31117721Speter
31217721Speter/* The type of request that is being done in do_module() */
31317721Speterenum mtype
31417721Speter{
31517721Speter    CHECKOUT, TAG, PATCH, EXPORT
31617721Speter};
31717721Speter
31817721Speter/*
31917721Speter * structure used for list-private storage by Entries_Open() and
32025839Speter * Version_TS() and Find_Directories().
32117721Speter */
32217721Speterstruct stickydirtag
32317721Speter{
32425839Speter    /* These fields pass sticky tag information from Entries_Open() to
32525839Speter       Version_TS().  */
32617721Speter    int aflag;
32717721Speter    char *tag;
32817721Speter    char *date;
32925839Speter    int nonbranch;
33025839Speter
33125839Speter    /* This field is set by Entries_Open() if there was subdirectory
33225839Speter       information; Find_Directories() uses it to see whether it needs
33325839Speter       to scan the directory itself.  */
33425839Speter    int subdirs;
33517721Speter};
33617721Speter
33717721Speter/* Flags for find_{names,dirs} routines */
33817721Speter#define W_LOCAL			0x01	/* look for files locally */
33917721Speter#define W_REPOS			0x02	/* look for files in the repository */
34017721Speter#define W_ATTIC			0x04	/* look for files in the attic */
34117721Speter
34217721Speter/* Flags for return values of direnter procs for the recursion processor */
34317721Speterenum direnter_type
34417721Speter{
34517721Speter    R_PROCESS = 1,			/* process files and maybe dirs */
34617721Speter    R_SKIP_FILES,			/* don't process files in this dir */
34717721Speter    R_SKIP_DIRS,			/* don't process sub-dirs */
34817721Speter    R_SKIP_ALL				/* don't process files or dirs */
34917721Speter};
35025839Speter#ifdef ENUMS_CAN_BE_TROUBLE
35125839Spetertypedef int Dtype;
35225839Speter#else
35317721Spetertypedef enum direnter_type Dtype;
35425839Speter#endif
35517721Speter
35617721Speterextern char *program_name, *program_path, *command_name;
35725839Speterextern char *Rcsbin, *Tmpdir, *Editor;
35817721Speterextern int cvsadmin_root;
35917721Speterextern char *CurDir;
36017721Speterextern int really_quiet, quiet;
36117721Speterextern int use_editor;
36217721Speterextern int cvswrite;
36317721Speterextern mode_t cvsumask;
36425847Speterextern char *RCS_citag;
36517721Speter
36625839Speter/* Access method specified in CVSroot. */
36725839Spetertypedef enum {
36825839Speter  local_method, server_method, pserver_method, kserver_method, ext_method
36925839Speter} CVSmethod;
37025839Speterextern char *method_names[];	/* change this in root.c if you change
37125839Speter				   the enum above */
37225839Speter
37325839Speterextern char *CVSroot_original;	/* the active, complete CVSroot string */
37425839Speterextern int client_active;	/* nonzero if we are doing remote access */
37525839Speterextern CVSmethod CVSroot_method; /* one of the enum values above */
37625839Speterextern char *CVSroot_username;	/* the username or NULL if method == local */
37725839Speterextern char *CVSroot_hostname;	/* the hostname or NULL if method == local */
37825839Speterextern char *CVSroot_directory;	/* the directory name */
37925839Speter
38017721Speterextern int trace;		/* Show all commands */
38117721Speterextern int noexec;		/* Don't modify disk anywhere */
38217721Speterextern int logoff;		/* Don't write history entry */
38317721Speter
38425839Speter#ifdef AUTH_SERVER_SUPPORT
38525839Speterextern char *Pserver_Repos;     /* used to check that same repos is
38625839Speter                                   transmitted in pserver auth and in
38725839Speter                                   CVS protocol. */
38825839Speter#endif /* AUTH_SERVER_SUPPORT */
38925839Speter
39017721Speterextern char hostname[];
39117721Speter
39217721Speter/* Externs that are included directly in the CVS sources */
39317721Speter
39425839Speterint RCS_exec_settag PROTO((const char *, const char *, const char *));
39525839Speterint RCS_exec_deltag PROTO((const char *, const char *, int));
39625839Speterint RCS_exec_setbranch PROTO((const char *, const char *));
39725839Speterint RCS_exec_lock PROTO((const char *, const char *, int));
39825839Speterint RCS_exec_unlock PROTO((const char *, const char *, int));
39917721Speterint RCS_merge PROTO((const char *, const char *, const char *, const char *));
40017721Speter/* Flags used by RCS_* functions.  See the description of the individual
40117721Speter   functions for which flags mean what for each function.  */
40225839Speter#define RCS_FLAGS_FORCE 1
40325839Speter#define RCS_FLAGS_DEAD 2
40425839Speter#define RCS_FLAGS_QUIET 4
40525839Speter#define RCS_FLAGS_MODTIME 8
40617721Speterint RCS_checkin PROTO ((char *rcsfile, char *workfile, char *message,
40725839Speter			char *rev, int flags));
40817721Speter
40917721Speter
41017721Speter
41117721Speter#include "error.h"
41217721Speter
41317721SpeterDBM *open_module PROTO((void));
41417721SpeterFILE *open_file PROTO((const char *, const char *));
41525839SpeterList *Find_Directories PROTO((char *repository, int which, List *entries));
41617721Spetervoid Entries_Close PROTO((List *entries));
41717721SpeterList *Entries_Open PROTO((int aflag));
41825839Spetervoid Subdirs_Known PROTO((List *entries));
41925839Spetervoid Subdir_Register PROTO((List *, const char *, const char *));
42025839Spetervoid Subdir_Deregister PROTO((List *, const char *, const char *));
42117721Speterchar *Make_Date PROTO((char *rawdate));
42217721Speterchar *Name_Repository PROTO((char *dir, char *update_dir));
42317721Speterchar *Name_Root PROTO((char *dir, char *update_dir));
42425839Speterint parse_cvsroot PROTO((char *CVSroot));
42525839Spetervoid set_local_cvsroot PROTO((char *dir));
42617721Spetervoid Create_Root PROTO((char *dir, char *rootdir));
42717721Speterint same_directories PROTO((char *dir1, char *dir2));
42817721Speterchar *Short_Repository PROTO((char *repository));
42917721Speterchar *gca PROTO((char *rev1, char *rev2));
43017721Speterchar *getcaller PROTO((void));
43117721Speterchar *time_stamp PROTO((char *file));
43225839Speter
43317721Speterchar *xmalloc PROTO((size_t bytes));
43417721Spetervoid *xrealloc PROTO((void *ptr, size_t bytes));
43525839Spetervoid expand_string PROTO ((char **, size_t *, size_t));
43617721Speterchar *xstrdup PROTO((const char *str));
43717721Spetervoid strip_trailing_newlines PROTO((char *str));
43825839Speterint pathname_levels PROTO ((char *path));
43925839Speter
44017721Spetertypedef	int (*CALLPROC)	PROTO((char *repository, char *value));
44117721Speterint Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
44217721Spetertypedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
44317721Speterint SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
44417721Speterint isdir PROTO((const char *file));
44517721Speterint isfile PROTO((const char *file));
44617721Speterint islink PROTO((const char *file));
44717721Speterint isreadable PROTO((const char *file));
44817721Speterint iswritable PROTO((const char *file));
44917721Speterint isaccessible PROTO((const char *file, const int mode));
45017721Speterint isabsolute PROTO((const char *filename));
45117721Speterchar *last_component PROTO((char *path));
45217721Speterchar *get_homedir PROTO ((void));
45325839Speterchar *cvs_temp_name PROTO ((void));
45425847Spetervoid parseopts PROTO ((const char *root));
45517721Speter
45617721Speterint numdots PROTO((const char *s));
45717721Speterint unlink_file PROTO((const char *f));
45817721Speterint link_file PROTO ((const char *from, const char *to));
45917721Speterint unlink_file_dir PROTO((const char *f));
46017721Speterint update PROTO((int argc, char *argv[]));
46117721Speterint xcmp PROTO((const char *file1, const char *file2));
46217721Speterint yesno PROTO((void));
46317721Spetervoid *valloc PROTO((size_t bytes));
46417721Spetertime_t get_date PROTO((char *date, struct timeb *now));
46517721Spetervoid Create_Admin PROTO((char *dir, char *update_dir,
46625839Speter			 char *repository, char *tag, char *date,
46725839Speter			 int nonbranch));
46817721Speter
46925839Speter/* Locking subsystem (implemented in lock.c).  */
47025839Speter
47125839Speterint Reader_Lock PROTO((char *xrepository));
47217721Spetervoid Lock_Cleanup PROTO((void));
47317721Speter
47417721Speter/* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
47517721Speter   and AFLAG, anyway.  */
47617721Spetervoid lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag));
47717721Speter
47825839Speter/* See lock.c for description.  */
47925839Speterextern void lock_dir_for_write PROTO ((char *));
48017721Speter
48117721Spetervoid Scratch_Entry PROTO((List * list, char *fname));
48225839Spetervoid ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
48325839Spetervoid WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
48425839Speter		      char *update_dir, char *repository));
48517721Spetervoid cat_module PROTO((int status));
48617721Spetervoid check_entries PROTO((char *dir));
48717721Spetervoid close_module PROTO((DBM * db));
48817721Spetervoid copy_file PROTO((const char *from, const char *to));
48917721Spetervoid fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
49017721Spetervoid free_names PROTO((int *pargc, char *argv[]));
49117721Speter
49217721Speterextern int ign_name PROTO ((char *name));
49317721Spetervoid ign_add PROTO((char *ign, int hold));
49417721Spetervoid ign_add_file PROTO((char *file, int hold));
49517721Spetervoid ign_setup PROTO((void));
49617721Spetervoid ign_dir_add PROTO((char *name));
49717721Speterint ignore_directory PROTO((char *name));
49817721Spetertypedef void (*Ignore_proc) PROTO ((char *, char *));
49925839Speterextern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
50017721Speterextern int ign_inhibit_server;
50117721Speterextern int ign_case;
50217721Speter
50317721Speter#include "update.h"
50417721Speter
50525839Spetervoid line2argv PROTO ((int *pargc, char ***argv, char *line));
50617721Spetervoid make_directories PROTO((const char *name));
50717721Spetervoid make_directory PROTO((const char *name));
50825839Speterextern int mkdir_if_needed PROTO ((char *name));
50917721Spetervoid rename_file PROTO((const char *from, const char *to));
51017721Speter/* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
51117721Speter   files which exist in the current directory, and accordingly to OS-specific
51217721Speter   conventions regarding wildcard syntax.  It might be desirable to change the
51317721Speter   former in the future (e.g. "cvs status *.h" including files which don't exist
51417721Speter   in the working directory).  The result is placed in *PARGC and *PARGV;
51517721Speter   the *PARGV array itself and all the strings it contains are newly
51617721Speter   malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
51717721Speterextern void expand_wild PROTO ((int argc, char **argv,
51817721Speter                                int *pargc, char ***pargv));
51917721Speter
52025839Speter#ifdef SERVER_SUPPORT
52125839Speterextern int cvs_casecmp PROTO ((char *, char *));
52225839Speterextern int fopen_case PROTO ((char *, char *, FILE **, char **));
52325839Speter#endif
52425839Speter
52517721Spetervoid strip_trailing_slashes PROTO((char *path));
52617721Spetervoid update_delproc PROTO((Node * p));
52717721Spetervoid usage PROTO((const char *const *cpp));
52817721Spetervoid xchmod PROTO((char *fname, int writable));
52917721Speterchar *xgetwd PROTO((void));
53017721SpeterList *Find_Names PROTO((char *repository, int which, int aflag,
53117721Speter		  List ** optentries));
53217721Spetervoid Register PROTO((List * list, char *fname, char *vn, char *ts,
53317721Speter	       char *options, char *tag, char *date, char *ts_conflict));
53425839Spetervoid Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
53525839Speter		     List * xchanges));
53617721Spetervoid do_editor PROTO((char *dir, char **messagep,
53717721Speter		      char *repository, List * changes));
53817721Speter
53925839Spetervoid do_verify PROTO((char *message, char *repository));
54025839Speter
54117721Spetertypedef	int (*CALLBACKPROC)	PROTO((int *pargc, char *argv[], char *where,
54217721Speter	char *mwhere, char *mfile, int horten, int local_specified,
54317721Speter	char *omodule, char *msg));
54417721Speter
54517721Speter/* This is the structure that the recursion processor passes to the
54617721Speter   fileproc to tell it about a particular file.  */
54717721Speterstruct file_info
54817721Speter{
54917721Speter    /* Name of the file, without any directory component.  */
55017721Speter    char *file;
55117721Speter
55217721Speter    /* Name of the directory we are in, relative to the directory in
55317721Speter       which this command was issued.  We have cd'd to this directory
55417721Speter       (either in the working directory or in the repository, depending
55517721Speter       on which sort of recursion we are doing).  If we are in the directory
55617721Speter       in which the command was issued, this is "".  */
55717721Speter    char *update_dir;
55817721Speter
55917721Speter    /* update_dir and file put together, with a slash between them as
56017721Speter       necessary.  This is the proper way to refer to the file in user
56117721Speter       messages.  */
56217721Speter    char *fullname;
56317721Speter
56417721Speter    /* Name of the directory corresponding to the repository which contains
56517721Speter       this file.  */
56617721Speter    char *repository;
56717721Speter
56817721Speter    /* The pre-parsed entries for this directory.  */
56917721Speter    List *entries;
57017721Speter
57117721Speter    RCSNode *rcs;
57217721Speter};
57317721Speter
57425839Spetertypedef	int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
57525839Spetertypedef	int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
57625839Speter				     char *repository, char *update_dir,
57725839Speter				     List *entries));
57825839Spetertypedef	Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
57925839Speter				    char *repos, char *update_dir,
58025839Speter				    List *entries));
58125839Spetertypedef	int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
58225839Speter				    char *update_dir, List *entries));
58317721Speter
58417721Speterextern int mkmodules PROTO ((char *dir));
58517721Speterextern int init PROTO ((int argc, char **argv));
58617721Speter
58717721Speterint do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
58817721Speter		CALLBACKPROC callback_proc, char *where, int shorten,
58917721Speter		int local_specified, int run_module_prog, char *extra_arg));
59017721Spetervoid history_write PROTO((int type, char *update_dir, char *revs, char *name,
59117721Speter		    char *repository));
59217721Speterint start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
59317721Speter		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
59425839Speter		     void *callerdat,
59517721Speter		     int argc, char *argv[], int local, int which,
59617721Speter		     int aflag, int readlock, char *update_preload,
59725839Speter		     int dosrcs));
59817721Spetervoid SIG_beginCrSect PROTO((void));
59917721Spetervoid SIG_endCrSect PROTO((void));
60017721Spetervoid read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
60117721Speter
60217721Speterchar *make_message_rcslegal PROTO((char *message));
60325839Speterextern int file_has_markers PROTO ((struct file_info *));
60417721Speter
60517721Speter/* flags for run_exec(), the fast system() for CVS */
60617721Speter#define	RUN_NORMAL		0x0000	/* no special behaviour */
60717721Speter#define	RUN_COMBINED		0x0001	/* stdout is duped to stderr */
60817721Speter#define	RUN_REALLY		0x0002	/* do the exec, even if noexec is on */
60917721Speter#define	RUN_STDOUT_APPEND	0x0004	/* append to stdout, don't truncate */
61017721Speter#define	RUN_STDERR_APPEND	0x0008	/* append to stderr, don't truncate */
61117721Speter#define	RUN_SIGIGNORE		0x0010	/* ignore interrupts for command */
61217721Speter#define	RUN_TTY		(char *)0	/* for the benefit of lint */
61317721Speter
61417721Spetervoid run_arg PROTO((const char *s));
61517721Spetervoid run_print PROTO((FILE * fp));
61617721Speter#ifdef HAVE_VPRINTF
61717721Spetervoid run_setup PROTO((const char *fmt,...));
61817721Spetervoid run_args PROTO((const char *fmt,...));
61917721Speter#else
62017721Spetervoid run_setup ();
62117721Spetervoid run_args ();
62217721Speter#endif
62317721Speterint run_exec PROTO((char *stin, char *stout, char *sterr, int flags));
62417721Speter
62517721Speter/* other similar-minded stuff from run.c.  */
62617721SpeterFILE *run_popen PROTO((const char *, const char *));
62717721Speterint piped_child PROTO((char **, int *, int *));
62817721Spetervoid close_on_exec PROTO((int));
62917721Speterint filter_stream_through_program PROTO((int, int, char **, pid_t *));
63017721Speter
63117721Speterpid_t waitpid PROTO((pid_t, int *, int));
63217721Speter
63325839Speter/*
63425839Speter * a struct vers_ts contains all the information about a file including the
63525839Speter * user and rcs file names, and the version checked out and the head.
63625839Speter *
63725839Speter * this is usually obtained from a call to Version_TS which takes a
63825839Speter * tag argument for the RCS file if desired
63925839Speter */
64025839Speterstruct vers_ts
64125839Speter{
64225839Speter    /* rcs version user file derives from, from CVS/Entries.
64325839Speter     * it can have the following special values:
64425839Speter     *    empty = no user file
64525839Speter     *    0 = user file is new
64625839Speter     *    -vers = user file to be removed.  */
64725839Speter    char *vn_user;
64825839Speter
64925839Speter    /* Numeric revision number corresponding to ->vn_tag (->vn_tag
65025839Speter       will often be symbolic).  */
65125839Speter    char *vn_rcs;
65225839Speter    /* If ->tag is a simple tag in the RCS file--a tag which really
65325839Speter       exists which is not a magic revision--and if ->date is NULL,
65425839Speter       then this is a copy of ->tag.  Otherwise, it is a copy of
65525839Speter       ->vn_rcs.  */
65625839Speter    char *vn_tag;
65725839Speter
65825839Speter    /* This is the timestamp from stating the file in the working directory.
65925839Speter       It is NULL if there is no file in the working directory.  It is
66025839Speter       "Is-modified" if we know the file is modified but don't have its
66125839Speter       contents.  */
66225839Speter    char *ts_user;
66325839Speter    /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
66425839Speter       are computed in a slightly different way, but the fact remains that
66525839Speter       if they are equal the file in the working directory is unmodified
66625839Speter       and if they differ it is modified.  */
66725839Speter    char *ts_rcs;
66825839Speter
66925839Speter    /* Options from CVS/Entries (keyword expansion).  */
67025839Speter    char *options;
67125839Speter
67225839Speter    /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
67325839Speter       and the time stamp in this field is the time stamp of the working
67425839Speter       directory file which was created with the conflict markers in it.
67525839Speter       This is from CVS/Entries.  */
67625839Speter    char *ts_conflict;
67725839Speter
67825839Speter    /* Tag specified on the command line, or if none, tag stored in
67925839Speter       CVS/Entries.  */
68025839Speter    char *tag;
68125839Speter    /* Date specified on the command line, or if none, date stored in
68225839Speter       CVS/Entries.  */
68325839Speter    char *date;
68425839Speter    /* If this is 1, then tag is not a branch tag.  If this is 0, then
68525839Speter       tag may or may not be a branch tag.  */
68625839Speter    int nonbranch;
68725839Speter
68825839Speter    /* Pointer to entries file node  */
68925839Speter    Entnode *entdata;
69025839Speter
69125839Speter    /* Pointer to parsed src file info */
69225839Speter    RCSNode *srcfile;
69325839Speter};
69425839Spetertypedef struct vers_ts Vers_TS;
69525839Speter
69625839SpeterVers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
69725839Speter			    char *date, int force_tag_match,
69825839Speter			    int set_time));
69925839Spetervoid freevers_ts PROTO ((Vers_TS ** versp));
70025839Speter
70125839Speter/* Miscellaneous CVS infrastructure which layers on top of the recursion
70225839Speter   processor (for example, needs struct file_info).  */
70325839Speter
70425839Speterint Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
70525839Speter		    char *tag, char *options, char *message));
70625839Speterint No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
70725839Speter
70825839Speter/*
70925839Speter * defines for Classify_File() to determine the current state of a file.
71025839Speter * These are also used as types in the data field for the list we make for
71125839Speter * Update_Logfile in commit, import, and add.
71225839Speter */
71325839Speterenum classify_type
71425839Speter{
71525839Speter    T_UNKNOWN = 1,			/* no old-style analog existed	 */
71625839Speter    T_CONFLICT,				/* C (conflict) list		 */
71725839Speter    T_NEEDS_MERGE,			/* G (needs merging) list	 */
71825839Speter    T_MODIFIED,				/* M (needs checked in) list 	 */
71925839Speter    T_CHECKOUT,				/* O (needs checkout) list	 */
72025839Speter    T_ADDED,				/* A (added file) list		 */
72125839Speter    T_REMOVED,				/* R (removed file) list	 */
72225839Speter    T_REMOVE_ENTRY,			/* W (removed entry) list	 */
72325839Speter    T_UPTODATE,				/* File is up-to-date		 */
72425839Speter#ifdef SERVER_SUPPORT
72525839Speter    T_PATCH,				/* P Like C, but can patch	 */
72625839Speter#endif
72725839Speter    T_TITLE				/* title for node type 		 */
72825839Speter};
72925839Spetertypedef enum classify_type Ctype;
73025839Speter
73125839SpeterCtype Classify_File PROTO
73225839Speter    ((struct file_info *finfo, char *tag, char *date, char *options,
73325839Speter      int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
73425839Speter
73525839Speter/*
73625839Speter * structure used for list nodes passed to Update_Logfile() and
73725839Speter * do_editor().
73825839Speter */
73925839Speterstruct logfile_info
74025839Speter{
74125839Speter  enum classify_type type;
74225839Speter  char *tag;
74325839Speter  char *rev_old;		/* rev number before a commit/modify,
74425839Speter				   NULL for add or import */
74525839Speter  char *rev_new;		/* rev number after a commit/modify,
74625839Speter				   add, or import, NULL for remove */
74725839Speter};
74825839Speter
74917721Speter/* Wrappers.  */
75017721Speter
75117721Spetertypedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
75225839Spetertypedef enum {
75325839Speter    /* -t and -f wrapper options.  Treating directories as single files.  */
75425839Speter    WRAP_TOCVS,
75525839Speter    WRAP_FROMCVS,
75625839Speter    /* -k wrapper option.  Default keyword expansion options.  */
75725839Speter    WRAP_RCSOPTION
75825839Speter} WrapMergeHas;
75917721Speter
76017721Spetervoid  wrap_setup PROTO((void));
76117721Speterint   wrap_name_has PROTO((const char *name,WrapMergeHas has));
76225839Speterchar *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
76317721Speterchar *wrap_tocvs_process_file PROTO((const char *fileName));
76417721Speterint   wrap_merge_is_copy PROTO((const char *fileName));
76525839Spetervoid wrap_fromcvs_process_file PROTO ((const char *fileName));
76617721Spetervoid wrap_add_file PROTO((const char *file,int temp));
76717721Spetervoid wrap_add PROTO((char *line,int temp));
76825839Spetervoid wrap_send PROTO ((void));
76917721Speter
77017721Speter/* Pathname expansion */
77117721Speterchar *expand_path PROTO((char *name, char *file, int line));
77217721Speter
77317721Speter/* User variables.  */
77417721Speterextern List *variable_list;
77517721Speter
77617721Speterextern void variable_set PROTO ((char *nameval));
77717721Speter
77817721Speterint watch PROTO ((int argc, char **argv));
77917721Speterint edit PROTO ((int argc, char **argv));
78017721Speterint unedit PROTO ((int argc, char **argv));
78117721Speterint editors PROTO ((int argc, char **argv));
78217721Speterint watchers PROTO ((int argc, char **argv));
78317721Speterextern int annotate PROTO ((int argc, char **argv));
78425839Speterextern int add PROTO ((int argc, char **argv));
78525839Speterextern int admin PROTO ((int argc, char **argv));
78625839Speterextern int checkout PROTO ((int argc, char **argv));
78725839Speterextern int commit PROTO ((int argc, char **argv));
78825839Speterextern int diff PROTO ((int argc, char **argv));
78925839Speterextern int history PROTO ((int argc, char **argv));
79025839Speterextern int import PROTO ((int argc, char **argv));
79125839Speterextern int cvslog PROTO ((int argc, char **argv));
79225839Speter#ifdef AUTH_CLIENT_SUPPORT
79325839Speterextern int login PROTO((int argc, char **argv));
79425839Speterint logout PROTO((int argc, char **argv));
79525839Speter#endif /* AUTH_CLIENT_SUPPORT */
79625839Speterextern int patch PROTO((int argc, char **argv));
79725839Speterextern int release PROTO((int argc, char **argv));
79825839Speterextern int cvsremove PROTO((int argc, char **argv));
79925839Speterextern int rtag PROTO((int argc, char **argv));
80025839Speterextern int status PROTO((int argc, char **argv));
80125839Speterextern int cvstag PROTO((int argc, char **argv));
80217721Speter
80325839Speterextern unsigned long int lookup_command_attribute PROTO((char *));
80425839Speter
80517721Speter#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
80617721Speterchar *scramble PROTO ((char *str));
80717721Speterchar *descramble PROTO ((char *str));
80817721Speter#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
80917721Speter
81025839Speter#ifdef AUTH_CLIENT_SUPPORT
81125839Speterchar *get_cvs_password PROTO((void));
81225839Speter#endif /* AUTH_CLIENT_SUPPORT */
81325839Speter
81417721Speterextern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
81525839Speterextern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
81625839Speter					 char *));
81717721Speter
81825839Speterextern void cvs_output PROTO ((const char *, size_t));
81925839Speterextern void cvs_outerr PROTO ((const char *, size_t));
82025839Speterextern void cvs_flusherr PROTO ((void));
82125839Speterextern void cvs_flushout PROTO ((void));
82225839Speter
82325839Speter#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
82425839Speter#include "server.h"
82525839Speter#endif
826