#include "config.h"
#include "options.h"
#ifdef __STDC__
#define PTR void *
#else
#define PTR char *
#endif
#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif
#include <stdio.h>
#ifdef USE_OWN_POPEN
#include "popen.h"
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
extern void exit ();
extern char *getenv();
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef SERVER_SUPPORT
char *strerror ();
#endif
#include <fnmatch.h>
#include <ctype.h>
#include <pwd.h>
#include <signal.h>
#ifdef HAVE_ERRNO_H
#include <errno.h>
#else
#ifndef errno
extern int errno;
#endif
#endif
#include "system.h"
#include "hash.h"
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
#include "client.h"
#endif
#ifdef MY_NDBM
#include "myndbm.h"
#else
#include <ndbm.h>
#endif
#include "regex.h"
#include "getopt.h"
#include "wait.h"
#include "rcs.h"
#ifndef PATH_MAX
#ifdef MAXPATHLEN
#define PATH_MAX MAXPATHLEN+2
#else
#define PATH_MAX 1024+2
#endif
#endif
#ifdef USE_VMS_FILENAMES
#define CVSADM "CVS"
#define CVSADM_ENT "CVS/Entries."
#define CVSADM_ENTBAK "CVS/Entries.Backup"
#define CVSADM_ENTLOG "CVS/Entries.Log"
#define CVSADM_ENTSTAT "CVS/Entries.Static"
#define CVSADM_REP "CVS/Repository."
#define CVSADM_ROOT "CVS/Root."
#define CVSADM_CIPROG "CVS/Checkin.prog"
#define CVSADM_UPROG "CVS/Update.prog"
#define CVSADM_TAG "CVS/Tag."
#define CVSADM_NOTIFY "CVS/Notify."
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
#define CVSADM_BASE "CVS/Base"
#define CVSADM_BASEREV "CVS/Baserev."
#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
#define CVSADM_TEMPLATE "CVS/Template."
#else
#define CVSADM "CVS"
#define CVSADM_ENT "CVS/Entries"
#define CVSADM_ENTBAK "CVS/Entries.Backup"
#define CVSADM_ENTLOG "CVS/Entries.Log"
#define CVSADM_ENTSTAT "CVS/Entries.Static"
#define CVSADM_REP "CVS/Repository"
#define CVSADM_ROOT "CVS/Root"
#define CVSADM_CIPROG "CVS/Checkin.prog"
#define CVSADM_UPROG "CVS/Update.prog"
#define CVSADM_TAG "CVS/Tag"
#define CVSADM_NOTIFY "CVS/Notify"
#define CVSADM_NOTIFYTMP "CVS/Notify.tmp"
#define CVSADM_BASE "CVS/Base"
#define CVSADM_BASEREV "CVS/Baserev"
#define CVSADM_BASEREVTMP "CVS/Baserev.tmp"
#define CVSADM_TEMPLATE "CVS/Template"
#endif
#define CVSREP "CVS"
#define CVSROOTADM "CVSROOT"
#define CVSROOTADM_MODULES "modules"
#define CVSROOTADM_LOGINFO "loginfo"
#define CVSROOTADM_RCSINFO "rcsinfo"
#define CVSROOTADM_COMMITINFO "commitinfo"
#define CVSROOTADM_TAGINFO "taginfo"
#define CVSROOTADM_EDITINFO "editinfo"
#define CVSROOTADM_VERIFYMSG "verifymsg"
#define CVSROOTADM_HISTORY "history"
#define CVSROOTADM_VALTAGS "val-tags"
#define CVSROOTADM_IGNORE "cvsignore"
#define CVSROOTADM_CHECKOUTLIST "checkoutlist"
#define CVSROOTADM_WRAPPER "cvswrappers"
#define CVSROOTADM_NOTIFY "notify"
#define CVSROOTADM_USERS "users"
#define CVSROOTADM_READERS "readers"
#define CVSROOTADM_WRITERS "writers"
#define CVSROOTADM_PASSWD "passwd"
#define CVSROOTADM_CONFIG "config"
#define CVSNULLREPOS "Emptydir"
#define CVSATTIC "Attic"
#define CVSLCK "#cvs.lock"
#define CVSRFL "#cvs.rfl"
#define CVSWFL "#cvs.wfl"
#define CVSRFLPAT "#cvs.rfl.*"
#define CVSEXT_LOG ",t"
#define CVSPREFIX ",,"
#define CVSDOTIGNORE ".cvsignore"
#define CVSDOTWRAPPER ".cvswrappers"
#ifdef WRAPPERS_USE_TAR_FOR_TRANSFER
#define CVSWRAPPERTMP "#cvs.wrap-tmp"
#endif
#define CVS_CMD_IGNORE_ADMROOT 1
#define CVS_CMD_USES_WORK_DIR 2
#define CVS_CMD_MODIFIES_REPOSITORY 4
#define CVSEDITPREFIX "CVS: "
#define CVSEDITPREFIXLEN 4
#define CVSLCKAGE (60*60)
#define CVSLCKSLEEP 30
#define CVSBRANCH "1.1.1"
#ifdef USE_VMS_FILENAMES
#define BAKPREFIX "_$"
#define DEVNULL "NLA0:"
#else
#define BAKPREFIX ".#"
#ifndef DEVNULL
#define DEVNULL "/dev/null"
#endif
#endif
#define TAG_HEAD "HEAD"
#define TAG_BASE "BASE"
#define CVSREAD_ENV "CVSREAD"
#define CVSREAD_DFLT 0
#define TMPDIR_ENV "TMPDIR"
#define EDITOR1_ENV "CVSEDITOR"
#define EDITOR2_ENV "VISUAL"
#define EDITOR3_ENV "EDITOR"
#define CVSROOT_ENV "CVSROOT"
#define CVSROOT_DFLT NULL
#define IGNORE_ENV "CVSIGNORE"
#define WRAPPER_ENV "CVSWRAPPERS"
#define CVSUMASK_ENV "CVSUMASK"
#define REPOS_STRIP "/master/"
#define MAXDATELEN 50
enum ent_type
{
ENT_FILE, ENT_SUBDIR
};
struct entnode
{
enum ent_type type;
char *user;
char *version;
char *timestamp;
char *options;
char *tag;
char *date;
char *conflict;
};
typedef struct entnode Entnode;
enum mtype
{
CHECKOUT, TAG, PATCH, EXPORT
};
struct stickydirtag
{
int aflag;
char *tag;
char *date;
int nonbranch;
int subdirs;
};
#define W_LOCAL 0x01
#define W_REPOS 0x02
#define W_ATTIC 0x04
enum direnter_type
{
R_PROCESS = 1,
R_SKIP_FILES,
R_SKIP_DIRS,
R_SKIP_ALL
};
#ifdef ENUMS_CAN_BE_TROUBLE
typedef int Dtype;
#else
typedef enum direnter_type Dtype;
#endif
extern char *program_name, *program_path, *command_name;
extern char *Tmpdir, *Editor;
extern int cvsadmin_root;
extern char *CurDir;
extern int really_quiet, quiet;
extern int use_editor;
extern int cvswrite;
extern mode_t cvsumask;
typedef enum {
local_method, server_method, pserver_method, kserver_method, gserver_method,
ext_method
} CVSmethod;
extern char *method_names[];
extern char *CVSroot_original;
extern int client_active;
extern CVSmethod CVSroot_method;
extern char *CVSroot_username;
extern char *CVSroot_hostname;
extern char *CVSroot_directory;
extern char *emptydir_name PROTO ((void));
extern int trace;
extern int noexec;
extern int logoff;
extern int top_level_admin;
#ifdef AUTH_SERVER_SUPPORT
extern char *Pserver_Repos;
#endif
extern char hostname[];
int RCS_merge PROTO((RCSNode *, char *, char *, char *, char *, char *));
#define RCS_FLAGS_FORCE 1
#define RCS_FLAGS_DEAD 2
#define RCS_FLAGS_QUIET 4
#define RCS_FLAGS_MODTIME 8
#define RCS_FLAGS_KEEPFILE 16
extern int RCS_exec_rcsdiff PROTO ((RCSNode *rcsfile,
char *opts, char *options,
char *rev1, char *rev2,
char *label1, char *label2,
char *workfile));
extern int diff_exec PROTO ((char *file1, char *file2, char *options,
char *out));
extern int diff_execv PROTO ((char *file1, char *file2,
char *label1, char *label2,
char *options, char *out));
#include "error.h"
DBM *open_module PROTO((void));
FILE *open_file PROTO((const char *, const char *));
List *Find_Directories PROTO((char *repository, int which, List *entries));
void Entries_Close PROTO((List *entries));
List *Entries_Open PROTO ((int aflag, char *update_dir));
void Subdirs_Known PROTO((List *entries));
void Subdir_Register PROTO((List *, const char *, const char *));
void Subdir_Deregister PROTO((List *, const char *, const char *));
char *Make_Date PROTO((char *rawdate));
char *date_from_time_t PROTO ((time_t));
char *Name_Repository PROTO((char *dir, char *update_dir));
char *Short_Repository PROTO((char *repository));
void Sanitize_Repository_Name PROTO((char *repository));
char *Name_Root PROTO((char *dir, char *update_dir));
int parse_cvsroot PROTO((char *CVSroot));
void set_local_cvsroot PROTO((char *dir));
void Create_Root PROTO((char *dir, char *rootdir));
void root_allow_add PROTO ((char *));
void root_allow_free PROTO ((void));
int root_allow_ok PROTO ((char *));
char *gca PROTO((const char *rev1, const char *rev2));
extern void check_numeric PROTO ((const char *, int, char **));
char *getcaller PROTO((void));
char *time_stamp PROTO((char *file));
char *xmalloc PROTO((size_t bytes));
void *xrealloc PROTO((void *ptr, size_t bytes));
void expand_string PROTO ((char **, size_t *, size_t));
char *xstrdup PROTO((const char *str));
void strip_trailing_newlines PROTO((char *str));
int pathname_levels PROTO ((char *path));
typedef int (*CALLPROC) PROTO((char *repository, char *value));
int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
extern int parse_config PROTO ((char *));
typedef RETSIGTYPE (*SIGCLEANUPPROC) PROTO(());
int SIG_register PROTO((int sig, SIGCLEANUPPROC sigcleanup));
int isdir PROTO((const char *file));
int isfile PROTO((const char *file));
int islink PROTO((const char *file));
int isdevice PROTO ((const char *));
int isreadable PROTO((const char *file));
int iswritable PROTO((const char *file));
int isaccessible PROTO((const char *file, const int mode));
int isabsolute PROTO((const char *filename));
char *xreadlink PROTO((const char *link));
char *last_component PROTO((char *path));
char *get_homedir PROTO ((void));
char *cvs_temp_name PROTO ((void));
int numdots PROTO((const char *s));
char *increment_revnum PROTO ((const char *));
int compare_revnums PROTO ((const char *, const char *));
int unlink_file PROTO((const char *f));
int unlink_file_dir PROTO((const char *f));
int update PROTO((int argc, char *argv[]));
int xcmp PROTO((const char *file1, const char *file2));
int yesno PROTO((void));
void *valloc PROTO((size_t bytes));
time_t get_date PROTO((char *date, struct timeb *now));
extern int Create_Admin PROTO ((char *dir, char *update_dir,
char *repository, char *tag, char *date,
int nonbranch, int warn));
extern int expand_at_signs PROTO ((char *, off_t, FILE *));
int Reader_Lock PROTO((char *xrepository));
void Lock_Cleanup PROTO((void));
void lock_tree_for_write PROTO ((int argc, char **argv, int local, int aflag));
extern void lock_dir_for_write PROTO ((char *));
void Scratch_Entry PROTO((List * list, char *fname));
void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
void WriteTag PROTO ((char *dir, char *tag, char *date, int nonbranch,
char *update_dir, char *repository));
void cat_module PROTO((int status));
void check_entries PROTO((char *dir));
void close_module PROTO((DBM * db));
void copy_file PROTO((const char *from, const char *to));
void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
void free_names PROTO((int *pargc, char *argv[]));
extern int ign_name PROTO ((char *name));
void ign_add PROTO((char *ign, int hold));
void ign_add_file PROTO((char *file, int hold));
void ign_setup PROTO((void));
void ign_dir_add PROTO((char *name));
int ignore_directory PROTO((char *name));
typedef void (*Ignore_proc) PROTO ((char *, char *));
extern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
extern int ign_inhibit_server;
extern int ign_case;
#include "update.h"
void line2argv PROTO ((int *pargc, char ***argv, char *line, char *sepchars));
void make_directories PROTO((const char *name));
void make_directory PROTO((const char *name));
extern int mkdir_if_needed PROTO ((char *name));
void rename_file PROTO((const char *from, const char *to));
extern void expand_wild PROTO ((int argc, char **argv,
int *pargc, char ***pargv));
#ifdef SERVER_SUPPORT
extern int cvs_casecmp PROTO ((char *, char *));
extern int fopen_case PROTO ((char *, char *, FILE **, char **));
#endif
void strip_trailing_slashes PROTO((char *path));
void update_delproc PROTO((Node * p));
void usage PROTO((const char *const *cpp));
void xchmod PROTO((char *fname, int writable));
char *xgetwd PROTO((void));
List *Find_Names PROTO((char *repository, int which, int aflag,
List ** optentries));
void Register PROTO((List * list, char *fname, char *vn, char *ts,
char *options, char *tag, char *date, char *ts_conflict));
void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
List * xchanges));
void do_editor PROTO((char *dir, char **messagep,
char *repository, List * changes));
void do_verify PROTO((char *message, char *repository));
typedef int (*CALLBACKPROC) PROTO((int *pargc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
char *omodule, char *msg));
struct file_info
{
char *file;
char *update_dir;
char *fullname;
char *repository;
List *entries;
RCSNode *rcs;
};
typedef int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
typedef int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
char *repository, char *update_dir,
List *entries));
typedef Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
char *repos, char *update_dir,
List *entries));
typedef int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
char *update_dir, List *entries));
extern int mkmodules PROTO ((char *dir));
extern int init PROTO ((int argc, char **argv));
int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
CALLBACKPROC callback_proc, char *where, int shorten,
int local_specified, int run_module_prog, char *extra_arg));
void history_write PROTO((int type, char *update_dir, char *revs, char *name,
char *repository));
int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
void *callerdat,
int argc, char *argv[], int local, int which,
int aflag, int readlock, char *update_preload,
int dosrcs));
void SIG_beginCrSect PROTO((void));
void SIG_endCrSect PROTO((void));
void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
char *make_message_rcslegal PROTO((char *message));
extern int file_has_markers PROTO ((const struct file_info *));
extern void get_file PROTO ((const char *, const char *, const char *,
char **, size_t *, size_t *));
#define RUN_NORMAL 0x0000
#define RUN_COMBINED 0x0001
#define RUN_REALLY 0x0002
#define RUN_STDOUT_APPEND 0x0004
#define RUN_STDERR_APPEND 0x0008
#define RUN_SIGIGNORE 0x0010
#define RUN_TTY (char *)0
void run_arg PROTO((const char *s));
void run_print PROTO((FILE * fp));
void run_setup PROTO ((const char *prog));
int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
int flags));
FILE *run_popen PROTO((const char *, const char *));
int piped_child PROTO((char **, int *, int *));
void close_on_exec PROTO((int));
int filter_stream_through_program PROTO((int, int, char **, pid_t *));
pid_t waitpid PROTO((pid_t, int *, int));
struct vers_ts
{
char *vn_user;
char *vn_rcs;
char *vn_tag;
char *ts_user;
char *ts_rcs;
char *options;
char *ts_conflict;
char *tag;
char *date;
int nonbranch;
Entnode *entdata;
RCSNode *srcfile;
};
typedef struct vers_ts Vers_TS;
Vers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
char *date, int force_tag_match,
int set_time));
void freevers_ts PROTO ((Vers_TS ** versp));
int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
char *tag, char *options, char *message));
int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
int special_file_mismatch PROTO ((struct file_info *finfo,
char *rev1, char *rev2));
extern char *base_get PROTO ((struct file_info *));
extern void base_register PROTO ((struct file_info *, char *));
extern void base_deregister PROTO ((struct file_info *));
enum classify_type
{
T_UNKNOWN = 1,
T_CONFLICT,
T_NEEDS_MERGE,
T_MODIFIED,
T_CHECKOUT,
T_ADDED,
T_REMOVED,
T_REMOVE_ENTRY,
T_UPTODATE,
#ifdef SERVER_SUPPORT
T_PATCH,
#endif
T_TITLE
};
typedef enum classify_type Ctype;
Ctype Classify_File PROTO
((struct file_info *finfo, char *tag, char *date, char *options,
int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
struct logfile_info
{
enum classify_type type;
char *tag;
char *rev_old;
char *rev_new;
};
typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
typedef enum {
WRAP_TOCVS,
WRAP_FROMCVS,
WRAP_RCSOPTION
} WrapMergeHas;
void wrap_setup PROTO((void));
int wrap_name_has PROTO((const char *name,WrapMergeHas has));
char *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
char *wrap_tocvs_process_file PROTO((const char *fileName));
int wrap_merge_is_copy PROTO((const char *fileName));
void wrap_fromcvs_process_file PROTO ((const char *fileName));
void wrap_add_file PROTO((const char *file,int temp));
void wrap_add PROTO((char *line,int temp));
void wrap_send PROTO ((void));
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
void wrap_unparse_rcs_options PROTO ((char **, int));
#endif
char *expand_path PROTO((char *name, char *file, int line));
extern List *variable_list;
extern void variable_set PROTO ((char *nameval));
int watch PROTO ((int argc, char **argv));
int edit PROTO ((int argc, char **argv));
int unedit PROTO ((int argc, char **argv));
int editors PROTO ((int argc, char **argv));
int watchers PROTO ((int argc, char **argv));
extern int annotate PROTO ((int argc, char **argv));
extern int add PROTO ((int argc, char **argv));
extern int admin PROTO ((int argc, char **argv));
extern int checkout PROTO ((int argc, char **argv));
extern int commit PROTO ((int argc, char **argv));
extern int diff PROTO ((int argc, char **argv));
extern int history PROTO ((int argc, char **argv));
extern int import PROTO ((int argc, char **argv));
extern int cvslog PROTO ((int argc, char **argv));
#ifdef AUTH_CLIENT_SUPPORT
extern int login PROTO((int argc, char **argv));
int logout PROTO((int argc, char **argv));
#endif
extern int patch PROTO((int argc, char **argv));
extern int release PROTO((int argc, char **argv));
extern int cvsremove PROTO((int argc, char **argv));
extern int rtag PROTO((int argc, char **argv));
extern int cvsstatus PROTO((int argc, char **argv));
extern int cvstag PROTO((int argc, char **argv));
extern unsigned long int lookup_command_attribute PROTO((char *));
#if defined(AUTH_CLIENT_SUPPORT) || defined(AUTH_SERVER_SUPPORT)
char *scramble PROTO ((char *str));
char *descramble PROTO ((char *str));
#endif
#ifdef AUTH_CLIENT_SUPPORT
char *get_cvs_password PROTO((void));
#endif
extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
extern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
char *));
extern void cvs_output PROTO ((const char *, size_t));
extern void cvs_output_binary PROTO ((char *, size_t));
extern void cvs_outerr PROTO ((const char *, size_t));
extern void cvs_flusherr PROTO ((void));
extern void cvs_flushout PROTO ((void));
extern void cvs_output_tagged PROTO ((char *, char *));
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
#include "server.h"
#endif