125839Speter/*
2175267Sobrien * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
325839Speter *
4175267Sobrien * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5175267Sobrien *                                  and others.
6175267Sobrien *
7175267Sobrien * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8175267Sobrien * Portions Copyright (C) 1989-1992, Brian Berliner
9175267Sobrien *
1025839Speter * You may distribute under the terms of the GNU General Public License as
1125839Speter * specified in the README file that comes with the CVS kit.
1225839Speter */
1317721Speter
1417721Speter/*
1517721Speter * basic information used in all source files
1617721Speter *
1754431Speter * $FreeBSD$
1817721Speter */
1917721Speter
2017721Speter
21107487Speter#ifdef HAVE_CONFIG_H
22107487Speter# include <config.h>		/* this is stuff found via autoconf */
23107487Speter#endif /* CONFIG_H */
2417721Speter
2517721Speter/* Changed from if __STDC__ to ifdef __STDC__ because of Sun's acc compiler */
2617721Speter
2717721Speter#ifdef __STDC__
2817721Speter#define	PTR	void *
2917721Speter#else
3017721Speter#define	PTR	char *
3117721Speter#endif
3217721Speter
3317721Speter/* Add prototype support.  */
3417721Speter#ifndef PROTO
3517721Speter#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
3617721Speter#define PROTO(ARGS) ARGS
3717721Speter#else
3817721Speter#define PROTO(ARGS) ()
3917721Speter#endif
4017721Speter#endif
4117721Speter
4217721Speter#include <stdio.h>
4317721Speter
4417721Speter/* Under OS/2, <stdio.h> doesn't define popen()/pclose(). */
4517721Speter#ifdef USE_OWN_POPEN
4617721Speter#include "popen.h"
4717721Speter#endif
4817721Speter
49130307Speter/* Begin GNULIB headers.  */
50130307Speter#include "xsize.h"
51130307Speter/* End GNULIB headers.  */
52130307Speter
5317721Speter#ifdef STDC_HEADERS
5417721Speter#include <stdlib.h>
5517721Speter#else
5617721Speterextern void exit ();
5717721Speterextern char *getenv();
5817721Speter#endif
5917721Speter
6017721Speter#ifdef HAVE_UNISTD_H
6117721Speter#include <unistd.h>
6217721Speter#endif
6317721Speter
6417721Speter#ifdef HAVE_STRING_H
6517721Speter#include <string.h>
6617721Speter#else
6717721Speter#include <strings.h>
6817721Speter#endif
6917721Speter
7017721Speter#ifdef SERVER_SUPPORT
7117721Speter/* If the system doesn't provide strerror, it won't be declared in
7217721Speter   string.h.  */
7317721Speterchar *strerror ();
7417721Speter#endif
7517721Speter
76107487Speter#ifdef HAVE_FNMATCH
77107487Speter# include <fnmatch.h> /* This is supposed to be available on Posix systems */
78107487Speter#else /* HAVE_FNMATCH */
79107487Speter# include "fnmatch.h" /* Our substitute */
80107487Speter#endif /* HAVE_FNMATCH */
8117721Speter
8217721Speter#include <ctype.h>
8317721Speter#include <pwd.h>
8417721Speter#include <signal.h>
8517721Speter
8617721Speter#ifdef HAVE_ERRNO_H
8717721Speter#include <errno.h>
8817721Speter#else
8917721Speter#ifndef errno
9017721Speterextern int errno;
9117721Speter#endif /* !errno */
9217721Speter#endif /* HAVE_ERRNO_H */
9317721Speter
9417721Speter#include "system.h"
9517721Speter
9617721Speter#include "hash.h"
97128269Speter#include "stack.h"
98102843Speter
99102843Speter#include "root.h"
100102843Speter
10117721Speter#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
102102843Speter# include "client.h"
10317721Speter#endif
10417721Speter
10517721Speter#ifdef MY_NDBM
10617721Speter#include "myndbm.h"
10717721Speter#else
10817721Speter#include <ndbm.h>
10917721Speter#endif /* MY_NDBM */
11017721Speter
11117721Speter#include "regex.h"
11217721Speter#include "getopt.h"
11317721Speter#include "wait.h"
11417721Speter
11517721Speter#include "rcs.h"
11617721Speter
11717721Speter
11825839Speter/* This actually gets set in system.h.  Note that the _ONLY_ reason for
11925839Speter   this is if various system calls (getwd, getcwd, readlink) require/want
12025839Speter   us to use it.  All other parts of CVS allocate pathname buffers
12125839Speter   dynamically, and we want to keep it that way.  */
12217721Speter#ifndef PATH_MAX
12317721Speter#ifdef MAXPATHLEN
12417721Speter#define	PATH_MAX MAXPATHLEN+2
12517721Speter#else
12617721Speter#define	PATH_MAX 1024+2
12717721Speter#endif
12817721Speter#endif /* PATH_MAX */
12917721Speter
13025839Speter/* Definitions for the CVS Administrative directory and the files it contains.
13125839Speter   Here as #define's to make changing the names a simple task.  */
13217721Speter
13317721Speter#ifdef USE_VMS_FILENAMES
13417721Speter#define CVSADM          "CVS"
13517721Speter#define CVSADM_ENT      "CVS/Entries."
13617721Speter#define CVSADM_ENTBAK   "CVS/Entries.Backup"
13717721Speter#define CVSADM_ENTLOG   "CVS/Entries.Log"
13817721Speter#define CVSADM_ENTSTAT  "CVS/Entries.Static"
13917721Speter#define CVSADM_REP      "CVS/Repository."
14017721Speter#define CVSADM_ROOT     "CVS/Root."
14117721Speter#define CVSADM_TAG      "CVS/Tag."
14217721Speter#define CVSADM_NOTIFY   "CVS/Notify."
14317721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
14417721Speter#define CVSADM_BASE      "CVS/Base"
14532788Speter#define CVSADM_BASEREV   "CVS/Baserev."
14632788Speter#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
14717721Speter#define CVSADM_TEMPLATE "CVS/Template."
14817721Speter#else /* USE_VMS_FILENAMES */
14917721Speter#define	CVSADM		"CVS"
15017721Speter#define	CVSADM_ENT	"CVS/Entries"
15117721Speter#define	CVSADM_ENTBAK	"CVS/Entries.Backup"
15217721Speter#define CVSADM_ENTLOG	"CVS/Entries.Log"
15317721Speter#define	CVSADM_ENTSTAT	"CVS/Entries.Static"
15417721Speter#define	CVSADM_REP	"CVS/Repository"
15517721Speter#define	CVSADM_ROOT	"CVS/Root"
15617721Speter#define	CVSADM_TAG	"CVS/Tag"
15717721Speter#define CVSADM_NOTIFY	"CVS/Notify"
15817721Speter#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
15917721Speter/* A directory in which we store base versions of files we currently are
16017721Speter   editing with "cvs edit".  */
16117721Speter#define CVSADM_BASE     "CVS/Base"
16232788Speter#define CVSADM_BASEREV  "CVS/Baserev"
16332788Speter#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
16417721Speter/* File which contains the template for use in log messages.  */
16517721Speter#define CVSADM_TEMPLATE "CVS/Template"
16617721Speter#endif /* USE_VMS_FILENAMES */
16717721Speter
16817721Speter/* This is the special directory which we use to store various extra
16917721Speter   per-directory information in the repository.  It must be the same as
17017721Speter   CVSADM to avoid creating a new reserved directory name which users cannot
17117721Speter   use, but is a separate #define because if anyone changes it (which I don't
17217721Speter   recommend), one needs to deal with old, unconverted, repositories.
17317721Speter
17417721Speter   See fileattr.h for details about file attributes, the only thing stored
17517721Speter   in CVSREP currently.  */
17617721Speter#define CVSREP "CVS"
17717721Speter
17817721Speter/*
17917721Speter * Definitions for the CVSROOT Administrative directory and the files it
18017721Speter * contains.  This directory is created as a sub-directory of the $CVSROOT
18117721Speter * environment variable, and holds global administration information for the
18217721Speter * entire source repository beginning at $CVSROOT.
18317721Speter */
18417721Speter#define	CVSROOTADM		"CVSROOT"
18517721Speter#define	CVSROOTADM_MODULES	"modules"
18617721Speter#define	CVSROOTADM_LOGINFO	"loginfo"
18717721Speter#define	CVSROOTADM_RCSINFO	"rcsinfo"
18817721Speter#define CVSROOTADM_COMMITINFO	"commitinfo"
18917721Speter#define CVSROOTADM_TAGINFO      "taginfo"
19017721Speter#define	CVSROOTADM_EDITINFO	"editinfo"
19125839Speter#define CVSROOTADM_VERIFYMSG    "verifymsg"
19217721Speter#define	CVSROOTADM_HISTORY	"history"
19317721Speter#define CVSROOTADM_VALTAGS	"val-tags"
19417721Speter#define	CVSROOTADM_IGNORE	"cvsignore"
19517721Speter#define	CVSROOTADM_CHECKOUTLIST "checkoutlist"
19617721Speter#define CVSROOTADM_WRAPPER	"cvswrappers"
19717721Speter#define CVSROOTADM_NOTIFY	"notify"
19817721Speter#define CVSROOTADM_USERS	"users"
19925839Speter#define CVSROOTADM_READERS	"readers"
20025839Speter#define CVSROOTADM_WRITERS	"writers"
20125839Speter#define CVSROOTADM_PASSWD	"passwd"
20232788Speter#define CVSROOTADM_CONFIG	"config"
20325847Speter#define CVSROOTADM_OPTIONS	"options"
20417721Speter
20517721Speter#define CVSNULLREPOS		"Emptydir"	/* an empty directory */
20617721Speter
20717721Speter/* Other CVS file names */
20817721Speter
20917721Speter/* Files go in the attic if the head main branch revision is dead,
21017721Speter   otherwise they go in the regular repository directories.  The whole
21117721Speter   concept of having an attic is sort of a relic from before death
21217721Speter   support but on the other hand, it probably does help the speed of
21317721Speter   some operations (such as main branch checkouts and updates).  */
21417721Speter#define	CVSATTIC	"Attic"
21517721Speter
21617721Speter#define	CVSLCK		"#cvs.lock"
217175267Sobrien#define	CVSHISTORYLCK	"#cvs.history.lock"
218175267Sobrien#define	CVSVALTAGSLCK	"#cvs.val-tags.lock"
21917721Speter#define	CVSRFL		"#cvs.rfl"
22017721Speter#define	CVSWFL		"#cvs.wfl"
22117721Speter#define CVSRFLPAT	"#cvs.rfl.*"	/* wildcard expr to match read locks */
22217721Speter#define	CVSEXT_LOG	",t"
22317721Speter#define	CVSPREFIX	",,"
22417721Speter#define CVSDOTIGNORE	".cvsignore"
22517721Speter#define CVSDOTWRAPPER   ".cvswrappers"
22617721Speter
22725839Speter/* Command attributes -- see function lookup_command_attribute(). */
22825839Speter#define CVS_CMD_IGNORE_ADMROOT        1
22925839Speter
23032788Speter/* Set if CVS needs to create a CVS/Root file upon completion of this
23132788Speter   command.  The name may be slightly confusing, because the flag
23232788Speter   isn't really as general purpose as it seems (it is not set for cvs
23332788Speter   release).  */
23425839Speter
23525839Speter#define CVS_CMD_USES_WORK_DIR         2
23625839Speter
23725839Speter#define CVS_CMD_MODIFIES_REPOSITORY   4
23825839Speter
23917721Speter/* miscellaneous CVS defines */
24025839Speter
24125839Speter/* This is the string which is at the start of the non-log-message lines
24225839Speter   that we put up for the user when they edit the log message.  */
24317721Speter#define	CVSEDITPREFIX	"CVS: "
24425839Speter/* Number of characters in CVSEDITPREFIX to compare when deciding to strip
24525839Speter   off those lines.  We don't check for the space, to accomodate users who
24625839Speter   have editors which strip trailing spaces.  */
24725839Speter#define CVSEDITPREFIXLEN 4
24825839Speter
24917721Speter#define	CVSLCKAGE	(60*60)		/* 1-hour old lock files cleaned up */
25017721Speter#define	CVSLCKSLEEP	30		/* wait 30 seconds before retrying */
25117721Speter#define	CVSBRANCH	"1.1.1"		/* RCS branch used for vendor srcs */
25217721Speter
25317721Speter#ifdef USE_VMS_FILENAMES
25417721Speter#define BAKPREFIX       "_$"
25517721Speter#define DEVNULL         "NLA0:"
25617721Speter#else /* USE_VMS_FILENAMES */
25717721Speter#define	BAKPREFIX	".#"		/* when rcsmerge'ing */
25817721Speter#ifndef DEVNULL
25917721Speter#define	DEVNULL		"/dev/null"
26017721Speter#endif
26117721Speter#endif /* USE_VMS_FILENAMES */
26217721Speter
26317721Speter/*
26417721Speter * Special tags. -rHEAD	refers to the head of an RCS file, regardless of any
26517721Speter * sticky tags. -rBASE	refers to the current revision the user has checked
26617721Speter * out This mimics the behaviour of RCS.
26717721Speter */
26817721Speter#define	TAG_HEAD	"HEAD"
26917721Speter#define	TAG_BASE	"BASE"
27017721Speter
27117721Speter/* Environment variable used by CVS */
27217721Speter#define	CVSREAD_ENV	"CVSREAD"	/* make files read-only */
27332788Speter#define	CVSREAD_DFLT	0		/* writable files by default */
27417721Speter
27525866Speter#define	CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
27625866Speter
27725839Speter#define	TMPDIR_ENV	"TMPDIR"	/* Temporary directory */
27825839Speter
27917721Speter#define	EDITOR1_ENV	"CVSEDITOR"	/* which editor to use */
28017721Speter#define	EDITOR2_ENV	"VISUAL"	/* which editor to use */
28117721Speter#define	EDITOR3_ENV	"EDITOR"	/* which editor to use */
28217721Speter
28317721Speter#define	CVSROOT_ENV	"CVSROOT"	/* source directory root */
284175267Sobrien/* Define CVSROOT_DFLT to a fallback value for CVSROOT.
285175267Sobrien *
286175267Sobrien#undef	CVSROOT_DFL
287175267Sobrien */
28817721Speter
28917721Speter#define	IGNORE_ENV	"CVSIGNORE"	/* More files to ignore */
29017721Speter#define WRAPPER_ENV     "CVSWRAPPERS"   /* name of the wrapper file */
29117721Speter
29217721Speter#define	CVSUMASK_ENV	"CVSUMASK"	/* Effective umask for repository */
29317721Speter
29417721Speter/*
29517721Speter * If the beginning of the Repository matches the following string, strip it
29617721Speter * so that the output to the logfile does not contain a full pathname.
29717721Speter *
29817721Speter * If the CVSROOT environment variable is set, it overrides this define.
29917721Speter */
30017721Speter#define	REPOS_STRIP	"/master/"
30117721Speter
30225839Speter/* Large enough to hold DATEFORM.  Not an arbitrary limit as long as
30325839Speter   it is used for that purpose, and not to hold a string from the
30425839Speter   command line, the client, etc.  */
30525839Speter#define MAXDATELEN	50
30617721Speter
30725839Speter/* The type of an entnode.  */
30825839Speterenum ent_type
30925839Speter{
31025839Speter    ENT_FILE, ENT_SUBDIR
31125839Speter};
31225839Speter
31317721Speter/* structure of a entry record */
31417721Speterstruct entnode
31517721Speter{
31625839Speter    enum ent_type type;
31717721Speter    char *user;
31817721Speter    char *version;
31932788Speter
32032788Speter    /* Timestamp, or "" if none (never NULL).  */
32117721Speter    char *timestamp;
32232788Speter
32332788Speter    /* Keyword expansion options, or "" if none (never NULL).  */
32417721Speter    char *options;
32532788Speter
32617721Speter    char *tag;
32717721Speter    char *date;
32817721Speter    char *conflict;
32917721Speter};
33017721Spetertypedef struct entnode Entnode;
33117721Speter
33217721Speter/* The type of request that is being done in do_module() */
33317721Speterenum mtype
33417721Speter{
33581407Speter    CHECKOUT, TAG, PATCH, EXPORT, MISC
33617721Speter};
33717721Speter
33817721Speter/*
33917721Speter * structure used for list-private storage by Entries_Open() and
34025839Speter * Version_TS() and Find_Directories().
34117721Speter */
34217721Speterstruct stickydirtag
34317721Speter{
34425839Speter    /* These fields pass sticky tag information from Entries_Open() to
34525839Speter       Version_TS().  */
34617721Speter    int aflag;
34717721Speter    char *tag;
34817721Speter    char *date;
34925839Speter    int nonbranch;
35025839Speter
35125839Speter    /* This field is set by Entries_Open() if there was subdirectory
35225839Speter       information; Find_Directories() uses it to see whether it needs
35325839Speter       to scan the directory itself.  */
35425839Speter    int subdirs;
35517721Speter};
35617721Speter
35717721Speter/* Flags for find_{names,dirs} routines */
35817721Speter#define W_LOCAL			0x01	/* look for files locally */
35917721Speter#define W_REPOS			0x02	/* look for files in the repository */
36017721Speter#define W_ATTIC			0x04	/* look for files in the attic */
36117721Speter
36217721Speter/* Flags for return values of direnter procs for the recursion processor */
36317721Speterenum direnter_type
36417721Speter{
36517721Speter    R_PROCESS = 1,			/* process files and maybe dirs */
36617721Speter    R_SKIP_FILES,			/* don't process files in this dir */
36717721Speter    R_SKIP_DIRS,			/* don't process sub-dirs */
36817721Speter    R_SKIP_ALL				/* don't process files or dirs */
36917721Speter};
37025839Speter#ifdef ENUMS_CAN_BE_TROUBLE
37125839Spetertypedef int Dtype;
37225839Speter#else
37317721Spetertypedef enum direnter_type Dtype;
37425839Speter#endif
37517721Speter
376107487Speter/* Recursion processor lock types */
377109660Speter#define CVS_LOCK_NONE	0
378109660Speter#define CVS_LOCK_READ	1
379109660Speter#define CVS_LOCK_WRITE	2
380107487Speter
381128269Speterextern const char *program_name, *program_path, *cvs_cmd_name;
38232788Speterextern char *Tmpdir, *Editor;
38317721Speterextern int cvsadmin_root;
38417721Speterextern char *CurDir;
38517721Speterextern int really_quiet, quiet;
38617721Speterextern int use_editor;
38717721Speterextern int cvswrite;
38817721Speterextern mode_t cvsumask;
38925847Speterextern char *RCS_citag;
39017721Speter
39125839Speter
39281407Speter
39354431Speter/* This global variable holds the global -d option.  It is NULL if -d
39454431Speter   was not used, which means that we must get the CVSroot information
39554431Speter   from the CVSROOT environment variable or from a CVS/Root file.  */
39654431Speterextern char *CVSroot_cmdline;
39754431Speter
39854431Speter/* These variables keep track of all of the CVSROOT directories that
39954431Speter   have been seen by the client and the current one of those selected.  */
40054431Speterextern List *root_directories;
40181407Speterextern cvsroot_t *current_parsed_root;
40254431Speter
40332788Speterextern char *emptydir_name PROTO ((void));
404102843Speterextern int safe_location PROTO ((char *));
40532788Speter
40617721Speterextern int trace;		/* Show all commands */
40717721Speterextern int noexec;		/* Don't modify disk anywhere */
40825866Speterextern int readonlyfs;		/* fail on all write locks; succeed all read locks */
40917721Speterextern int logoff;		/* Don't write history entry */
41036418Speterextern int require_real_user;	/* skip CVSROOT/passwd, /etc/passwd users only*/
41117721Speter
41244856Speterextern int top_level_admin;
41344856Speter
414102843Speter
415102843Speter#define LOGMSG_REREAD_NEVER 0	/* do_verify - never  reread message */
416102843Speter#define LOGMSG_REREAD_ALWAYS 1	/* do_verify - always reread message */
417102843Speter#define LOGMSG_REREAD_STAT 2	/* do_verify - reread message if changed */
418102843Speterextern int RereadLogAfterVerify;
419102843Speter
42054431Speter#ifdef CLIENT_SUPPORT
42154431Speterextern List *dirs_sent_to_server; /* used to decide which "Argument
42254431Speter				     xxx" commands to send to each
42354431Speter				     server in multiroot mode. */
42454431Speter#endif
42525839Speter
42617721Speterextern char hostname[];
42717721Speter
42817721Speter/* Externs that are included directly in the CVS sources */
42917721Speter
430128269Speterint RCS_merge PROTO((RCSNode *, const char *, const char *, const char *,
431128269Speter                     const char *, const char *));
43217721Speter/* Flags used by RCS_* functions.  See the description of the individual
43317721Speter   functions for which flags mean what for each function.  */
43425839Speter#define RCS_FLAGS_FORCE 1
43525839Speter#define RCS_FLAGS_DEAD 2
43625839Speter#define RCS_FLAGS_QUIET 4
43725839Speter#define RCS_FLAGS_MODTIME 8
43834467Speter#define RCS_FLAGS_KEEPFILE 16
439175267Sobrien#define RCS_FLAGS_USETIME 32
44017721Speter
441175267Sobrienextern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile, int diff_argc,
442175267Sobrien				    char *const *diff_argv,
443175267Sobrien				    const char *options,
444128269Speter				    const char *rev1, const char *rev1_cache,
445128269Speter                                    const char *rev2, const char *label1,
446128269Speter                                    const char *label2, const char *workfile));
447128269Speterextern int diff_exec PROTO ((const char *file1, const char *file2,
448128269Speter			     const char *label1, const char *label2,
449175267Sobrien			     int diff_argc, char *const *diff_argv,
450175267Sobrien			     const char *out));
45117721Speter
452128269Speter
45317721Speter#include "error.h"
45417721Speter
45517721SpeterDBM *open_module PROTO((void));
45617721SpeterFILE *open_file PROTO((const char *, const char *));
45725839SpeterList *Find_Directories PROTO((char *repository, int which, List *entries));
45817721Spetervoid Entries_Close PROTO((List *entries));
45934467SpeterList *Entries_Open PROTO ((int aflag, char *update_dir));
46025839Spetervoid Subdirs_Known PROTO((List *entries));
46125839Spetervoid Subdir_Register PROTO((List *, const char *, const char *));
46225839Spetervoid Subdir_Deregister PROTO((List *, const char *, const char *));
46332788Speter
46417721Speterchar *Make_Date PROTO((char *rawdate));
46544856Speterchar *date_from_time_t PROTO ((time_t));
46681407Spetervoid date_to_internet PROTO ((char *, const char *));
46781407Spetervoid date_to_tm PROTO ((struct tm *, const char *));
46881407Spetervoid tm_to_internet PROTO ((char *, const struct tm *));
46944856Speter
470128269Speterchar *Name_Repository PROTO((const char *dir, const char *update_dir));
471128269Speterconst char *Short_Repository PROTO((const char *repository));
47232788Spetervoid Sanitize_Repository_Name PROTO((char *repository));
47326804Speter
474128269Speterchar *previous_rev PROTO ((RCSNode *rcs, const char *rev));
475128269Speterchar *gca PROTO ((const char *rev1, const char *rev2));
47632788Speterextern void check_numeric PROTO ((const char *, int, char **));
477128269Speterchar *getcaller PROTO ((void));
478128269Speterchar *time_stamp PROTO ((const char *file));
47925839Speter
48054431Spetervoid *xmalloc PROTO((size_t bytes));
48117721Spetervoid *xrealloc PROTO((void *ptr, size_t bytes));
48225839Spetervoid expand_string PROTO ((char **, size_t *, size_t));
483102843Spetervoid xrealloc_and_strcat PROTO ((char **, size_t *, const char *));
48417721Speterchar *xstrdup PROTO((const char *str));
485128269Speterint strip_trailing_newlines PROTO((char *str));
486128269Speterint pathname_levels PROTO ((const char *path));
48725839Speter
488128269Spetertypedef	int (*CALLPROC)	PROTO((const char *repository, const char *value));
489128269Speterint Parse_Info PROTO((const char *infofile, const char *repository,
490128269Speter                      CALLPROC callproc, int all));
49132788Speterextern int parse_config PROTO ((char *));
49232788Speter
49317721Spetertypedef	RETSIGTYPE (*SIGCLEANUPPROC)	PROTO(());
49417721Speterint SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
49517721Speterint isdir PROTO((const char *file));
49617721Speterint isfile PROTO((const char *file));
49717721Speterint islink PROTO((const char *file));
49834467Speterint isdevice PROTO ((const char *));
49917721Speterint isreadable PROTO((const char *file));
50017721Speterint iswritable PROTO((const char *file));
50117721Speterint isaccessible PROTO((const char *file, const int mode));
50217721Speterint isabsolute PROTO((const char *filename));
503128269Speter#ifdef HAVE_READLINK
50434467Speterchar *xreadlink PROTO((const char *link));
505128269Speter#endif
506128269Speterchar *xresolvepath PROTO((const char *path));
507128269Speterconst char *last_component PROTO((const char *path));
50817721Speterchar *get_homedir PROTO ((void));
509107487Speterchar *strcat_filename_onto_homedir PROTO ((const char *, const char *));
51025839Speterchar *cvs_temp_name PROTO ((void));
51181407SpeterFILE *cvs_temp_file PROTO ((char **filename));
51225847Spetervoid parseopts PROTO ((const char *root));
51317721Speter
51417721Speterint numdots PROTO((const char *s));
51532788Speterchar *increment_revnum PROTO ((const char *));
51632788Speterint compare_revnums PROTO ((const char *, const char *));
51717721Speterint unlink_file PROTO((const char *f));
51817721Speterint unlink_file_dir PROTO((const char *f));
519128269Speter
520128269Speter
521128269Speter
522128269Speter/* This is the structure that the recursion processor passes to the
523128269Speter   fileproc to tell it about a particular file.  */
524128269Speterstruct file_info
525128269Speter{
526128269Speter    /* Name of the file, without any directory component.  */
527128269Speter    const char *file;
528128269Speter
529128269Speter    /* Name of the directory we are in, relative to the directory in
530128269Speter       which this command was issued.  We have cd'd to this directory
531128269Speter       (either in the working directory or in the repository, depending
532128269Speter       on which sort of recursion we are doing).  If we are in the directory
533128269Speter       in which the command was issued, this is "".  */
534128269Speter    const char *update_dir;
535128269Speter
536128269Speter    /* update_dir and file put together, with a slash between them as
537128269Speter       necessary.  This is the proper way to refer to the file in user
538128269Speter       messages.  */
539128269Speter    const char *fullname;
540128269Speter
541128269Speter    /* Name of the directory corresponding to the repository which contains
542128269Speter       this file.  */
543128269Speter    const char *repository;
544128269Speter
545128269Speter    /* The pre-parsed entries for this directory.  */
546128269Speter    List *entries;
547128269Speter
548128269Speter    RCSNode *rcs;
549128269Speter};
550128269Speter
551128269Speter
552128269Speter
55317721Speterint update PROTO((int argc, char *argv[]));
554128269Speter/* The only place this is currently used outside of update.c is add.c.
555128269Speter * Restricting its use to update.c seems to be in the best interest of
556128269Speter * modularity, but I can't think of a good way to get an update of a
557128269Speter * resurrected file done and print the fact otherwise.
558128269Speter */
559128269Spetervoid write_letter PROTO ((struct file_info *finfo, int letter));
56017721Speterint xcmp PROTO((const char *file1, const char *file2));
56117721Speterint yesno PROTO((void));
56217721Spetervoid *valloc PROTO((size_t bytes));
56317721Spetertime_t get_date PROTO((char *date, struct timeb *now));
564128269Speterextern int Create_Admin PROTO ((const char *dir, const char *update_dir,
565128269Speter                                const char *repository, const char *tag,
566128269Speter                                const char *date,
567128269Speter                                int nonbranch, int warn, int dotemplate));
568128269Speterextern int expand_at_signs PROTO ((const char *, off_t, FILE *));
569128269Speter
57025839Speter/* Locking subsystem (implemented in lock.c).  */
57125839Speter
57225839Speterint Reader_Lock PROTO((char *xrepository));
57317721Spetervoid Lock_Cleanup PROTO((void));
57417721Speter
57517721Speter/* Writelock an entire subtree, well the part specified by ARGC, ARGV, LOCAL,
57617721Speter   and AFLAG, anyway.  */
57781407Spetervoid lock_tree_for_write PROTO ((int argc, char **argv, int local, int which,
57881407Speter				 int aflag));
57917721Speter
58025839Speter/* See lock.c for description.  */
58125839Speterextern void lock_dir_for_write PROTO ((char *));
58254431Speter
583175267Sobrien/* Get a write lock for the history file.  */
584175267Sobrienint history_lock PROTO ((const char *));
585175267Sobrienvoid clear_history_lock PROTO ((void));
586175267Sobrien
587175267Sobrien/* Get a write lock for the val-tags file.  */
588175267Sobrienint val_tags_lock PROTO ((const char *));
589175267Sobrienvoid clear_val_tags_lock PROTO ((void));
590175267Sobrien
59154431Speter/* LockDir setting from CVSROOT/config.  */
59254431Speterextern char *lock_dir;
593128269Speter
594128269Spetervoid Scratch_Entry PROTO((List * list, const char *fname));
59525839Spetervoid ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
596128269Spetervoid WriteTag PROTO ((const char *dir, const char *tag, const char *date,
597128269Speter                      int nonbranch, const char *update_dir,
598128269Speter                      const char *repository));
599128273Spetervoid WriteTemplate PROTO ((const char *dir, const char *update_dir));
60017721Spetervoid cat_module PROTO((int status));
60117721Spetervoid check_entries PROTO((char *dir));
60217721Spetervoid close_module PROTO((DBM * db));
60317721Spetervoid copy_file PROTO((const char *from, const char *to));
60466528Spetervoid fperrmsg PROTO((FILE * fp, int status, int errnum, char *message,...));
60517721Spetervoid free_names PROTO((int *pargc, char *argv[]));
60617721Speter
60717721Speterextern int ign_name PROTO ((char *name));
60817721Spetervoid ign_add PROTO((char *ign, int hold));
60917721Spetervoid ign_add_file PROTO((char *file, int hold));
61017721Spetervoid ign_setup PROTO((void));
61117721Spetervoid ign_dir_add PROTO((char *name));
612128269Speterint ignore_directory PROTO((const char *name));
613128269Spetertypedef void (*Ignore_proc) PROTO ((const char *, const char *));
614128269Speterextern void ignore_files PROTO ((List *, List *, const char *, Ignore_proc));
61517721Speterextern int ign_inhibit_server;
61617721Speter
61717721Speter#include "update.h"
61817721Speter
61932788Spetervoid line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars));
62017721Spetervoid make_directories PROTO((const char *name));
62117721Spetervoid make_directory PROTO((const char *name));
622128269Speterextern int mkdir_if_needed PROTO ((const char *name));
62317721Spetervoid rename_file PROTO((const char *from, const char *to));
62417721Speter/* Expand wildcards in each element of (ARGC,ARGV).  This is according to the
62517721Speter   files which exist in the current directory, and accordingly to OS-specific
62617721Speter   conventions regarding wildcard syntax.  It might be desirable to change the
62717721Speter   former in the future (e.g. "cvs status *.h" including files which don't exist
62817721Speter   in the working directory).  The result is placed in *PARGC and *PARGV;
62917721Speter   the *PARGV array itself and all the strings it contains are newly
63017721Speter   malloc'd.  It is OK to call it with PARGC == &ARGC or PARGV == &ARGV.  */
63117721Speterextern void expand_wild PROTO ((int argc, char **argv,
63217721Speter                                int *pargc, char ***pargv));
63317721Speter
63425839Speter#ifdef SERVER_SUPPORT
635128269Speterextern int cvs_casecmp PROTO ((const char *, const char *));
63625839Speter#endif
63725839Speter
63817721Spetervoid strip_trailing_slashes PROTO((char *path));
63917721Spetervoid update_delproc PROTO((Node * p));
64017721Spetervoid usage PROTO((const char *const *cpp));
641128269Spetervoid xchmod PROTO((const char *fname, int writable));
64217721Speterchar *xgetwd PROTO((void));
64317721SpeterList *Find_Names PROTO((char *repository, int which, int aflag,
644128269Speter                        List **optentries));
645128269Spetervoid Register PROTO((List * list, const char *fname, const char *vn,
646128269Speter                     const char *ts, const char *options, const char *tag,
647128269Speter                     const char *date, const char *ts_conflict));
648128269Spetervoid Update_Logfile PROTO((const char *repository, const char *xmessage,
649128269Speter                           FILE * xlogfp, List * xchanges));
650128269Spetervoid do_editor PROTO((const char *dir, char **messagep,
651128269Speter		      const char *repository, List * changes));
65217721Speter
653128269Spetervoid do_verify PROTO((char **messagep, const char *repository));
65425839Speter
65566528Spetertypedef	int (*CALLBACKPROC)	PROTO((int argc, char *argv[], char *where,
65632788Speter	char *mwhere, char *mfile, int shorten, int local_specified,
65717721Speter	char *omodule, char *msg));
65817721Speter
65925839Spetertypedef	int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
66025839Spetertypedef	int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
661128269Speter                                     const char *repository,
662128269Speter                                     const char *update_dir,
663128269Speter                                     List *entries));
664128269Spetertypedef	Dtype (*DIRENTPROC) PROTO ((void *callerdat, const char *dir,
665128269Speter				    const char *repos, const char *update_dir,
66625839Speter				    List *entries));
667128269Spetertypedef	int (*DIRLEAVEPROC) PROTO ((void *callerdat, const char *dir, int err,
668128269Speter				    const char *update_dir, List *entries));
66917721Speter
67017721Speterextern int mkmodules PROTO ((char *dir));
67117721Speterextern int init PROTO ((int argc, char **argv));
67217721Speter
67317721Speterint do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
67417721Speter		CALLBACKPROC callback_proc, char *where, int shorten,
67581407Speter		int local_specified, int run_module_prog, int build_dirs,
67681407Speter		char *extra_arg));
677128269Spetervoid history_write PROTO((int type, const char *update_dir, const char *revs,
678128269Speter                          const char *name, const char *repository));
67917721Speterint start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
68017721Speter		     DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
68125839Speter		     void *callerdat,
68217721Speter		     int argc, char *argv[], int local, int which,
683107487Speter		     int aflag, int locktype, char *update_preload,
684128269Speter		     int dosrcs, char *repository));
68517721Spetervoid SIG_beginCrSect PROTO((void));
68617721Spetervoid SIG_endCrSect PROTO((void));
68766528Speterint SIG_inCrSect PROTO((void));
688128269Spetervoid read_cvsrc PROTO((int *argc, char ***argv, const char *cmdname));
68917721Speter
690128269Speterchar *make_message_rcslegal PROTO((const char *message));
69132788Speterextern int file_has_markers PROTO ((const struct file_info *));
69232788Speterextern void get_file PROTO ((const char *, const char *, const char *,
69332788Speter			     char **, size_t *, size_t *));
69481407Speterextern char *shell_escape PROTO((char *buf, const char *str));
69581407Speterchar *backup_file PROTO((const char *file, const char *suffix));
69654431Speterextern void resolve_symlink PROTO ((char **filename));
69781407Spetervoid sleep_past PROTO ((time_t desttime));
69817721Speter
69917721Speter/* flags for run_exec(), the fast system() for CVS */
700128269Speter#define	RUN_NORMAL            0x0000    /* no special behaviour */
701128269Speter#define	RUN_COMBINED          0x0001    /* stdout is duped to stderr */
702128269Speter#define	RUN_REALLY            0x0002    /* do the exec, even if noexec is on */
703128269Speter#define	RUN_STDOUT_APPEND     0x0004    /* append to stdout, don't truncate */
704128269Speter#define	RUN_STDERR_APPEND     0x0008    /* append to stderr, don't truncate */
705128269Speter#define	RUN_SIGIGNORE         0x0010    /* ignore interrupts for command */
706128269Speter#define	RUN_TTY               (char *)0 /* for the benefit of lint */
70717721Speter
708175267Sobrienvoid run_add_arg_p PROTO ((int *, size_t *, char ***, const char *s));
709175267Sobrienvoid run_arg_free_p PROTO ((int, char **));
71017721Spetervoid run_arg PROTO((const char *s));
71117721Spetervoid run_print PROTO((FILE * fp));
71232788Spetervoid run_setup PROTO ((const char *prog));
71332788Speterint run_exec PROTO((const char *stin, const char *stout, const char *sterr,
71432788Speter		    int flags));
71517721Speter
71617721Speter/* other similar-minded stuff from run.c.  */
71717721SpeterFILE *run_popen PROTO((const char *, const char *));
718175267Sobrienint piped_child PROTO((const char **, int *, int *, int));
71917721Spetervoid close_on_exec PROTO((int));
72017721Speter
72117721Speterpid_t waitpid PROTO((pid_t, int *, int));
72217721Speter
72325839Speter/*
72425839Speter * a struct vers_ts contains all the information about a file including the
72525839Speter * user and rcs file names, and the version checked out and the head.
72625839Speter *
72725839Speter * this is usually obtained from a call to Version_TS which takes a
72825839Speter * tag argument for the RCS file if desired
72925839Speter */
73025839Speterstruct vers_ts
73125839Speter{
73225839Speter    /* rcs version user file derives from, from CVS/Entries.
73332788Speter       It can have the following special values:
73432788Speter
73532788Speter       NULL = file is not mentioned in Entries (this is also used for a
73632788Speter	      directory).
73732788Speter       "" = ILLEGAL!  The comment used to say that it meant "no user file"
73832788Speter	    but as far as I know CVS didn't actually use it that way.
73932788Speter	    Note that according to cvs.texinfo, "" is not legal in the
74032788Speter	    Entries file.
74132788Speter       0 = user file is new
74232788Speter       -vers = user file to be removed.  */
74325839Speter    char *vn_user;
74425839Speter
74525839Speter    /* Numeric revision number corresponding to ->vn_tag (->vn_tag
74625839Speter       will often be symbolic).  */
74725839Speter    char *vn_rcs;
74825839Speter    /* If ->tag is a simple tag in the RCS file--a tag which really
74925839Speter       exists which is not a magic revision--and if ->date is NULL,
75025839Speter       then this is a copy of ->tag.  Otherwise, it is a copy of
75125839Speter       ->vn_rcs.  */
75225839Speter    char *vn_tag;
75325839Speter
75425839Speter    /* This is the timestamp from stating the file in the working directory.
75525839Speter       It is NULL if there is no file in the working directory.  It is
75625839Speter       "Is-modified" if we know the file is modified but don't have its
75725839Speter       contents.  */
75825839Speter    char *ts_user;
75925839Speter    /* Timestamp from CVS/Entries.  For the server, ts_user and ts_rcs
76025839Speter       are computed in a slightly different way, but the fact remains that
76125839Speter       if they are equal the file in the working directory is unmodified
76225839Speter       and if they differ it is modified.  */
76325839Speter    char *ts_rcs;
76425839Speter
76532788Speter    /* Options from CVS/Entries (keyword expansion), malloc'd.  If none,
76632788Speter       then it is an empty string (never NULL).  */
76725839Speter    char *options;
76825839Speter
76925839Speter    /* If non-NULL, there was a conflict (or merely a merge?  See merge_file)
77025839Speter       and the time stamp in this field is the time stamp of the working
77125839Speter       directory file which was created with the conflict markers in it.
77225839Speter       This is from CVS/Entries.  */
77325839Speter    char *ts_conflict;
77425839Speter
77525839Speter    /* Tag specified on the command line, or if none, tag stored in
77625839Speter       CVS/Entries.  */
77725839Speter    char *tag;
77825839Speter    /* Date specified on the command line, or if none, date stored in
77925839Speter       CVS/Entries.  */
78025839Speter    char *date;
78125839Speter    /* If this is 1, then tag is not a branch tag.  If this is 0, then
78225839Speter       tag may or may not be a branch tag.  */
78325839Speter    int nonbranch;
78425839Speter
78525839Speter    /* Pointer to entries file node  */
78625839Speter    Entnode *entdata;
78725839Speter
78825839Speter    /* Pointer to parsed src file info */
78925839Speter    RCSNode *srcfile;
79025839Speter};
79125839Spetertypedef struct vers_ts Vers_TS;
79225839Speter
79325839SpeterVers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
79425839Speter			    char *date, int force_tag_match,
79525839Speter			    int set_time));
79625839Spetervoid freevers_ts PROTO ((Vers_TS ** versp));
79725839Speter
79825839Speter/* Miscellaneous CVS infrastructure which layers on top of the recursion
79925839Speter   processor (for example, needs struct file_info).  */
80025839Speter
801128269Speterint Checkin PROTO ((int type, struct file_info *finfo, char *rev,
80225839Speter		    char *tag, char *options, char *message));
80325839Speterint No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
80434467Speter/* TODO: can the finfo argument to special_file_mismatch be changed? -twp */
80534467Speterint special_file_mismatch PROTO ((struct file_info *finfo,
80634467Speter				  char *rev1, char *rev2));
80725839Speter
80832788Speter/* CVSADM_BASEREV stuff, from entries.c.  */
80932788Speterextern char *base_get PROTO ((struct file_info *));
81032788Speterextern void base_register PROTO ((struct file_info *, char *));
81132788Speterextern void base_deregister PROTO ((struct file_info *));
81232788Speter
81325839Speter/*
81425839Speter * defines for Classify_File() to determine the current state of a file.
81525839Speter * These are also used as types in the data field for the list we make for
81625839Speter * Update_Logfile in commit, import, and add.
81725839Speter */
81825839Speterenum classify_type
81925839Speter{
82025839Speter    T_UNKNOWN = 1,			/* no old-style analog existed	 */
82125839Speter    T_CONFLICT,				/* C (conflict) list		 */
82225839Speter    T_NEEDS_MERGE,			/* G (needs merging) list	 */
82325839Speter    T_MODIFIED,				/* M (needs checked in) list 	 */
82425839Speter    T_CHECKOUT,				/* O (needs checkout) list	 */
82525839Speter    T_ADDED,				/* A (added file) list		 */
82625839Speter    T_REMOVED,				/* R (removed file) list	 */
82725839Speter    T_REMOVE_ENTRY,			/* W (removed entry) list	 */
82825839Speter    T_UPTODATE,				/* File is up-to-date		 */
82925839Speter    T_PATCH,				/* P Like C, but can patch	 */
83025839Speter    T_TITLE				/* title for node type 		 */
83125839Speter};
83225839Spetertypedef enum classify_type Ctype;
83325839Speter
83425839SpeterCtype Classify_File PROTO
83525839Speter    ((struct file_info *finfo, char *tag, char *date, char *options,
83625839Speter      int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
83725839Speter
83825839Speter/*
83925839Speter * structure used for list nodes passed to Update_Logfile() and
84025839Speter * do_editor().
84125839Speter */
84225839Speterstruct logfile_info
84325839Speter{
84425839Speter  enum classify_type type;
84525839Speter  char *tag;
84625839Speter  char *rev_old;		/* rev number before a commit/modify,
84725839Speter				   NULL for add or import */
84825839Speter  char *rev_new;		/* rev number after a commit/modify,
84925839Speter				   add, or import, NULL for remove */
85025839Speter};
85125839Speter
85217721Speter/* Wrappers.  */
85317721Speter
85417721Spetertypedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
85525839Spetertypedef enum {
85625839Speter    /* -t and -f wrapper options.  Treating directories as single files.  */
85725839Speter    WRAP_TOCVS,
85825839Speter    WRAP_FROMCVS,
85925839Speter    /* -k wrapper option.  Default keyword expansion options.  */
86025839Speter    WRAP_RCSOPTION
86125839Speter} WrapMergeHas;
86217721Speter
86317721Spetervoid  wrap_setup PROTO((void));
86417721Speterint   wrap_name_has PROTO((const char *name,WrapMergeHas has));
86525839Speterchar *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
86617721Speterchar *wrap_tocvs_process_file PROTO((const char *fileName));
86717721Speterint   wrap_merge_is_copy PROTO((const char *fileName));
86825839Spetervoid wrap_fromcvs_process_file PROTO ((const char *fileName));
86917721Spetervoid wrap_add_file PROTO((const char *file,int temp));
87017721Spetervoid wrap_add PROTO((char *line,int temp));
87125839Spetervoid wrap_send PROTO ((void));
87232899Speter#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
87332899Spetervoid wrap_unparse_rcs_options PROTO ((char **, int));
87432899Speter#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
875128269Speter
87617721Speter/* Pathname expansion */
877128269Speterchar *expand_path PROTO((const char *name, const char *file, int line));
87817721Speter
87917721Speter/* User variables.  */
88017721Speterextern List *variable_list;
88117721Speter
88217721Speterextern void variable_set PROTO ((char *nameval));
883128269Speter
88417721Speterint watch PROTO ((int argc, char **argv));
88517721Speterint edit PROTO ((int argc, char **argv));
88617721Speterint unedit PROTO ((int argc, char **argv));
88717721Speterint editors PROTO ((int argc, char **argv));
88817721Speterint watchers PROTO ((int argc, char **argv));
88917721Speterextern int annotate PROTO ((int argc, char **argv));
89025839Speterextern int add PROTO ((int argc, char **argv));
89125839Speterextern int admin PROTO ((int argc, char **argv));
89225839Speterextern int checkout PROTO ((int argc, char **argv));
89325839Speterextern int commit PROTO ((int argc, char **argv));
89425839Speterextern int diff PROTO ((int argc, char **argv));
89525839Speterextern int history PROTO ((int argc, char **argv));
89625839Speterextern int import PROTO ((int argc, char **argv));
89725839Speterextern int cvslog PROTO ((int argc, char **argv));
89825839Speter#ifdef AUTH_CLIENT_SUPPORT
899107487Speter/* Some systems (namely Mac OS X) have conflicting definitions for these
900107487Speter * functions.  Avoid them.
901107487Speter */
902107487Speter#ifdef HAVE_LOGIN
903107487Speter# define login		cvs_login
904107487Speter#endif /* HAVE_LOGIN */
905107487Speter#ifdef HAVE_LOGOUT
906107487Speter# define logout		cvs_logout
907107487Speter#endif /* HAVE_LOGOUT */
90825839Speterextern int login PROTO((int argc, char **argv));
909107487Speterextern int logout PROTO((int argc, char **argv));
91025839Speter#endif /* AUTH_CLIENT_SUPPORT */
91125839Speterextern int patch PROTO((int argc, char **argv));
91225839Speterextern int release PROTO((int argc, char **argv));
91325839Speterextern int cvsremove PROTO((int argc, char **argv));
91425839Speterextern int rtag PROTO((int argc, char **argv));
91544856Speterextern int cvsstatus PROTO((int argc, char **argv));
91625839Speterextern int cvstag PROTO((int argc, char **argv));
91766528Speterextern int version PROTO((int argc, char **argv));
91817721Speter
91925839Speterextern unsigned long int lookup_command_attribute PROTO((char *));
92025839Speter
92117721Speter#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
92217721Speterchar *scramble PROTO ((char *str));
92317721Speterchar *descramble PROTO ((char *str));
92417721Speter#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
92517721Speter
92625839Speter#ifdef AUTH_CLIENT_SUPPORT
92725839Speterchar *get_cvs_password PROTO((void));
928177395Sobrienvoid free_cvs_password PROTO((char *str));
92981407Speterint get_cvs_port_number PROTO((const cvsroot_t *root));
93081407Speterchar *normalize_cvsroot PROTO((const cvsroot_t *root));
93125839Speter#endif /* AUTH_CLIENT_SUPPORT */
93225839Speter
93317721Speterextern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
93425839Speterextern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
93525839Speter					 char *));
93617721Speter
93766528Speter#include "server.h"
93866528Speter
93932788Speter/* From server.c and documented there.  */
94025839Speterextern void cvs_output PROTO ((const char *, size_t));
94132788Speterextern void cvs_output_binary PROTO ((char *, size_t));
94225839Speterextern void cvs_outerr PROTO ((const char *, size_t));
94325839Speterextern void cvs_flusherr PROTO ((void));
94425839Speterextern void cvs_flushout PROTO ((void));
945128269Speterextern void cvs_output_tagged PROTO ((const char *, const char *));
946