cvs.h revision 17721
117721Speter/* $CVSid: @(#)cvs.h 1.86 94/10/22 $	 */
217721Speter
317721Speter/*
417721Speter * basic information used in all source files
517721Speter *
617721Speter */
717721Speter
817721Speter
917721Speter#include "config.h"		/* this is stuff found via autoconf */
1017721Speter#include "options.h"		/* these are some larger questions which
1117721Speter				   can't easily be automatically checked
1217721Speter				   for */
1317721Speter
1417721Speter/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
1517721Speter
1617721Speter#ifdef __STDC__
1717721Speter#define	PTR	void *
1817721Speter#else
1917721Speter#define	PTR	char *
2017721Speter#endif
2117721Speter
2217721Speter/* Add prototype support.  */
2317721Speter#ifndef PROTO
2417721Speter#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
2517721Speter#define PROTO(ARGS) ARGS
2617721Speter#else
2717721Speter#define PROTO(ARGS) ()
2817721Speter#endif
2917721Speter#endif
3017721Speter
3117721Speter#include <stdio.h>
3217721Speter
3317721Speter/* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
3417721Speter#ifdef USE_OWN_POPEN
3517721Speter#include "popen.h"
3617721Speter#endif
3717721Speter
3817721Speter#ifdef STDC_HEADERS
3917721Speter#include <stdlib.h>
4017721Speter#else
4117721Speterextern void exit ();
4217721Speterextern char *getenv();
4317721Speter#endif
4417721Speter
4517721Speter#ifdef HAVE_UNISTD_H
4617721Speter#include <unistd.h>
4717721Speter#endif
4817721Speter
4917721Speter#ifdef HAVE_STRING_H
5017721Speter#include <string.h>
5117721Speter#else
5217721Speter#include <strings.h>
5317721Speter#endif
5417721Speter
5517721Speter#ifdef SERVER_SUPPORT
5617721Speter/* If the system doesn't provide strerror, it won't be declared in
5717721Speter   string.h.  */
5817721Speterchar *strerror ();
5917721Speter#endif
6017721Speter
6117721Speter#include <fnmatch.h> /* This is supposed to be available on Posix systems */
6217721Speter
6317721Speter#include <ctype.h>
6417721Speter#include <pwd.h>
6517721Speter#include <signal.h>
6617721Speter
6717721Speter#ifdef HAVE_ERRNO_H
6817721Speter#include <errno.h>
6917721Speter#else
7017721Speter#ifndef errno
7117721Speterextern int errno;
7217721Speter#endif /* !errno */
7317721Speter#endif /* HAVE_ERRNO_H */
7417721Speter
7517721Speter#include "system.h"
7617721Speter
7717721Speter#include "hash.h"
7817721Speter#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
7917721Speter#include "server.h"
8017721Speter#include "client.h"
8117721Speter#endif
8217721Speter
8317721Speter#ifdef MY_NDBM
8417721Speter#include "myndbm.h"
8517721Speter#else
8617721Speter#include <ndbm.h>
8717721Speter#endif /* MY_NDBM */
8817721Speter
8917721Speter#include "regex.h"
9017721Speter#include "getopt.h"
9117721Speter#include "wait.h"
9217721Speter
9317721Speter#include "rcs.h"
9417721Speter
9517721Speter
9617721Speter/* XXX - for now this is static */
9717721Speter#ifndef PATH_MAX
9817721Speter#ifdef MAXPATHLEN
9917721Speter#define	PATH_MAX MAXPATHLEN+2
10017721Speter#else
10117721Speter#define	PATH_MAX 1024+2
10217721Speter#endif
10317721Speter#endif /* PATH_MAX */
10417721Speter
10517721Speter/* just in case this implementation does not define this */
10617721Speter#ifndef L_tmpnam
10717721Speter#define	L_tmpnam	50
10817721Speter#endif
10917721Speter
11017721Speter
11117721Speter/*
11217721Speter * Copyright (c) 1992, Brian Berliner and Jeff Polk
11317721Speter * Copyright (c) 1989-1992, Brian Berliner
11417721Speter *
11517721Speter * You may distribute under the terms of the GNU General Public License as
11617721Speter * specified in the README file that comes with the CVS 1.4 kit.
11717721Speter *
11817721Speter * Definitions for the CVS Administrative directory and the files it contains.
11917721Speter * Here as #define's to make changing the names a simple task.
12017721Speter */
12117721Speter
12217721Speter#ifdef USE_VMS_FILENAMES
12317721Speter#define CVSADM          "CVS"
12417721Speter#define CVSADM_ENT      "CVS/Entries."
12517721Speter#define CVSADM_ENTBAK   "CVS/Entries.Backup"
12617721Speter#define CVSADM_ENTLOG   "CVS/Entries.Log"
12717721Speter#define CVSADM_ENTSTAT  "CVS/Entries.Static"
12817721Speter#define CVSADM_REP      "CVS/Repository."
12917721Speter#define CVSADM_ROOT     "CVS/Root."
13017721Speter#define CVSADM_CIPROG   "CVS/Checkin.prog"
13117721Speter#define CVSADM_UPROG    "CVS/Update.prog"
13217721Speter#define CVSADM_TAG      "CVS/Tag."
13317721Speter#define CVSADM_NOTIFY   "CVS/Notify."
13417721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
13517721Speter#define CVSADM_BASE      "CVS/Base"
13617721Speter#define CVSADM_TEMPLATE "CVS/Template."
13717721Speter#else /* USE_VMS_FILENAMES */
13817721Speter#define	CVSADM		"CVS"
13917721Speter#define	CVSADM_ENT	"CVS/Entries"
14017721Speter#define	CVSADM_ENTBAK	"CVS/Entries.Backup"
14117721Speter#define CVSADM_ENTLOG	"CVS/Entries.Log"
14217721Speter#define	CVSADM_ENTSTAT	"CVS/Entries.Static"
14317721Speter#define	CVSADM_REP	"CVS/Repository"
14417721Speter#define	CVSADM_ROOT	"CVS/Root"
14517721Speter#define	CVSADM_CIPROG	"CVS/Checkin.prog"
14617721Speter#define	CVSADM_UPROG	"CVS/Update.prog"
14717721Speter#define	CVSADM_TAG	"CVS/Tag"
14817721Speter#define CVSADM_NOTIFY	"CVS/Notify"
14917721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
15017721Speter/* A directory in which we store base versions of files we currently are
15117721Speter   editing with "cvs edit".  */
15217721Speter#define CVSADM_BASE     "CVS/Base"
15317721Speter/* File which contains the template for use in log messages.  */
15417721Speter#define CVSADM_TEMPLATE "CVS/Template"
15517721Speter#endif /* USE_VMS_FILENAMES */
15617721Speter
15717721Speter/* This is the special directory which we use to store various extra
15817721Speter   per-directory information in the repository.  It must be the same as
15917721Speter   CVSADM to avoid creating a new reserved directory name which users cannot
16017721Speter   use, but is a separate #define because if anyone changes it (which I don't
16117721Speter   recommend), one needs to deal with old, unconverted, repositories.
16217721Speter
16317721Speter   See fileattr.h for details about file attributes, the only thing stored
16417721Speter   in CVSREP currently.  */
16517721Speter#define CVSREP "CVS"
16617721Speter
16717721Speter/*
16817721Speter * Definitions for the CVSROOT Administrative directory and the files it
16917721Speter * contains.  This directory is created as a sub-directory of the $CVSROOT
17017721Speter * environment variable, and holds global administration information for the
17117721Speter * entire source repository beginning at $CVSROOT.
17217721Speter */
17317721Speter#define	CVSROOTADM		"CVSROOT"
17417721Speter#define	CVSROOTADM_MODULES	"modules"
17517721Speter#define	CVSROOTADM_LOGINFO	"loginfo"
17617721Speter#define	CVSROOTADM_RCSINFO	"rcsinfo"
17717721Speter#define CVSROOTADM_COMMITINFO	"commitinfo"
17817721Speter#define CVSROOTADM_TAGINFO      "taginfo"
17917721Speter#define	CVSROOTADM_EDITINFO	"editinfo"
18017721Speter#define	CVSROOTADM_HISTORY	"history"
18117721Speter#define CVSROOTADM_VALTAGS	"val-tags"
18217721Speter#define	CVSROOTADM_IGNORE	"cvsignore"
18317721Speter#define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
18417721Speter#define CVSROOTADM_WRAPPER	"cvswrappers"
18517721Speter#define CVSROOTADM_NOTIFY	"notify"
18617721Speter#define CVSROOTADM_USERS	"users"
18717721Speter
18817721Speter#define CVSNULLREPOS		"Emptydir"	/* an empty directory */
18917721Speter
19017721Speter/* Other CVS file names */
19117721Speter
19217721Speter/* Files go in the attic if the head main branch revision is dead,
19317721Speter   otherwise they go in the regular repository directories.  The whole
19417721Speter   concept of having an attic is sort of a relic from before death
19517721Speter   support but on the other hand, it probably does help the speed of
19617721Speter   some operations (such as main branch checkouts and updates).  */
19717721Speter#define	CVSATTIC	"Attic"
19817721Speter
19917721Speter#define	CVSLCK		"#cvs.lock"
20017721Speter#define	CVSRFL		"#cvs.rfl"
20117721Speter#define	CVSWFL		"#cvs.wfl"
20217721Speter#define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
20317721Speter#define	CVSEXT_LOG	",t"
20417721Speter#define	CVSPREFIX	",,"
20517721Speter#define CVSDOTIGNORE	".cvsignore"
20617721Speter#define CVSDOTWRAPPER   ".cvswrappers"
20717721Speter
20817721Speter/* miscellaneous CVS defines */
20917721Speter#define	CVSEDITPREFIX	"CVS: "
21017721Speter#define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
21117721Speter#define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
21217721Speter#define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
21317721Speter
21417721Speter#ifdef USE_VMS_FILENAMES
21517721Speter#define BAKPREFIX       "_$"
21617721Speter#define DEVNULL         "NLA0:"
21717721Speter#else /* USE_VMS_FILENAMES */
21817721Speter#define	BAKPREFIX	".#"		/* when rcsmerge'ing */
21917721Speter#ifndef DEVNULL
22017721Speter#define	DEVNULL		"/dev/null"
22117721Speter#endif
22217721Speter#endif /* USE_VMS_FILENAMES */
22317721Speter
22417721Speter#define	FALSE		0
22517721Speter#define	TRUE		1
22617721Speter
22717721Speter/*
22817721Speter * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
22917721Speter * sticky tags. -rBASE	refers to the current revision the user has checked
23017721Speter * out This mimics the behaviour of RCS.
23117721Speter */
23217721Speter#define	TAG_HEAD	"HEAD"
23317721Speter#define	TAG_BASE	"BASE"
23417721Speter
23517721Speter/* Environment variable used by CVS */
23617721Speter#define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
23717721Speter#define	CVSREAD_DFLT	FALSE		/* writable files by default */
23817721Speter
23917721Speter#define	RCSBIN_ENV	"RCSBIN"	/* RCS binary directory */
24017721Speter/* #define	RCSBIN_DFLT		   Set by config.h */
24117721Speter
24217721Speter#define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
24317721Speter#define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
24417721Speter#define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
24517721Speter/* #define	EDITOR_DFLT		   Set by config.h */
24617721Speter
24717721Speter#define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
24817721Speter#define	CVSROOT_DFLT	NULL		/* No dflt; must set for checkout */
24917721Speter
25017721Speter#define	IGNORE_ENV	"CVSIGNORE"	/* More files to ignore */
25117721Speter#define WRAPPER_ENV     "CVSWRAPPERS"   /* name of the wrapper file */
25217721Speter
25317721Speter#define	CVSUMASK_ENV	"CVSUMASK"	/* Effective umask for repository */
25417721Speter/* #define	CVSUMASK_DFLT		   Set by config.h */
25517721Speter
25617721Speter/*
25717721Speter * If the beginning of the Repository matches the following string, strip it
25817721Speter * so that the output to the logfile does not contain a full pathname.
25917721Speter *
26017721Speter * If the CVSROOT environment variable is set, it overrides this define.
26117721Speter */
26217721Speter#define	REPOS_STRIP	"/master/"
26317721Speter
26417721Speter/*
26517721Speter * The maximum number of files per each CVS directory. This is mainly for
26617721Speter * sizing arrays statically rather than dynamically.  3000 seems plenty for
26717721Speter * now.
26817721Speter */
26917721Speter#define	MAXFILEPERDIR	3000
27017721Speter#define	MAXLINELEN	5000		/* max input line from a file */
27117721Speter#define	MAXPROGLEN	30000		/* max program length to system() */
27217721Speter#define	MAXLISTLEN	40000		/* For [A-Z]list holders */
27317721Speter#define MAXDATELEN	50		/* max length for a date */
27417721Speter
27517721Speter/* structure of a entry record */
27617721Speterstruct entnode
27717721Speter{
27817721Speter    char *user;
27917721Speter    char *version;
28017721Speter    char *timestamp;
28117721Speter    char *options;
28217721Speter    char *tag;
28317721Speter    char *date;
28417721Speter    char *conflict;
28517721Speter};
28617721Spetertypedef struct entnode Entnode;
28717721Speter
28817721Speter/* The type of request that is being done in do_module() */
28917721Speterenum mtype
29017721Speter{
29117721Speter    CHECKOUT, TAG, PATCH, EXPORT
29217721Speter};
29317721Speter
29417721Speter/*
29517721Speter * defines for Classify_File() to determine the current state of a file.
29617721Speter * These are also used as types in the data field for the list we make for
29717721Speter * Update_Logfile in commit, import, and add.
29817721Speter */
29917721Speterenum classify_type
30017721Speter{
30117721Speter    T_UNKNOWN = 1,			/* no old-style analog existed	 */
30217721Speter    T_CONFLICT,				/* C (conflict) list		 */
30317721Speter    T_NEEDS_MERGE,			/* G (needs merging) list	 */
30417721Speter    T_MODIFIED,				/* M (needs checked in) list 	 */
30517721Speter    T_CHECKOUT,				/* O (needs checkout) list	 */
30617721Speter    T_ADDED,				/* A (added file) list		 */
30717721Speter    T_REMOVED,				/* R (removed file) list	 */
30817721Speter    T_REMOVE_ENTRY,			/* W (removed entry) list	 */
30917721Speter    T_UPTODATE,				/* File is up-to-date		 */
31017721Speter#ifdef SERVER_SUPPORT
31117721Speter    T_PATCH,				/* P Like C, but can patch	 */
31217721Speter#endif
31317721Speter    T_TITLE				/* title for node type 		 */
31417721Speter};
31517721Spetertypedef enum classify_type Ctype;
31617721Speter
31717721Speter/*
31817721Speter * a struct vers_ts contains all the information about a file including the
31917721Speter * user and rcs file names, and the version checked out and the head.
32017721Speter *
32117721Speter * this is usually obtained from a call to Version_TS which takes a tag argument
32217721Speter * for the RCS file if desired
32317721Speter */
32417721Speterstruct vers_ts
32517721Speter{
32617721Speter    /* rcs version user file derives from, from CVS/Entries.
32717721Speter     * it can have the following special values:
32817721Speter     *    empty = no user file
32917721Speter     *    0 = user file is new
33017721Speter     *    -vers = user file to be removed.  */
33117721Speter    char *vn_user;
33217721Speter
33317721Speter    /* Numeric revision number corresponding to ->vn_tag (->vn_tag
33417721Speter       will often be symbolic).  */
33517721Speter    char *vn_rcs;
33617721Speter    /* If ->tag corresponds to a tag which really exists in this file,
33717721Speter       this is just a copy of ->tag.  If not, this is either NULL or
33817721Speter       the head revision.  (Or something like that, see RCS_getversion
33917721Speter       and friends).  */
34017721Speter    char *vn_tag;
34117721Speter
34217721Speter    /* This is the timestamp from stating the file in the working directory.
34317721Speter       It is NULL if there is no file in the working directory.  */
34417721Speter    char *ts_user;
34517721Speter    /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
34617721Speter       are computed in a slightly different way, but the fact remains that
34717721Speter       if they are equal the file in the working directory is unmodified
34817721Speter       and if they differ it is modified.  */
34917721Speter    char *ts_rcs;
35017721Speter
35117721Speter    /* Options from CVS/Entries (keyword expansion).  */
35217721Speter    char *options;
35317721Speter
35417721Speter    /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
35517721Speter       and the time stamp in this field is the time stamp of the working
35617721Speter       directory file which was created with the conflict markers in it.
35717721Speter       This is from CVS/Entries.  */
35817721Speter    char *ts_conflict;
35917721Speter
36017721Speter    /* Tag specified on the command line, or if none, tag stored in
36117721Speter       CVS/Entries.  */
36217721Speter    char *tag;
36317721Speter    /* Date specified on the command line, or if none, date stored in
36417721Speter       CVS/Entries.  */
36517721Speter    char *date;
36617721Speter
36717721Speter    /* Pointer to entries file node  */
36817721Speter    Entnode *entdata;
36917721Speter
37017721Speter    /* Pointer to parsed src file info */
37117721Speter    RCSNode *srcfile;
37217721Speter};
37317721Spetertypedef struct vers_ts Vers_TS;
37417721Speter
37517721Speter/*
37617721Speter * structure used for list-private storage by Entries_Open() and
37717721Speter * Version_TS().
37817721Speter */
37917721Speterstruct stickydirtag
38017721Speter{
38117721Speter    int aflag;
38217721Speter    char *tag;
38317721Speter    char *date;
38417721Speter    char *options;
38517721Speter};
38617721Speter
38717721Speter/* Flags for find_{names,dirs} routines */
38817721Speter#define W_LOCAL			0x01	/* look for files locally */
38917721Speter#define W_REPOS			0x02	/* look for files in the repository */
39017721Speter#define W_ATTIC			0x04	/* look for files in the attic */
39117721Speter
39217721Speter/* Flags for return values of direnter procs for the recursion processor */
39317721Speterenum direnter_type
39417721Speter{
39517721Speter    R_PROCESS = 1,			/* process files and maybe dirs */
39617721Speter    R_SKIP_FILES,			/* don't process files in this dir */
39717721Speter    R_SKIP_DIRS,			/* don't process sub-dirs */
39817721Speter    R_SKIP_ALL				/* don't process files or dirs */
39917721Speter};
40017721Spetertypedef enum direnter_type Dtype;
40117721Speter
40217721Speterextern char *program_name, *program_path, *command_name;
40317721Speterextern char *Rcsbin, *Editor, *CVSroot;
40417721Speterextern char *CVSADM_Root;
40517721Speterextern int cvsadmin_root;
40617721Speterextern char *CurDir;
40717721Speterextern int really_quiet, quiet;
40817721Speterextern int use_editor;
40917721Speterextern int cvswrite;
41017721Speterextern mode_t cvsumask;
41117721Speter
41217721Speterextern int trace;		/* Show all commands */
41317721Speterextern int noexec;		/* Don't modify disk anywhere */
41417721Speterextern int logoff;		/* Don't write history entry */
41517721Speter
41617721Speterextern char hostname[];
41717721Speter
41817721Speter/* Externs that are included directly in the CVS sources */
41917721Speter
42017721Speterint RCS_settag PROTO((const char *, const char *, const char *));
42117721Speterint RCS_deltag PROTO((const char *, const char *, int));
42217721Speterint RCS_setbranch PROTO((const char *, const char *));
42317721Speterint RCS_lock PROTO((const char *, const char *, int));
42417721Speterint RCS_unlock PROTO((const char *, const char *, int));
42517721Speterint RCS_merge PROTO((const char *, const char *, const char *, const char *));
42617721Speterint RCS_checkout PROTO ((char *rcsfile, char *workfile, char *tag,
42717721Speter			 char *options,
42817721Speter                         char *sout, int flags, int noerr));
42917721Speter/* Flags used by RCS_* functions.  See the description of the individual
43017721Speter   functions for which flags mean what for each function.  */
43117721Speter#define RCS_FLAGS_LOCK 1
43217721Speter#define RCS_FLAGS_FORCE 2
43317721Speter#define RCS_FLAGS_DEAD 4
43417721Speter#define RCS_FLAGS_QUIET 8
43517721Speter#define RCS_FLAGS_MODTIME 16
43617721Speterint RCS_checkin PROTO ((char *rcsfile, char *workfile, char *message,
43717721Speter			char *rev, int flags, int noerr));
43817721Speter
43917721Speter
44017721Speter
44117721Speter#include "error.h"
44217721Speter
44317721SpeterDBM *open_module PROTO((void));
44417721SpeterFILE *open_file PROTO((const char *, const char *));
44517721SpeterList *Find_Directories PROTO((char *repository, int which));
44617721Spetervoid Entries_Close PROTO((List *entries));
44717721SpeterList *Entries_Open PROTO((int aflag));
44817721Speterchar *Make_Date PROTO((char *rawdate));
44917721Speterchar *Name_Repository PROTO((char *dir, char *update_dir));
45017721Speterchar *Name_Root PROTO((char *dir, char *update_dir));
45117721Spetervoid Create_Root PROTO((char *dir, char *rootdir));
45217721Speterint same_directories PROTO((char *dir1, char *dir2));
45317721Speterchar *Short_Repository PROTO((char *repository));
45417721Speterchar *gca PROTO((char *rev1, char *rev2));
45517721Speterchar *getcaller PROTO((void));
45617721Speterchar *time_stamp PROTO((char *file));
45717721Speterchar *xmalloc PROTO((size_t bytes));
45817721Spetervoid *xrealloc PROTO((void *ptr, size_t bytes));
45917721Speterchar *xstrdup PROTO((const char *str));
46017721Spetervoid strip_trailing_newlines PROTO((char *str));
46117721Speterint No_Difference PROTO((char *file, Vers_TS * vers, List * entries,
46217721Speter			 char *repository, char *update_dir));
46317721Spetertypedef	int (*CALLPROC)	PROTO((char *repository, char *value));
46417721Speterint Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
46517721Speterint Reader_Lock PROTO((char *xrepository));
46617721Spetertypedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
46717721Speterint SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
46817721Speterint Writer_Lock PROTO((List * list));
46917721Speterint isdir PROTO((const char *file));
47017721Speterint isfile PROTO((const char *file));
47117721Speterint islink PROTO((const char *file));
47217721Speterint isreadable PROTO((const char *file));
47317721Speterint iswritable PROTO((const char *file));
47417721Speterint isaccessible PROTO((const char *file, const int mode));
47517721Speterint isabsolute PROTO((const char *filename));
47617721Speterchar *last_component PROTO((char *path));
47717721Speterchar *get_homedir PROTO ((void));
47817721Speter
47917721Speterint numdots PROTO((const char *s));
48017721Speterint unlink_file PROTO((const char *f));
48117721Speterint link_file PROTO ((const char *from, const char *to));
48217721Speterint unlink_file_dir PROTO((const char *f));
48317721Speterint update PROTO((int argc, char *argv[]));
48417721Speterint xcmp PROTO((const char *file1, const char *file2));
48517721Speterint yesno PROTO((void));
48617721Spetervoid *valloc PROTO((size_t bytes));
48717721Spetertime_t get_date PROTO((char *date, struct timeb *now));
48817721Spetervoid Create_Admin PROTO((char *dir, char *update_dir,
48917721Speter			 char *repository, char *tag, char *date));
49017721Speter
49117721Spetervoid Lock_Cleanup PROTO((void));
49217721Speter
49317721Speter/* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
49417721Speter   and AFLAG, anyway.  */
49517721Spetervoid lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag));
49617721Speter
49717721Speter/* Remove locks set by lock_tree_for_write.  Currently removes readlocks
49817721Speter   too.  */
49917721Spetervoid lock_tree_cleanup PROTO ((void));
50017721Speter
50117721Spetervoid ParseTag PROTO((char **tagp, char **datep));
50217721Spetervoid Scratch_Entry PROTO((List * list, char *fname));
50317721Spetervoid WriteTag PROTO((char *dir, char *tag, char *date));
50417721Spetervoid cat_module PROTO((int status));
50517721Spetervoid check_entries PROTO((char *dir));
50617721Spetervoid close_module PROTO((DBM * db));
50717721Spetervoid copy_file PROTO((const char *from, const char *to));
50817721Spetervoid (*error_set_cleanup PROTO((void (*) (void)))) PROTO ((void));
50917721Spetervoid fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
51017721Spetervoid free_names PROTO((int *pargc, char *argv[]));
51117721Spetervoid freevers_ts PROTO((Vers_TS ** versp));
51217721Speter
51317721Speterextern int ign_name PROTO ((char *name));
51417721Spetervoid ign_add PROTO((char *ign, int hold));
51517721Spetervoid ign_add_file PROTO((char *file, int hold));
51617721Spetervoid ign_setup PROTO((void));
51717721Spetervoid ign_dir_add PROTO((char *name));
51817721Speterint ignore_directory PROTO((char *name));
51917721Spetertypedef void (*Ignore_proc) PROTO ((char *, char *));
52017721Speterextern void ignore_files PROTO ((List *, char *, Ignore_proc));
52117721Speterextern int ign_inhibit_server;
52217721Speterextern int ign_case;
52317721Speter
52417721Speter#include "update.h"
52517721Speter
52617721Spetervoid line2argv PROTO((int *pargc, char *argv[], char *line));
52717721Spetervoid make_directories PROTO((const char *name));
52817721Spetervoid make_directory PROTO((const char *name));
52917721Spetervoid rename_file PROTO((const char *from, const char *to));
53017721Speter/* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
53117721Speter   files which exist in the current directory, and accordingly to OS-specific
53217721Speter   conventions regarding wildcard syntax.  It might be desirable to change the
53317721Speter   former in the future (e.g. "cvs status *.h" including files which don't exist
53417721Speter   in the working directory).  The result is placed in *PARGC and *PARGV;
53517721Speter   the *PARGV array itself and all the strings it contains are newly
53617721Speter   malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
53717721Speterextern void expand_wild PROTO ((int argc, char **argv,
53817721Speter                                int *pargc, char ***pargv));
53917721Speter
54017721Spetervoid strip_path PROTO((char *path));
54117721Spetervoid strip_trailing_slashes PROTO((char *path));
54217721Spetervoid update_delproc PROTO((Node * p));
54317721Spetervoid usage PROTO((const char *const *cpp));
54417721Spetervoid xchmod PROTO((char *fname, int writable));
54517721Speterchar *xgetwd PROTO((void));
54617721Speterint Checkin PROTO((int type, char *file, char *update_dir,
54717721Speter		   char *repository, char *rcs, char *rev,
54817721Speter		   char *tag, char *options, char *message, List *entries));
54917721SpeterCtype Classify_File PROTO((char *file, char *tag, char *date, char *options,
55017721Speter		     int force_tag_match, int aflag, char *repository,
55117721Speter		     List *entries, RCSNode *rcsnode, Vers_TS **versp,
55217721Speter		     char *update_dir, int pipeout));
55317721SpeterList *Find_Names PROTO((char *repository, int which, int aflag,
55417721Speter		  List ** optentries));
55517721Spetervoid Register PROTO((List * list, char *fname, char *vn, char *ts,
55617721Speter	       char *options, char *tag, char *date, char *ts_conflict));
55717721Spetervoid Update_Logfile PROTO((char *repository, char *xmessage, char *xrevision,
55817721Speter		     FILE * xlogfp, List * xchanges));
55917721SpeterVers_TS *Version_TS PROTO((char *repository, char *options, char *tag,
56017721Speter		     char *date, char *user, int force_tag_match,
56117721Speter		     int set_time, List * entries, RCSNode * rcs));
56217721Spetervoid do_editor PROTO((char *dir, char **messagep,
56317721Speter		      char *repository, List * changes));
56417721Speter
56517721Spetertypedef	int (*CALLBACKPROC)	PROTO((int *pargc, char *argv[], char *where,
56617721Speter	char *mwhere, char *mfile, int horten, int local_specified,
56717721Speter	char *omodule, char *msg));
56817721Speter
56917721Speter/* This is the structure that the recursion processor passes to the
57017721Speter   fileproc to tell it about a particular file.  */
57117721Speterstruct file_info
57217721Speter{
57317721Speter    /* Name of the file, without any directory component.  */
57417721Speter    char *file;
57517721Speter
57617721Speter    /* Name of the directory we are in, relative to the directory in
57717721Speter       which this command was issued.  We have cd'd to this directory
57817721Speter       (either in the working directory or in the repository, depending
57917721Speter       on which sort of recursion we are doing).  If we are in the directory
58017721Speter       in which the command was issued, this is "".  */
58117721Speter    char *update_dir;
58217721Speter
58317721Speter    /* update_dir and file put together, with a slash between them as
58417721Speter       necessary.  This is the proper way to refer to the file in user
58517721Speter       messages.  */
58617721Speter    char *fullname;
58717721Speter
58817721Speter    /* Name of the directory corresponding to the repository which contains
58917721Speter       this file.  */
59017721Speter    char *repository;
59117721Speter
59217721Speter    /* The pre-parsed entries for this directory.  */
59317721Speter    List *entries;
59417721Speter
59517721Speter    RCSNode *rcs;
59617721Speter};
59717721Speter
59817721Spetertypedef	int (*FILEPROC)		PROTO((struct file_info *finfo));
59917721Spetertypedef	int (*FILESDONEPROC)	PROTO((int err, char *repository, char *update_dir));
60017721Spetertypedef	Dtype (*DIRENTPROC)	PROTO((char *dir, char *repos, char *update_dir));
60117721Spetertypedef	int (*DIRLEAVEPROC)	PROTO((char *dir, int err, char *update_dir));
60217721Speter
60317721Speterextern int mkmodules PROTO ((char *dir));
60417721Speterextern int init PROTO ((int argc, char **argv));
60517721Speter
60617721Speterint do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
60717721Speter		CALLBACKPROC callback_proc, char *where, int shorten,
60817721Speter		int local_specified, int run_module_prog, char *extra_arg));
60917721Speterint do_recursion PROTO((FILEPROC xfileproc, FILESDONEPROC xfilesdoneproc,
61017721Speter		  DIRENTPROC xdirentproc, DIRLEAVEPROC xdirleaveproc,
61117721Speter		  Dtype xflags, int xwhich, int xaflag, int xreadlock,
61217721Speter		  int xdosrcs));
61317721Spetervoid history_write PROTO((int type, char *update_dir, char *revs, char *name,
61417721Speter		    char *repository));
61517721Speterint start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
61617721Speter		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
61717721Speter		     int argc, char *argv[], int local, int which,
61817721Speter		     int aflag, int readlock, char *update_preload,
61917721Speter		     int dosrcs, int wd_is_repos));
62017721Spetervoid SIG_beginCrSect PROTO((void));
62117721Spetervoid SIG_endCrSect PROTO((void));
62217721Spetervoid read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
62317721Speter
62417721Speterchar *make_message_rcslegal PROTO((char *message));
62517721Speter
62617721Speter/* flags for run_exec(), the fast system() for CVS */
62717721Speter#define	RUN_NORMAL		0x0000	/* no special behaviour */
62817721Speter#define	RUN_COMBINED		0x0001	/* stdout is duped to stderr */
62917721Speter#define	RUN_REALLY		0x0002	/* do the exec, even if noexec is on */
63017721Speter#define	RUN_STDOUT_APPEND	0x0004	/* append to stdout, don't truncate */
63117721Speter#define	RUN_STDERR_APPEND	0x0008	/* append to stderr, don't truncate */
63217721Speter#define	RUN_SIGIGNORE		0x0010	/* ignore interrupts for command */
63317721Speter#define	RUN_TTY		(char *)0	/* for the benefit of lint */
63417721Speter
63517721Spetervoid run_arg PROTO((const char *s));
63617721Spetervoid run_print PROTO((FILE * fp));
63717721Speter#ifdef HAVE_VPRINTF
63817721Spetervoid run_setup PROTO((const char *fmt,...));
63917721Spetervoid run_args PROTO((const char *fmt,...));
64017721Speter#else
64117721Spetervoid run_setup ();
64217721Spetervoid run_args ();
64317721Speter#endif
64417721Speterint run_exec PROTO((char *stin, char *stout, char *sterr, int flags));
64517721Speter
64617721Speter/* other similar-minded stuff from run.c.  */
64717721SpeterFILE *run_popen PROTO((const char *, const char *));
64817721Speterint piped_child PROTO((char **, int *, int *));
64917721Spetervoid close_on_exec PROTO((int));
65017721Speterint filter_stream_through_program PROTO((int, int, char **, pid_t *));
65117721Speter
65217721Speterpid_t waitpid PROTO((pid_t, int *, int));
65317721Speter
65417721Speter/* Wrappers.  */
65517721Speter
65617721Spetertypedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
65717721Spetertypedef enum { WRAP_TOCVS, WRAP_FROMCVS, WRAP_CONFLICT } WrapMergeHas;
65817721Speter
65917721Spetervoid  wrap_setup PROTO((void));
66017721Speterint   wrap_name_has PROTO((const char *name,WrapMergeHas has));
66117721Speterchar *wrap_tocvs_process_file PROTO((const char *fileName));
66217721Speterint   wrap_merge_is_copy PROTO((const char *fileName));
66317721Speterchar *wrap_fromcvs_process_file PROTO((const char *fileName));
66417721Spetervoid wrap_add_file PROTO((const char *file,int temp));
66517721Spetervoid wrap_add PROTO((char *line,int temp));
66617721Speter
66717721Speter/* Pathname expansion */
66817721Speterchar *expand_path PROTO((char *name, char *file, int line));
66917721Speter
67017721Speter/* User variables.  */
67117721Speterextern List *variable_list;
67217721Speter
67317721Speterextern void variable_set PROTO ((char *nameval));
67417721Speter
67517721Speterint watch PROTO ((int argc, char **argv));
67617721Speterint edit PROTO ((int argc, char **argv));
67717721Speterint unedit PROTO ((int argc, char **argv));
67817721Speterint editors PROTO ((int argc, char **argv));
67917721Speterint watchers PROTO ((int argc, char **argv));
68017721Speterextern int annotate PROTO ((int argc, char **argv));
68117721Speter
68217721Speter#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
68317721Speterchar *scramble PROTO ((char *str));
68417721Speterchar *descramble PROTO ((char *str));
68517721Speter#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
68617721Speter
68717721Speterextern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
68817721Speter
68917721Speterextern void cvs_output PROTO ((char *, size_t));
69017721Speterextern void cvs_outerr PROTO ((char *, size_t));
691