summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r--contrib/cvs/src/NOTES60
-rw-r--r--contrib/cvs/src/README-rm-add31
-rw-r--r--contrib/cvs/src/buffer.c2
-rw-r--r--contrib/cvs/src/checkout.c17
-rw-r--r--contrib/cvs/src/client.c56
-rw-r--r--contrib/cvs/src/commit.c1
-rw-r--r--contrib/cvs/src/cvs.h13
-rwxr-xr-xcontrib/cvs/src/cvsbug.in2
-rw-r--r--contrib/cvs/src/diff.c53
-rw-r--r--contrib/cvs/src/entries.c69
-rw-r--r--contrib/cvs/src/filesubr.c4
-rw-r--r--contrib/cvs/src/import.c27
-rw-r--r--contrib/cvs/src/lock.c11
-rw-r--r--contrib/cvs/src/log.c13
-rw-r--r--contrib/cvs/src/login.c55
-rw-r--r--contrib/cvs/src/logmsg.c4
-rw-r--r--contrib/cvs/src/main.c102
-rw-r--r--contrib/cvs/src/mkmodules.c62
-rw-r--r--contrib/cvs/src/options.h.in200
-rw-r--r--contrib/cvs/src/parseinfo.c47
-rw-r--r--contrib/cvs/src/patch.c2
-rw-r--r--contrib/cvs/src/rcs.c615
-rw-r--r--contrib/cvs/src/rcs.h5
-rw-r--r--contrib/cvs/src/rcscmds.c2
-rw-r--r--contrib/cvs/src/recurse.c6
-rw-r--r--contrib/cvs/src/server.c61
-rw-r--r--contrib/cvs/src/stamp-h2.in1
-rw-r--r--contrib/cvs/src/tag.c5
-rw-r--r--contrib/cvs/src/update.c178
-rw-r--r--contrib/cvs/src/update.h6
-rw-r--r--contrib/cvs/src/version.c.in86
-rw-r--r--contrib/cvs/src/version.h.in15
32 files changed, 820 insertions, 991 deletions
diff --git a/contrib/cvs/src/NOTES b/contrib/cvs/src/NOTES
deleted file mode 100644
index 646ebdf..0000000
--- a/contrib/cvs/src/NOTES
+++ /dev/null
@@ -1,60 +0,0 @@
-wishlist - Tue Nov 2 15:22:58 PST 1993
-
-* bcopy -> memcpy & friends.
- ** done 12/18/93
-
-* remove static buffers.
-* replace list & node cache with recursive obstacks, (xmalloc,
- getnode, getlist)
-* check all io functions for error return codes. also check all
- system calls.
-* error check mkdir.
-
----
-Old notes...
-
-* All sizing limits are gone. The rest of these items were incidental
- in that effort.
-
-* login name from history was duplicated. taught existing routine to
- cache and use that instead. Also add routines to cache uid, pid,
- etc.
-
-* ign strings were never freed. Now they are.
-
-* there was a printf("... %s ...", cp) vs *cp bug in history.c. Now
- fixed.
-
-* The environment variables TMPDIR, HOME, and LOGNAME were not
- honored. Now they are.
-
-* extra line inserted by do_editor() is gone. Then obviated. Editor
- is now called exactly once per checkin.
-
-* revised editor behaviour. Never use /dev/tty. If the editor
- session fails, we haven't yet done anything. Therefor the user can
- safely rerun cvs and we should just fail. Also use the editor for
- initial log messages on added files. Also omit the confirmation
- when adding directories. Adding directories will require an
- explicit "commit" step soon. Make it possible to prevent null login
- messages using #define REQUIRE_LOG_MESSAGES
-
-* prototypes for all callbacks.
-
-* all callbacks get ref pointers.
-
-* do_recursion/start_recursion now use recusion_frame's rather than a
- list of a lot of pointers and global variables.
-
-* corrected types on status_dirproc().
-
-* CONFIRM_DIRECTORY_ADDS
-
-* re_comp was innappropriate in a few places. I've eliminated it.
-
-* FORCE_MESSAGE_ON_ADD
-
-* So I built a regression test. Let's call it a sanity check to be
- less ambitious. It exposed that cvs is difficult to call from
- scripts.
-
diff --git a/contrib/cvs/src/README-rm-add b/contrib/cvs/src/README-rm-add
deleted file mode 100644
index 87fd7c6..0000000
--- a/contrib/cvs/src/README-rm-add
+++ /dev/null
@@ -1,31 +0,0 @@
-WHAT THE "DEATH SUPPORT" FEATURES DO:
-
-(Some of the death support stuff is documented in the main manual, but
-this file is for stuff which noone has gotten around to adding to the
-main manual yet).
-
-CVS with death support can record when a file is active, or alive, and
-when it is removed, or dead. With this facility you can record the
-history of a file, including the fact that at some point in its life
-the file was removed and then later added.
-
-Files can now be added or removed in a branch and later merged
-into the trunk.
-
- cvs update -A
- touch a b c
- cvs add a b c ; cvs ci -m "added" a b c
- cvs tag -b branchtag
- cvs update -r branchtag
- touch d ; cvs add d
- rm a ; cvs rm a
- cvs ci -m "added d, removed a"
- cvs update -A
- cvs update -jbranchtag
-
-Added and removed files may also be merged between branches.
-
-Files removed in the trunk may be merged into branches.
-
-Files added on the trunk are a special case. They cannot be merged
-into a branch. Instead, simply branch the file by hand.
diff --git a/contrib/cvs/src/buffer.c b/contrib/cvs/src/buffer.c
index 8e66355..db2bea0 100644
--- a/contrib/cvs/src/buffer.c
+++ b/contrib/cvs/src/buffer.c
@@ -14,6 +14,8 @@
/* Code for the buffer data structure. */
+/* $FreeBSD$ */
+
#include <assert.h>
#include "cvs.h"
#include "buffer.h"
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index e4d80ea..a1cd6cc 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -38,6 +38,10 @@
* edited by the user, if necessary (when the repository is moved, e.g.)
*/
+/*
+ * $FreeBSD$
+ */
+
#include <assert.h>
#include "cvs.h"
@@ -55,6 +59,7 @@ static const char *const checkout_usage[] =
"\t-N\tDon't shorten module paths if -d specified.\n",
"\t-P\tPrune empty directories.\n",
"\t-R\tProcess directories recursively.\n",
+ "\t-T\tCreate Template file from local repository for remote commit.\n",
"\t-c\t\"cat\" the module database.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
@@ -97,6 +102,7 @@ static char *date;
static char *join_rev1;
static char *join_rev2;
static int join_tags_validated;
+static int pull_template;
static char *preload_update_dir;
static char *history_name;
static enum mtype m_type;
@@ -144,7 +150,7 @@ checkout (argc, argv)
else
{
m_type = CHECKOUT;
- valid_options = "+ANnk:d:flRpQqcsr:D:j:P";
+ valid_options = "+ANnk:d:flRpTQqcsr:D:j:P";
valid_usage = checkout_usage;
}
@@ -173,6 +179,9 @@ checkout (argc, argv)
case 'n':
run_module_prog = 0;
break;
+ case 'T':
+ pull_template = 1;
+ break;
case 'Q':
case 'q':
/* The CVS 1.5 client sends these options (in addition to
@@ -1098,8 +1107,7 @@ internal error: %s doesn't start with %s in checkout_proc",
force_tag_match, 0 /* !local */ ,
1 /* update -d */ , aflag, checkout_prune_dirs,
pipeout, which, join_rev1, join_rev2,
- preload_update_dir, m_type == CHECKOUT,
- repository);
+ preload_update_dir, pull_template, repository);
goto out;
}
@@ -1155,8 +1163,7 @@ internal error: %s doesn't start with %s in checkout_proc",
err += do_update (argc - 1, argv + 1, options, tag, date,
force_tag_match, local_specified, 1 /* update -d */,
aflag, checkout_prune_dirs, pipeout, which, join_rev1,
- join_rev2, preload_update_dir, m_type == CHECKOUT,
- repository);
+ join_rev2, preload_update_dir, pull_template, repository);
out:
free (preload_update_dir);
preload_update_dir = oldupdate;
diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c
index 78fc989..318db4a 100644
--- a/contrib/cvs/src/client.c
+++ b/contrib/cvs/src/client.c
@@ -10,6 +10,10 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. */
+/*
+ * $FreeBSD$
+ */
+
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
@@ -160,22 +164,17 @@ is_arg_a_parent_or_listed_dir (n, d)
void *d;
{
char *directory = n->key; /* name of the dir sent to server */
- char *this_argv_elem = xstrdup (d); /* this argv element */
- int retval;
+ char *this_argv_elem = (char *) d; /* this argv element */
/* Say we should send this argument if the argument matches the
beginning of a directory name sent to the server. This way,
the server will know to start at the top of that directory
hierarchy and descend. */
- strip_trailing_slashes (this_argv_elem);
if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
- retval = 1;
- else
- retval = 0;
+ return 1;
- free (this_argv_elem);
- return retval;
+ return 0;
}
static int arg_should_not_be_sent_to_server PROTO((char *));
@@ -274,7 +273,8 @@ arg_should_not_be_sent_to_server (arg)
}
/* Now check the value for root. */
- if (root_string && current_parsed_root
+ if (CVSroot_cmdline == NULL &&
+ root_string && current_parsed_root
&& (strcmp (root_string, current_parsed_root->original) != 0))
{
/* Don't send this, since the CVSROOTs don't match. */
@@ -2783,8 +2783,7 @@ send_repository (dir, repos, update_dir)
send_to_server (repos, 0);
send_to_server ("\012", 1);
- if (strcmp (cvs_cmd_name, "import")
- && supported_request ("Static-directory"))
+ if (supported_request ("Static-directory"))
{
adm_name[0] = '\0';
if (dir[0] != '\0')
@@ -2798,8 +2797,7 @@ send_repository (dir, repos, update_dir)
send_to_server ("Static-directory\012", 0);
}
}
- if (strcmp (cvs_cmd_name, "import")
- && supported_request ("Sticky"))
+ if (supported_request ("Sticky"))
{
FILE *f;
if (dir[0] == '\0')
@@ -3842,7 +3840,7 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
int do_gssapi;
struct hostent *hostinfo;
{
- char *username = ""; /* the username we use to connect */
+ char *username; /* the username we use to connect */
char no_passwd = 0; /* gets set if no password found */
/* FIXME!!!!!!!!!!!!!!!!!!
@@ -3926,8 +3924,9 @@ auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
send_to_server(end, 0);
send_to_server("\012", 1);
- free_cvs_password (password);
- password = NULL;
+ /* Paranoia. */
+ memset (password, 0, strlen (password));
+ free (password);
# else /* ! AUTH_CLIENT_SUPPORT */
error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
# endif /* AUTH_CLIENT_SUPPORT */
@@ -4726,20 +4725,15 @@ start_rsh_server (root, to_server, from_server)
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
invoke another rsh on a proxy machine. */
- char *env_cvs_rsh = getenv ("CVS_RSH");
- char *env_cvs_ssh = getenv ("CVS_SSH");
- char *cvs_rsh;
+ char *cvs_rsh = getenv ("CVS_RSH");
char *cvs_server = getenv ("CVS_SERVER");
int i = 0;
/* This needs to fit "rsh", "-b", "-l", "USER", "host",
"cmd (w/ args)", and NULL. We leave some room to grow. */
char *rsh_argv[10];
- if (root->method == extssh_method)
- cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
- else
- cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
-
+ if (!cvs_rsh)
+ cvs_rsh = RSH_DFLT;
if (!cvs_server)
cvs_server = "cvs";
@@ -4793,19 +4787,14 @@ start_rsh_server (root, to_server, from_server)
/* If you're working through firewalls, you can set the
CVS_RSH environment variable to a script which uses rsh to
invoke another rsh on a proxy machine. */
- char *env_cvs_rsh = getenv ("CVS_RSH");
- char *env_cvs_ssh = getenv ("CVS_SSH");
- char *cvs_rsh;
+ char *cvs_rsh = getenv ("CVS_RSH");
char *cvs_server = getenv ("CVS_SERVER");
char *command;
int tofd, fromfd;
int child_pid;
- if (root->method == extssh_method)
- cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
- else
- cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
-
+ if (!cvs_rsh)
+ cvs_rsh = RSH_DFLT;
if (!cvs_server)
cvs_server = "cvs";
@@ -5166,7 +5155,8 @@ warning: ignoring -k options due to server limitations");
|| strcmp (vers->ts_conflict
&& supported_request ("Empty-conflicts")
? vers->ts_conflict : vers->ts_rcs, vers->ts_user)
- || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff")))
+ || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff"))
+ || (vers->vn_user && *vers->vn_user == '0'))
{
if (args->no_contents
&& supported_request ("Is-modified"))
diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c
index 7d168c3..b3ba47b 100644
--- a/contrib/cvs/src/commit.c
+++ b/contrib/cvs/src/commit.c
@@ -17,6 +17,7 @@
*
* The call is: cvs commit [options] files...
*
+ * $FreeBSD$
*/
#include <assert.h>
diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h
index 187a354..f412aa0 100644
--- a/contrib/cvs/src/cvs.h
+++ b/contrib/cvs/src/cvs.h
@@ -14,6 +14,7 @@
/*
* basic information used in all source files
*
+ * $FreeBSD$
*/
@@ -199,6 +200,7 @@ extern int errno;
#define CVSROOTADM_WRITERS "writers"
#define CVSROOTADM_PASSWD "passwd"
#define CVSROOTADM_CONFIG "config"
+#define CVSROOTADM_OPTIONS "options"
#define CVSNULLREPOS "Emptydir" /* an empty directory */
@@ -270,6 +272,8 @@ extern int errno;
#define CVSREAD_ENV "CVSREAD" /* make files read-only */
#define CVSREAD_DFLT 0 /* writable files by default */
+#define CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
+
#define TMPDIR_ENV "TMPDIR" /* Temporary directory */
#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */
@@ -300,6 +304,9 @@ extern int errno;
command line, the client, etc. */
#define MAXDATELEN 50
+/* FreeBSD.org default is to use ssh. */
+#define RSH_DFLT "ssh"
+
/* The type of an entnode. */
enum ent_type
{
@@ -382,6 +389,7 @@ extern int really_quiet, quiet;
extern int use_editor;
extern int cvswrite;
extern mode_t cvsumask;
+extern char *RCS_citag;
@@ -400,7 +408,9 @@ extern int safe_location PROTO ((char *));
extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
+extern int readonlyfs; /* fail on all write locks; succeed all read locks */
extern int logoff; /* Don't write history entry */
+extern int require_real_user; /* skip CVSROOT/passwd, /etc/passwd users only*/
extern int top_level_admin;
@@ -502,6 +512,7 @@ char *get_homedir PROTO ((void));
char *strcat_filename_onto_homedir PROTO ((const char *, const char *));
char *cvs_temp_name PROTO ((void));
FILE *cvs_temp_file PROTO ((char **filename));
+void parseopts PROTO ((const char *root));
int numdots PROTO((const char *s));
char *increment_revnum PROTO ((const char *));
@@ -588,6 +599,7 @@ void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
void WriteTag PROTO ((const char *dir, const char *tag, const char *date,
int nonbranch, const char *update_dir,
const char *repository));
+void WriteTemplate PROTO ((const char *dir, const char *update_dir));
void cat_module PROTO((int status));
void check_entries PROTO((char *dir));
void close_module PROTO((DBM * db));
@@ -916,7 +928,6 @@ char *descramble PROTO ((char *str));
#ifdef AUTH_CLIENT_SUPPORT
char *get_cvs_password PROTO((void));
-void free_cvs_password PROTO((char *str));
int get_cvs_port_number PROTO((const cvsroot_t *root));
char *normalize_cvsroot PROTO((const cvsroot_t *root));
#endif /* AUTH_CLIENT_SUPPORT */
diff --git a/contrib/cvs/src/cvsbug.in b/contrib/cvs/src/cvsbug.in
index efc156d..07de151 100755
--- a/contrib/cvs/src/cvsbug.in
+++ b/contrib/cvs/src/cvsbug.in
@@ -109,14 +109,12 @@ elif [ -f /bin/domainname ]; then
/usr/bin/ypcat passwd 2>/dev/null | cat - /etc/passwd | grep "^$LOGNAME:" |
cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
fi
fi
if [ "$ORIGINATOR" = "" ]; then
grep "^$LOGNAME:" /etc/passwd | cut -f5 -d':' | sed -e 's/,.*//' > $TEMP
ORIGINATOR="`cat $TEMP`"
- rm -f $TEMP
fi
if [ -n "$ORGANIZATION" ]; then
diff --git a/contrib/cvs/src/diff.c b/contrib/cvs/src/diff.c
index a5ca2d0..8a61f9a 100644
--- a/contrib/cvs/src/diff.c
+++ b/contrib/cvs/src/diff.c
@@ -17,6 +17,8 @@
*
* Without any file arguments, runs diff against all the currently modified
* files.
+ *
+ * $FreeBSD$
*/
#include <assert.h>
@@ -57,6 +59,7 @@ static void diff_mark_errors PROTO((int err));
static char *diff_rev1, *diff_rev2;
/* Command line dates, from -D option. Malloc'd. */
static char *diff_date1, *diff_date2;
+static char *diff_join1, *diff_join2;
static char *use_rev1, *use_rev2;
static int have_rev1_label, have_rev2_label;
@@ -324,6 +327,8 @@ diff (argc, argv)
diff_rev2 = NULL;
diff_date1 = NULL;
diff_date2 = NULL;
+ diff_join1 = NULL;
+ diff_join2 = NULL;
optind = 0;
/* FIXME: This should really be allocating an argv to be passed to diff
@@ -334,7 +339,7 @@ diff (argc, argv)
* to diff.
*/
while ((c = getopt_long (argc, argv,
- "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:",
+ "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:W:k:r:j:",
longopts, &option_index)) != -1)
{
switch (c)
@@ -378,6 +383,27 @@ diff (argc, argv)
free (options);
options = RCS_check_kflag (optarg);
break;
+ case 'j':
+ {
+ char *ptr;
+ char *cpy = strdup(optarg);
+
+ if ((ptr = strchr(optarg, ':')) != NULL)
+ *ptr++ = 0;
+ if (diff_rev2 != NULL || diff_date2 != NULL)
+ error (1, 0,
+ "no more than two revisions/dates can be specified");
+ if (diff_rev1 != NULL || diff_date1 != NULL) {
+ diff_join2 = cpy;
+ diff_rev2 = optarg;
+ diff_date2 = ptr ? Make_Date(ptr) : NULL;
+ } else {
+ diff_join1 = cpy;
+ diff_rev1 = optarg;
+ diff_date1 = ptr ? Make_Date(ptr) : NULL;
+ }
+ }
+ break;
case 'r':
if (diff_rev2 != NULL || diff_date2 != NULL)
error (1, 0,
@@ -426,13 +452,18 @@ diff (argc, argv)
send_options (diff_argc, diff_argv);
if (options[0] != '\0')
send_arg (options);
- if (diff_rev1)
+ if (diff_join1)
+ option_with_arg ("-j", diff_join1);
+ else if (diff_rev1)
option_with_arg ("-r", diff_rev1);
- if (diff_date1)
+ else if (diff_date1)
client_senddate (diff_date1);
- if (diff_rev2)
+
+ if (diff_join2)
+ option_with_arg ("-j", diff_join2);
+ else if (diff_rev2)
option_with_arg ("-r", diff_rev2);
- if (diff_date2)
+ else if (diff_date2)
client_senddate (diff_date2);
send_arg ("--");
@@ -446,12 +477,9 @@ diff (argc, argv)
send_to_server ("diff\012", 0);
err = get_responses_and_close ();
- free (options);
- options = NULL;
- return (err);
- }
+ } else
#endif
-
+ { /* FreeBSD addition - warning idention not changed til matching-} */
if (diff_rev1 != NULL)
tag_check_valid (diff_rev1, argc, argv, local, 0, "");
if (diff_rev2 != NULL)
@@ -468,6 +496,7 @@ diff (argc, argv)
diff_dirleaveproc, NULL, argc, argv, local,
which, 0, CVS_LOCK_READ, (char *) NULL, 1,
(char *) NULL);
+ } /* FreeBSD addition */
/* clean up */
free (options);
@@ -477,6 +506,10 @@ diff (argc, argv)
free (diff_date1);
if (diff_date2 != NULL)
free (diff_date2);
+ if (diff_join1 != NULL)
+ free (diff_join1);
+ if (diff_join2 != NULL)
+ free (diff_join2);
return (err);
}
diff --git a/contrib/cvs/src/entries.c b/contrib/cvs/src/entries.c
index c346fb6..9592c3c 100644
--- a/contrib/cvs/src/entries.c
+++ b/contrib/cvs/src/entries.c
@@ -16,6 +16,9 @@
* the Entries file.
*/
+/*
+ * $FreeBSD$
+ */
#include "cvs.h"
#include "getline.h"
@@ -641,6 +644,72 @@ AddEntryNode (list, entdata)
return (p);
}
+static char *root_template;
+
+static int
+get_root_template(const char *repository, const char *path)
+{
+ if (root_template) {
+ if (strcmp(path, root_template) == 0)
+ return(0);
+ free(root_template);
+ }
+ if ((root_template = strdup(path)) == NULL)
+ return(-1);
+ return(0);
+}
+
+/*
+ * Write out/Clear the CVS/Template file.
+ */
+void
+WriteTemplate (dir, update_dir)
+ const char *dir;
+ const char *update_dir;
+{
+ char *tmp = NULL;
+ struct stat st1;
+ struct stat st2;
+
+ if (Parse_Info(CVSROOTADM_RCSINFO, "cvs", get_root_template, 1) < 0)
+ return;
+
+ if (asprintf(&tmp, "%s/%s", dir, CVSADM_TEMPLATE) < 0)
+ error (1, errno, "out of memory");
+
+ if (stat(root_template, &st1) == 0) {
+ if (stat(tmp, &st2) < 0 || st1.st_mtime != st2.st_mtime) {
+ FILE *fi;
+ FILE *fo;
+
+ if ((fi = open_file(root_template, "r")) != NULL) {
+ if ((fo = open_file(tmp, "w")) != NULL) {
+ int n;
+ char buf[256];
+
+ while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
+ fwrite(buf, 1, n, fo);
+ fflush(fo);
+ if (ferror(fi) || ferror(fo)) {
+ fclose(fo);
+ remove(tmp);
+ error (1, errno, "error copying Template");
+ } else {
+ struct timeval times[2];
+ fclose(fo);
+ times[0].tv_sec = st1.st_mtime;
+ times[0].tv_usec = 0;
+ times[1] = times[0];
+ utimes(tmp, times);
+ }
+ }
+ fclose(fi);
+ }
+ }
+ }
+ free(tmp);
+}
+
/*
* Write out/Clear the CVS/Tag file.
*/
diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c
index 1e1f901..186f0c6 100644
--- a/contrib/cvs/src/filesubr.c
+++ b/contrib/cvs/src/filesubr.c
@@ -17,6 +17,10 @@
definitions under operating systems (like, say, Windows NT) with different
file system semantics. */
+/*
+ * $FreeBSD$
+ */
+
#include <assert.h>
#include "cvs.h"
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index bc918e0..d4e2f24 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -19,6 +19,8 @@
* VendorReleTag Tag for this particular release
*
* Additional arguments specify more Vendor Release Tags.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -162,21 +164,14 @@ import (argc, argv)
* Could abstract this to valid_module_path, but I don't think we'll need
* to call it from anywhere else.
*/
- /* for each "CVS" in path... */
- cp = argv[0];
- while ((cp = strstr(cp, "CVS")) != NULL)
+ if ((cp = strstr(argv[0], "CVS")) && /* path contains "CVS" AND ... */
+ ((cp == argv[0]) || ISDIRSEP(*(cp-1))) && /* /^CVS/ OR m#/CVS# AND ... */
+ ((*(cp+3) == '\0') || ISDIRSEP(*(cp+3))) /* /CVS$/ OR m#CVS/# */
+ )
{
- if ( /* /^CVS/ OR m#/CVS#... */
- (cp == argv[0] || ISDIRSEP(*(cp-1)))
- /* ...AND /CVS$/ OR m#CVS/# */
- && (*(cp+3) == '\0' || ISDIRSEP(*(cp+3)))
- )
- {
- error (0, 0,
- "The word `CVS' is reserved by CVS and may not be used");
- error (1, 0, "as a directory in a path or as a file name.");
- }
- cp += 3;
+ error (0, 0,
+ "The word `CVS' is reserved by CVS and may not be used");
+ error (1, 0, "as a directory in a path or as a file name.");
}
for (i = 1; i < argc; i++) /* check the tags for validity */
@@ -1608,8 +1603,8 @@ import_descend_dir (message, dir, vtag, targc, targv)
if ( CVS_CHDIR (dir) < 0)
{
ierrno = errno;
- fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", dir);
- error (0, ierrno, "ERROR: cannot chdir to %s", dir);
+ fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
+ error (0, ierrno, "ERROR: cannot chdir to %s", repository);
err = 1;
goto out;
}
diff --git a/contrib/cvs/src/lock.c b/contrib/cvs/src/lock.c
index 6f818da..a407dac 100644
--- a/contrib/cvs/src/lock.c
+++ b/contrib/cvs/src/lock.c
@@ -13,6 +13,8 @@
* Set Lock
*
* Lock file support for CVS.
+ *
+ * $FreeBSD$
*/
/* The node Concurrency in doc/cvs.texinfo has a brief introduction to
@@ -173,7 +175,7 @@ lock_name (repository, name)
const char *p;
char *q;
const char *short_repos;
- mode_t save_umask = 0;
+ mode_t save_umask;
int saved_umask = 0;
if (lock_dir == NULL)
@@ -420,7 +422,7 @@ Reader_Lock (xrepository)
(void) fprintf (stderr, "%s-> Reader_Lock(%s)\n", CLIENT_SERVER_STR,
xrepository);
- if (noexec)
+ if (noexec || readonlyfs)
return 0;
/* we only do one directory at a time for read locks! */
@@ -497,6 +499,11 @@ Writer_Lock (list)
if (noexec)
return 0;
+ if (readonlyfs) {
+ error (0, 0, "write lock failed - read-only repository");
+ return (1);
+ }
+
/* We only know how to do one list at a time */
if (locklist != (List *) NULL)
{
diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c
index 1730874..a952283 100644
--- a/contrib/cvs/src/log.c
+++ b/contrib/cvs/src/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -15,6 +15,8 @@
* Prints the RCS "log" (rlog) information for the specified files. With no
* argument, prints the log information for all the files in the directory
* (recursive by default).
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -87,7 +89,7 @@ struct log_data
/* Nonzero if the -N option was seen, meaning that tag information
should not be printed. */
int notags;
- /* Nonzero if the -b option was seen, meaning that revisions
+ /* Nonzero if the -b option was seen, meaning that only revisions
on the default branch should be printed. */
int default_branch;
/* Nonzero if the -S option was seen, meaning that the header/name
@@ -156,12 +158,11 @@ static const char *const log_usage[] =
"Usage: %s %s [-lRhtNb] [-r[revisions]] [-d dates] [-s states]\n",
" [-w[logins]] [files...]\n",
"\t-l\tLocal directory only, no recursion.\n",
- "\t-b\tList revisions on the default branch.\n",
+ "\t-b\tOnly list revisions on the default branch.\n",
"\t-h\tOnly print header.\n",
"\t-R\tOnly print name of RCS file.\n",
"\t-t\tOnly print header and descriptive text.\n",
"\t-N\tDo not list tags.\n",
- "\t-n\tList tags (default).\n",
"\t-S\tDo not print name/header if no revisions selected. -d, -r,\n",
"\t\t-s, & -w have little effect in conjunction with -b, -h, -R, and\n",
"\t\t-t without this option.\n",
@@ -1648,8 +1649,8 @@ log_version (log_data, revlist, rcs, ver, trunk)
&sec);
if (year < 1900)
year += 1900;
- sprintf (buf, "%04d/%02d/%02d %02d:%02d:%02d", year, mon, mday,
- hour, min, sec);
+ sprintf (buf, "%04d%c%02d%c%02d %02d:%02d:%02d",
+ year, datesep, mon, datesep, mday, hour, min, sec);
cvs_output (buf, 0);
cvs_output ("; author: ", 0);
diff --git a/contrib/cvs/src/login.c b/contrib/cvs/src/login.c
index 1d20c97..3222228 100644
--- a/contrib/cvs/src/login.c
+++ b/contrib/cvs/src/login.c
@@ -10,6 +10,8 @@
* specified in the README file that comes with CVS.
*
* Allow user to log in for an authenticating server.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -115,20 +117,20 @@ password_entry_parseline (cvsroot_canonical, warn, linenumber, linebuf)
{
/* Yes: slurp '^/\d+\D' and parse the rest of the line according to version number */
char *q;
- unsigned long int entry_version = 0;
+ unsigned long int entry_version;
if (isspace(*(linebuf + 1)))
- {
/* special case since strtoul ignores leading white space */
q = linebuf + 1;
- }
else
- {
entry_version = strtoul (linebuf + 1, &q, 10);
- if (q != linebuf + 1)
- /* assume a delimiting seperator */
- q++;
- }
+
+ if (q == linebuf + 1)
+ /* no valid digits found by strtoul */
+ entry_version = 0;
+ else
+ /* assume a delimiting seperator */
+ q++;
switch (entry_version)
{
@@ -566,40 +568,21 @@ login (argc, argv)
password_entry_operation (password_entry_add, current_parsed_root,
typed_password);
- free_cvs_password (typed_password);
+ memset (typed_password, 0, strlen (typed_password));
+ free (typed_password);
+
+ free (cvs_password);
free (cvsroot_canonical);
+ cvs_password = NULL;
return 0;
}
-/* Free the password returned by get_cvs_password() and also free the
- * saved cvs_password if they are different pointers. Be paranoid
- * about the in-memory copy of the password and overwrite it with zero
- * bytes before doing the free().
- */
-void
-free_cvs_password (char *password)
-{
- if (password && password != cvs_password)
- {
- memset (password, 0, strlen (password));
- free (password);
- }
-
- if (cvs_password)
- {
- memset (cvs_password, 0, strlen (cvs_password));
- free (cvs_password);
- cvs_password = NULL;
- }
-}
-
-/* Returns the _scrambled_ password in freshly allocated memory. The server
- * must descramble before hashing and comparing. If password file not found,
- * or password not found in the file, just return NULL.
- */
+/* Returns the _scrambled_ password. The server must descramble
+ before hashing and comparing. If password file not found, or
+ password not found in the file, just return NULL. */
char *
get_cvs_password ()
{
@@ -610,7 +593,7 @@ get_cvs_password ()
context, then assume they have supplied the correct, scrambled
password. */
if (cvs_password)
- return xstrdup (cvs_password);
+ return cvs_password;
if (getenv ("CVS_PASSWORD") != NULL)
{
diff --git a/contrib/cvs/src/logmsg.c b/contrib/cvs/src/logmsg.c
index 5ac4b0e..6878aaf 100644
--- a/contrib/cvs/src/logmsg.c
+++ b/contrib/cvs/src/logmsg.c
@@ -9,6 +9,8 @@
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
+ *
+ * $FreeBSD$
*/
#include <assert.h>
@@ -227,6 +229,8 @@ do_editor (dir, messagep, repository, changes)
(*messagep)[strlen (*messagep) - 1] != '\n')
(void) fprintf (fp, "\n");
}
+ else
+ (void) fprintf (fp, "\n");
if (repository != NULL)
/* tack templates on if necessary */
diff --git a/contrib/cvs/src/main.c b/contrib/cvs/src/main.c
index 3dace64..1365321 100644
--- a/contrib/cvs/src/main.c
+++ b/contrib/cvs/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2006 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2006 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -15,10 +15,12 @@
* Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing
* the shell-script CVS system that this is based on.
*
+ * $FreeBSD$
*/
#include <assert.h>
#include "cvs.h"
+#include "prepend_args.h"
#ifdef HAVE_WINSOCK_H
#include <winsock.h>
@@ -46,6 +48,8 @@ int really_quiet = 0;
int quiet = 0;
int trace = 0;
int noexec = 0;
+int readonlyfs = 0;
+int require_real_user = 0;
int logoff = 0;
/*
@@ -248,8 +252,10 @@ static const char *const opt_usage[] =
" -q Cause CVS to be somewhat quiet.\n",
" -r Make checked-out files read-only.\n",
" -w Make checked-out files read-write (default).\n",
+ " -g Force group-write perms on checked-out files.\n",
" -n Do not execute anything that will change the disk.\n",
" -t Show trace of program execution -- try with -n.\n",
+ " -R Assume repository is read-only, such as CDROM\n",
" -v CVS version and copyright.\n",
" -T tmpdir Use 'tmpdir' for temporary files.\n",
" -e editor Use 'editor' for editing log information.\n",
@@ -407,7 +413,7 @@ main (argc, argv)
int help = 0; /* Has the user asked for help? This
lets us support the `cvs -H cmd'
convention to give help for cmd. */
- static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa";
+ static const char short_options[] = "+QqgrwtnRvb:T:e:d:Hfz:s:xaU";
static struct option long_options[] =
{
{"help", 0, NULL, 'H'},
@@ -464,6 +470,12 @@ main (argc, argv)
Editor = cp;
if (getenv (CVSREAD_ENV) != NULL)
cvswrite = 0;
+ if (getenv (CVSREADONLYFS_ENV) != NULL) {
+ readonlyfs = 1;
+ logoff = 1;
+ }
+
+ prepend_default_options (getenv ("CVS_OPTIONS"), &argc, &argv);
/* Set this to 0 to force getopt initialization. getopt() sets
this to 1 internally. */
@@ -526,9 +538,20 @@ main (argc, argv)
case 'w':
cvswrite = 1;
break;
+ case 'g':
+ /*
+ * force full group write perms (used for shared checked-out
+ * source trees, see manual page)
+ */
+ umask(umask(077) & 007);
+ break;
case 't':
trace = 1;
break;
+ case 'R':
+ readonlyfs = 1;
+ logoff = 1;
+ break;
case 'n':
noexec = 1;
logoff = 1;
@@ -623,6 +646,11 @@ distribution kit for a complete list of contributors and copyrights.\n",
We will issue an error later if stream
authentication is not supported. */
break;
+ case 'U':
+#ifdef SERVER_SUPPORT
+ require_real_user = 1;
+#endif
+ break;
case '?':
default:
usage (usg);
@@ -749,6 +777,12 @@ distribution kit for a complete list of contributors and copyrights.\n",
(void) putenv (env);
/* do not free env, as putenv has control of it */
}
+ {
+ char *env;
+ env = xmalloc (sizeof "CVS_PID=" + 32); /* XXX pid < 10^32 */
+ (void) sprintf (env, "CVS_PID=%ld", (long) getpid ());
+ (void) putenv (env);
+ }
#endif
#ifndef DONT_USE_SIGNALS
@@ -953,6 +987,9 @@ distribution kit for a complete list of contributors and copyrights.\n",
if we didn't, then there would be no way to check in a new
CVSROOT/config file to fix the broken one! */
parse_config (current_parsed_root->directory);
+
+ /* Now is a convenient time to read CVSROOT/options */
+ parseopts(current_parsed_root->directory);
}
#ifdef CLIENT_SUPPORT
@@ -1140,3 +1177,64 @@ usage (cpp)
(void) fprintf (stderr, *cpp);
error_exit ();
}
+
+void
+parseopts(root)
+ const char *root;
+{
+ char path[PATH_MAX];
+ int save_errno;
+ char buf[1024];
+ const char *p;
+ char *q;
+ FILE *fp;
+
+ if (root == NULL) {
+ printf("no CVSROOT in parseopts\n");
+ return;
+ }
+ p = strchr (root, ':');
+ if (p)
+ p++;
+ else
+ p = root;
+ if (p == NULL) {
+ printf("mangled CVSROOT in parseopts\n");
+ return;
+ }
+ (void) sprintf (path, "%s/%s/%s", p, CVSROOTADM, CVSROOTADM_OPTIONS);
+ if ((fp = fopen(path, "r")) != NULL) {
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ if (buf[0] == '#')
+ continue;
+ q = strrchr(buf, '\n');
+ if (q)
+ *q = '\0';
+
+ if (!strcmp(buf, "iso8601")) {
+ datesep = '-';
+ }
+ if (!strncmp(buf, "tag=", 4)) {
+ char *what;
+ char *rcs_localid;
+
+ rcs_localid = buf + 4;
+ RCS_setlocalid(rcs_localid);
+ }
+ if (!strncmp(buf, "tagexpand=", 10)) {
+ char *what;
+ char *rcs_incexc;
+
+ rcs_incexc = buf + 10;
+ RCS_setincexc(rcs_incexc);
+ }
+ /*
+ * OpenBSD has a "umask=" and "dlimit=" command, we silently
+ * ignore them here since they are not much use to us. cvsumask
+ * defaults to 002 already, and the dlimit (data size limit)
+ * should really be handled elsewhere (eg: login.conf).
+ */
+ }
+ fclose(fp);
+ }
+}
diff --git a/contrib/cvs/src/mkmodules.c b/contrib/cvs/src/mkmodules.c
index 751d4c7..cdd766e 100644
--- a/contrib/cvs/src/mkmodules.c
+++ b/contrib/cvs/src/mkmodules.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -8,9 +8,11 @@
* Portions Copyright (C) 1989-1992, Brian Berliner
*
* You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS kit. */
+ * specified in the README file that comes with the CVS kit.
+ *
+ * $FreeBSD$
+ */
-#include <assert.h>
#include "cvs.h"
#include "getline.h"
#include "history.h"
@@ -262,6 +264,7 @@ static const char *const modules_contents[] = {
"# key [options] directory files...\n",
"#\n",
"# Where \"options\" are composed of:\n",
+ "# -i prog Run \"prog\" on \"cvs commit\" from top-level of module.\n",
"# -o prog Run \"prog\" on \"cvs checkout\" of module.\n",
"# -e prog Run \"prog\" on \"cvs export\" of module.\n",
"# -t prog Run \"prog\" on \"cvs rtag\" of module.\n",
@@ -288,13 +291,6 @@ static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
"#SystemAuth=yes\n",
"\n",
- "# Set `IgnoreUnknownConfigKeys' to `yes' to ignore unknown config\n",
- "# keys which are supported in a future version of CVS.\n",
- "# This option is intended to be useful as a transition for read-only\n",
- "# mirror sites when sites may need to be updated later than the\n",
- "# primary CVS repository.\n",
- "#IgnoreUnknownConfigKeys=no\n",
- "\n",
"# Put CVS lock files in this directory rather than directly in the repository.\n",
"#LockDir=/var/lock/cvs\n",
"\n",
@@ -853,41 +849,6 @@ rename_rcsfile (temp, real)
free (bak);
}
-
-/*
- * Walk PATH backwards to the root directory looking for the root of a
- * repository.
- */
-static char *
-in_repository (const char *path)
-{
- char *cp = xstrdup (path);
-
- for (;;)
- {
- if (isdir (cp))
- {
- int foundit;
- char *adm = xmalloc (strlen(cp) + strlen(CVSROOTADM) + 2);
- sprintf (adm, "%s/%s", cp, CVSROOTADM);
- foundit = isdir (adm);
- free (adm);
- if (foundit) return cp;
- }
-
- /* If last_component() returns the empty string, then cp either
- * points at the system root or is the empty string itself.
- */
- if (!*last_component (cp) || !strcmp (cp, ".")
- || last_component(cp) == cp)
- break;
-
- cp[strlen(cp) - strlen(last_component(cp)) - 1] = '\0';
- }
-
- return NULL;
-}
-
const char *const init_usage[] = {
"Usage: %s %s\n",
@@ -909,11 +870,8 @@ init (argc, argv)
/* Exit status. */
int err = 0;
- char *root_dir;
const struct admin_file *fileptr;
- assert (!server_active);
-
umask (cvsumask);
if (argc == -1 || argc > 1)
@@ -930,14 +888,6 @@ init (argc, argv)
}
#endif /* CLIENT_SUPPORT */
- root_dir = in_repository (current_parsed_root->directory);
-
- if (root_dir && strcmp (root_dir, current_parsed_root->directory))
- error (1, 0,
- "Cannot initialize repository under existing CVSROOT: `%s'",
- root_dir);
- free (root_dir);
-
/* Note: we do *not* create parent directories as needed like the
old cvsinit.sh script did. Few utilities do that, and a
non-existent parent directory is as likely to be a typo as something
diff --git a/contrib/cvs/src/options.h.in b/contrib/cvs/src/options.h.in
deleted file mode 100644
index a3ee047..0000000
--- a/contrib/cvs/src/options.h.in
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS source distribution.
- *
- * This file holds (most of) the configuration tweaks that can be made to
- * customize CVS for your site. CVS comes configured for a typical SunOS 4.x
- * environment. The comments for each configurable item are intended to be
- * self-explanatory. All #defines are tested first to see if an over-riding
- * option was specified on the "make" command line.
- *
- * If special libraries are needed, you will have to edit the Makefile.in file
- * or the configure script directly. Sorry.
- */
-
-/* By default, CVS stores its modules and other such items in flat
- text files (MY_NDBM enables this). Turning off MY_NDBM causes CVS
- to look for a system-supplied ndbm database library and use it
- instead. That may speed things up, but the default setting
- generally works fine too. */
-
-#ifndef MY_NDBM
-#define MY_NDBM
-#endif
-
-/*
- * The "patch" program to run when using the CVS server and accepting
- * patches across the network. Specify a full pathname if your site
- * wants to use a particular patch.
- */
-#ifndef PATCH_PROGRAM
-#define PATCH_PROGRAM "patch"
-#endif
-
-/* Directory used for storing temporary files, if not overridden by
- environment variables or the -T global option. There should be little
- need to change this (-T is a better mechanism if you need to use a
- different directory for temporary files). */
-#ifndef TMPDIR_DFLT
-#define TMPDIR_DFLT "/tmp"
-#endif
-
-/*
- * The default editor to use, if one does not specify the "-e" option
- * to cvs, or does not have an EDITOR environment variable. I set
- * this to just "vi", and use the shell to find where "vi" actually
- * is. This allows sites with /usr/bin/vi or /usr/ucb/vi to work
- * equally well (assuming that your PATH is reasonable).
- */
-#ifndef EDITOR_DFLT
-#define EDITOR_DFLT "vi"
-#endif
-
-/*
- * The default umask to use when creating or otherwise setting file or
- * directory permissions in the repository. Must be a value in the
- * range of 0 through 0777. For example, a value of 002 allows group
- * rwx access and world rx access; a value of 007 allows group rwx
- * access but no world access. This value is overridden by the value
- * of the CVSUMASK environment variable, which is interpreted as an
- * octal number.
- */
-#ifndef UMASK_DFLT
-#define UMASK_DFLT 002
-#endif
-
-/*
- * The cvs admin command is restricted to the members of the group
- * CVS_ADMIN_GROUP. If this group does not exist, all users are
- * allowed to run cvs admin. To disable the cvs admin for all users,
- * create an empty group CVS_ADMIN_GROUP. To disable access control
- * for cvs admin, comment out the define below.
- */
-#ifndef CVS_ADMIN_GROUP
-#define CVS_ADMIN_GROUP "cvsadmin"
-#endif
-
-/*
- * The Repository file holds the path to the directory within the
- * source repository that contains the RCS ,v files for each CVS
- * working directory. This path is either a full-path or a path
- * relative to CVSROOT.
- *
- * The big advantage that I can see to having a relative path is that
- * one can change the physical location of the master source
- * repository, change the contents of CVS/Root files in your
- * checked-out code, and CVS will work without problems.
- *
- * Therefore, RELATIVE_REPOS is now the default. In the future, this
- * is likely to disappear entirely as a compile-time (or other) option,
- * so if you have other software which relies on absolute pathnames,
- * update them.
- */
-#define RELATIVE_REPOS 1
-
-/*
- * When committing or importing files, you must enter a log message.
- * Normally, you can do this either via the -m flag on the command
- * line or an editor will be started for you. If you like to use
- * logging templates (the rcsinfo file within the $CVSROOT/CVSROOT
- * directory), you might want to force people to use the editor even
- * if they specify a message with -m. Enabling FORCE_USE_EDITOR will
- * cause the -m message to be appended to the temp file when the
- * editor is started.
- */
-#ifndef FORCE_USE_EDITOR
-/* #define FORCE_USE_EDITOR */
-#endif
-
-/*
- * When locking the repository, some sites like to remove locks and
- * assume the program that created them went away if the lock has
- * existed for a long time. This used to be the default for previous
- * versions of CVS. CVS now attempts to be much more robust, so lock
- * files should not be left around by mistake. The new behaviour will
- * never remove old locks (they must now be removed by hand).
- * Enabling CVS_FUDGELOCKS will cause CVS to remove locks that are
- * older than CVSLCKAGE seconds.
- *
- * Use of this option is NOT recommended.
- */
-#ifndef CVS_FUDGELOCKS
-/* #define CVS_FUDGELOCKS */
-#endif
-
-/*
- * When committing a permanent change, CVS and RCS make a log entry of
- * who committed the change. If you are committing the change logged
- * in as "root" (not under "su" or other root-priv giving program),
- * CVS/RCS cannot determine who is actually making the change.
- *
- * As such, by default, CVS disallows changes to be committed by users
- * logged in as "root". You can disable this option by commenting out
- * the lines below.
- */
-#ifndef CVS_BADROOT
-#define CVS_BADROOT
-#endif
-
-/* Define this to enable the SETXID support. The way to use this is
- to create a group with no users in it (except perhaps cvs
- administrators), set the cvs executable to setgid that group, chown
- all the repository files to that group, and change all directory
- permissions in the repository to 770. The last person to modify a
- file will own it, but as long as directory permissions are set
- right that won't matter. You'll need a system which inherits file
- groups from the parent directory (WARNING: using the wrong kind of
- system (I think Solaris 2.4 is the wrong kind, for example) will
- create a security hole! You will receive no warning other than the
- fact that files in the working directory are owned by the group
- which cvs is setgid to).
-
- One security hole which has been reported is that setgid is not
- turned off when the editor is invoked--most editors provide a way
- to execute a shell, or the user can specify an editor (this one is
- large enough to drive a truck through). Don't assume that the
- holes described here are the only ones; I don't know how carefully
- SETXID has been inspected for security holes. */
-#ifndef SETXID_SUPPORT
-/* #define SETXID_SUPPORT */
-#endif
-
-/*
- * Should we build the password-authenticating client? Whether to
- * include the password-authenticating _server_, on the other hand, is
- * set in config.h.
- */
-#ifdef CLIENT_SUPPORT
-#define AUTH_CLIENT_SUPPORT 1
-#endif
-
-/*
- * If you are working with a large remote repository and a 'cvs
- * checkout' is swamping your network and memory, define these to
- * enable flow control. You will end up with even less probability of
- * a consistent checkout (see Concurrency in cvs.texinfo), but CVS
- * doesn't try to guarantee that anyway. The master server process
- * will monitor how far it is getting behind, if it reaches the high
- * water mark, it will signal the child process to stop generating
- * data when convenient (ie: no locks are held, currently at the
- * beginning of a new directory). Once the buffer has drained
- * sufficiently to reach the low water mark, it will be signalled to
- * start again. You may override the default hi/low watermarks here
- * too.
- */
-#define SERVER_FLOWCONTROL
-#define SERVER_HI_WATER (2 * 1024 * 1024)
-#define SERVER_LO_WATER (1 * 1024 * 1024)
-
-/* End of CVS configuration section */
-
-/*
- * Externs that are included in libc, but are used frequently enough
- * to warrant defining here.
- */
-#ifndef STDC_HEADERS
-extern void exit ();
-#endif
diff --git a/contrib/cvs/src/parseinfo.c b/contrib/cvs/src/parseinfo.c
index feccc71..c206fb7 100644
--- a/contrib/cvs/src/parseinfo.c
+++ b/contrib/cvs/src/parseinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -9,6 +9,8 @@
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -245,7 +247,6 @@ parse_config (cvsroot)
/* FIXME-reentrancy: If we do a multi-threaded server, this would need
to go to the per-connection data structures. */
static int parsed = 0;
- int ignore_unknown_config_keys = 0;
/* Authentication code and serve_root might both want to call us.
Let this happen smoothly. */
@@ -358,6 +359,25 @@ parse_config (cvsroot)
goto error_return;
}
}
+ else if (strcmp (line, "tag") == 0) {
+ RCS_setlocalid(p);
+ }
+ else if (strcmp (line, "umask") == 0) {
+ cvsumask = (mode_t)(strtol(p, NULL, 8) & 0777);
+ }
+ else if (strcmp (line, "dlimit") == 0) {
+#ifdef BSD
+#include <sys/resource.h>
+ struct rlimit rl;
+
+ if (getrlimit(RLIMIT_DATA, &rl) != -1) {
+ rl.rlim_cur = atoi(p);
+ rl.rlim_cur *= 1024;
+
+ (void) setrlimit(RLIMIT_DATA, &rl);
+ }
+#endif /* BSD */
+ }
else if (strcmp (line, "PreservePermissions") == 0)
{
if (strcmp (p, "no") == 0)
@@ -416,23 +436,16 @@ warning: this CVS does not support PreservePermissions");
else if (strcmp (p, "stat") == 0)
RereadLogAfterVerify = LOGMSG_REREAD_STAT;
}
- else if (strcmp (line, "IgnoreUnknownConfigKeys") == 0)
+ else if (strcmp(line, "LocalKeyword") == 0)
{
- if (strcmp (p, "no") == 0 || strcmp (p, "false") == 0
- || strcmp (p, "off") == 0 || strcmp (p, "0") == 0)
- ignore_unknown_config_keys = 0;
- else if (strcmp (p, "yes") == 0 || strcmp (p, "true") == 0
- || strcmp (p, "on") == 0 || strcmp (p, "1") == 0)
- ignore_unknown_config_keys = 1;
- else
- {
- error (0, 0, "%s: unrecognized value '%s' for '%s'",
- infopath, p, line);
- goto error_return;
- }
+ /* Recognize cvs-1.12-style keyword control rather than erroring out. */
+ RCS_setlocalid(p);
+ }
+ else if (strcmp(line, "KeywordExpand") == 0)
+ {
+ /* Recognize cvs-1.12-style keyword control rather than erroring out. */
+ RCS_setincexc(p);
}
- else if (ignore_unknown_config_keys)
- ;
else
{
/* We may be dealing with a keyword which was added in a
diff --git a/contrib/cvs/src/patch.c b/contrib/cvs/src/patch.c
index 9af10a6..65f5051 100644
--- a/contrib/cvs/src/patch.c
+++ b/contrib/cvs/src/patch.c
@@ -15,6 +15,8 @@
* Create a Larry Wall format "patch" file between a previous release and the
* current head of a module, or between two releases. Can specify the
* release as either a date or a revision number.
+ *
+ * $FreeBSD$
*/
#include <assert.h>
diff --git a/contrib/cvs/src/rcs.c b/contrib/cvs/src/rcs.c
index 73ce8ea..fe51dd0 100644
--- a/contrib/cvs/src/rcs.c
+++ b/contrib/cvs/src/rcs.c
@@ -12,6 +12,8 @@
*
* The routines contained in this file do all the rcs file parsing and
* manipulation
+ *
+ * $FreeBSD$
*/
#include <assert.h>
@@ -30,15 +32,7 @@
# endif
#endif
-#ifdef MMAP_FALLBACK_TEST
-void *my_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
-{
- if (rand() & 1) return mmap(addr, len, prot, flags, fd, offset);
- return NULL;
-}
-#define mmap my_mmap
-#endif
-
+int datesep = '/';
int preserve_perms = 0;
/* The RCS -k options, and a set of enums that must match the array.
@@ -74,8 +68,6 @@ struct rcsbuffer
this is non-zero, we must search the string for pairs of '@'
and convert them to a single '@'. */
int embedded_at;
- /* Whether the buffer has been mmap'ed or not. */
- int mmapped;
};
static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile));
@@ -87,8 +79,10 @@ static void rcsbuf_close PROTO ((struct rcsbuffer *));
static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp,
char **valp));
static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp));
+#ifndef HAVE_MMAP
static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp,
char **valp));
+#endif
static int rcsbuf_valcmp PROTO ((struct rcsbuffer *));
static char *rcsbuf_valcopy PROTO ((struct rcsbuffer *, char *val, int polish,
size_t *lenp));
@@ -149,6 +143,8 @@ static char *rcs_lockfilename PROTO ((const char *));
evaluates its arguments multiple times. */
#define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0)
+static char * getfullCVSname PROTO ((char *, char **));
+
/*
* We don't want to use isspace() from the C library because:
*
@@ -838,8 +834,8 @@ warning: duplicate key `%s' in version `%s' of RCS file `%s'",
op = *cp++;
if (op != 'a' && op != 'd')
error (1, 0, "\
-unrecognized operation '\\x%x' in %s revision %s",
- op, rcs->path, vnode->version);
+unrecognized operation '\\x%x' in %s",
+ op, rcs->path);
(void) strtoul (cp, (char **) &cp, 10);
if (*cp++ != ' ')
error (1, 0, "space expected in %s revision %s",
@@ -1038,58 +1034,46 @@ rcsbuf_open (rcsbuf, fp, filename, pos)
const char *filename;
unsigned long pos;
{
-#ifdef HAVE_MMAP
- void *p;
- struct stat fs;
- size_t mmap_off = 0;
-#endif
-
if (rcsbuf_inuse)
error (1, 0, "rcsbuf_open: internal error");
rcsbuf_inuse = 1;
#ifdef HAVE_MMAP
- /* When we have mmap, it is much more efficient to let the system do the
- * buffering and caching for us
- */
+ {
+ /* When we have mmap, it is much more efficient to let the system do the
+ * buffering and caching for us
+ */
+ struct stat fs;
+ size_t mmap_off = 0;
- if ( fstat (fileno(fp), &fs) < 0 )
- error ( 1, errno, "Could not stat RCS archive %s for mapping", filename );
+ if ( fstat (fileno(fp), &fs) < 0 )
+ error ( 1, errno, "Could not stat RCS archive %s for mapping", filename );
- if (pos)
- {
- size_t ps = getpagesize ();
- mmap_off = ( pos / ps ) * ps;
- }
+ if (pos)
+ {
+ size_t ps = getpagesize ();
+ mmap_off = ( pos / ps ) * ps;
+ }
+
+ /* Map private here since this particular buffer is read only */
+ rcsbuf_buffer = mmap ( NULL, fs.st_size - mmap_off,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fileno(fp), mmap_off );
+ if ( rcsbuf_buffer == NULL || rcsbuf_buffer == MAP_FAILED )
+ error ( 1, errno, "Could not map memory to RCS archive %s", filename );
- /* Map private here since this particular buffer is read only */
- p = mmap ( NULL, fs.st_size - mmap_off, PROT_READ | PROT_WRITE,
- MAP_PRIVATE, fileno(fp), mmap_off );
- if (p != NULL && p != MAP_FAILED)
- {
- if (rcsbuf_buffer) free (rcsbuf_buffer);
- rcsbuf_buffer = p;
rcsbuf_buffer_size = fs.st_size - mmap_off;
- rcsbuf->mmapped = 1;
rcsbuf->ptr = rcsbuf_buffer + pos - mmap_off;
rcsbuf->ptrend = rcsbuf_buffer + fs.st_size - mmap_off;
rcsbuf->pos = mmap_off;
}
- else
- {
-#ifndef MMAP_FALLBACK_TEST
- error (0, errno, "Could not map memory to RCS archive %s", filename);
-#endif
-#endif /* HAVE_MMAP */
- if (rcsbuf_buffer_size < RCSBUF_BUFSIZE)
+#else /* HAVE_MMAP */
+ if (rcsbuf_buffer_size < RCSBUF_BUFSIZE)
expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, RCSBUF_BUFSIZE);
- rcsbuf->mmapped = 0;
- rcsbuf->ptr = rcsbuf_buffer;
- rcsbuf->ptrend = rcsbuf_buffer;
- rcsbuf->pos = pos;
-#ifdef HAVE_MMAP
- }
+ rcsbuf->ptr = rcsbuf_buffer;
+ rcsbuf->ptrend = rcsbuf_buffer;
+ rcsbuf->pos = pos;
#endif /* HAVE_MMAP */
rcsbuf->fp = fp;
rcsbuf->filename = filename;
@@ -1107,12 +1091,7 @@ rcsbuf_close (rcsbuf)
if (! rcsbuf_inuse)
error (1, 0, "rcsbuf_close: internal error");
#ifdef HAVE_MMAP
- if (rcsbuf->mmapped)
- {
- munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
- rcsbuf_buffer = NULL;
- rcsbuf_buffer_size = 0;
- }
+ munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
#endif
rcsbuf_inuse = 0;
}
@@ -1157,10 +1136,11 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
assert (ptr >= rcsbuf_buffer && ptr <= rcsbuf_buffer + rcsbuf_buffer_size);
assert (ptrend >= rcsbuf_buffer && ptrend <= rcsbuf_buffer + rcsbuf_buffer_size);
+#ifndef HAVE_MMAP
/* If the pointer is more than RCSBUF_BUFSIZE bytes into the
buffer, move back to the start of the buffer. This keeps the
buffer from growing indefinitely. */
- if (!rcsbuf->mmapped && ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+ if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
{
int len;
@@ -1179,18 +1159,23 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
ptrend = ptr + len;
rcsbuf->ptrend = ptrend;
}
+#endif /* ndef HAVE_MMAP */
/* Skip leading whitespace. */
while (1)
{
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
+#endif
return 0;
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
c = *ptr;
if (! my_whitespace (c))
@@ -1209,13 +1194,17 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
{
++ptr;
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
if (ptr == NULL)
+#endif
error (1, 0, "EOF in key in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
c = *ptr;
if (c == ';' || my_whitespace (c))
break;
@@ -1244,13 +1233,17 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
if (ptr == NULL)
+#endif
error (1, 0, "EOF while looking for value in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
c = *ptr;
if (c == ';')
{
@@ -1285,6 +1278,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
+#ifndef HAVE_MMAP
{
/* Note that we pass PTREND as the PTR value to
rcsbuf_fill, so that we will wind up setting PTR to
@@ -1292,25 +1286,31 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
that we don't search the same bytes again. */
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
+#endif
error (1, 0,
"EOF while looking for end of string in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
/* Handle the special case of an '@' right at the end of
the known bytes. */
if (pat + 1 >= ptrend)
+#ifndef HAVE_MMAP
{
/* Note that we pass PAT, not PTR, here. */
pat = rcsbuf_fill (rcsbuf, pat, keyp, valp);
if (pat == NULL)
{
+#endif
/* EOF here is OK; it just means that the last
character of the file was an '@' terminating a
value for a key type which does not require a
trailing ';'. */
pat = rcsbuf->ptrend - 1;
+#ifndef HAVE_MMAP
}
ptrend = rcsbuf->ptrend;
@@ -1318,6 +1318,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
/* Note that the value of PTR is bogus here. This is
OK, because we don't use it. */
}
+#endif
if (pat + 1 >= ptrend || pat[1] != '@')
break;
@@ -1367,13 +1368,17 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
char n;
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
if (ptr == NULL)
+#endif
error (1, 0, "EOF in value in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
n = *ptr;
if (n == ';')
{
@@ -1408,6 +1413,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
/* Find the ';' which must end the value. */
start = ptr;
while ((psemi = memchr (ptr, ';', ptrend - ptr)) == NULL)
+#ifndef HAVE_MMAP
{
int slen;
@@ -1418,10 +1424,13 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
slen = start - *valp;
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
+#endif
error (1, 0, "EOF in value in RCS file %s", rcsbuf->filename);
+#ifndef HAVE_MMAP
start = *valp + slen;
ptrend = rcsbuf->ptrend;
}
+#endif
/* See if there are any '@' strings in the value. */
pat = memchr (start, '@', psemi - start);
@@ -1465,6 +1474,7 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
while (1)
{
while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
+#ifndef HAVE_MMAP
{
/* Note that we pass PTREND as the PTR value to
rcsbuff_fill, so that we will wind up setting PTR
@@ -1472,22 +1482,29 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
that we don't search the same bytes again. */
ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
if (ptr == NULL)
+#endif
error (1, 0,
"EOF while looking for end of string in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
/* Handle the special case of an '@' right at the end of
the known bytes. */
if (pat + 1 >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
if (ptr == NULL)
+#endif
error (1, 0, "EOF in value in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
if (pat[1] != '@')
break;
@@ -1530,12 +1547,16 @@ rcsbuf_getrevnum (rcsbuf, revp)
while (1)
{
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
if (ptr == NULL)
+#endif
return 0;
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
c = *ptr;
if (! whitespace (c))
@@ -1556,14 +1577,18 @@ unexpected '\\x%x' reading revision number in RCS file %s",
{
++ptr;
if (ptr >= ptrend)
+#ifndef HAVE_MMAP
{
ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL);
if (ptr == NULL)
+#endif
error (1, 0,
"unexpected EOF reading revision number in RCS file %s",
rcsbuf->filename);
+#ifndef HAVE_MMAP
ptrend = rcsbuf->ptrend;
}
+#endif
c = *ptr;
}
@@ -1581,6 +1606,7 @@ unexpected '\\x%x' reading revision number in RCS file %s",
return 1;
}
+#ifndef HAVE_MMAP
/* Fill RCSBUF_BUFFER with bytes from the file associated with RCSBUF,
updating PTR and the PTREND field. If KEYP and *KEYP are not NULL,
then *KEYP points into the buffer, and must be adjusted if the
@@ -1596,9 +1622,6 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
{
int got;
- if (rcsbuf->mmapped)
- return NULL;
-
if (rcsbuf->ptrend - rcsbuf_buffer + RCSBUF_BUFSIZE > rcsbuf_buffer_size)
{
int poff, peoff, koff, voff;
@@ -1631,6 +1654,7 @@ rcsbuf_fill (rcsbuf, ptr, keyp, valp)
return ptr;
}
+#endif /* HAVE_MMAP */
/* Test whether the last value returned by rcsbuf_getkey is a composite
value or not. */
@@ -1942,7 +1966,7 @@ static unsigned long
rcsbuf_ftell (rcsbuf)
struct rcsbuffer *rcsbuf;
{
- return rcsbuf->pos + (rcsbuf->ptr - rcsbuf_buffer);
+ return rcsbuf->pos + rcsbuf->ptr - rcsbuf_buffer;
}
/* Return a pointer to any data buffered for RCSBUF, along with the
@@ -2008,7 +2032,8 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
FILE **pfp;
struct rcsbuffer *prcsbuf;
{
- if (cached_rcs == rcs && !cached_rcsbuf.mmapped)
+#ifndef HAVE_MMAP
+ if (cached_rcs == rcs)
{
if (rcsbuf_ftell (&cached_rcsbuf) != pos)
{
@@ -2038,6 +2063,7 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
}
else
{
+#endif /* ifndef HAVE_MMAP */
/* FIXME: If these routines can be rewritten to not write to the
* rcs file buffer, there would be a considerably larger memory savings
* from using mmap since the shared file would never need be copied to
@@ -2052,13 +2078,17 @@ rcsbuf_cache_open (rcs, pos, pfp, prcsbuf)
*pfp = CVS_FOPEN (rcs->path, FOPEN_BINARY_READ);
if (*pfp == NULL)
error (1, 0, "unable to reopen `%s'", rcs->path);
+#ifndef HAVE_MMAP
if (pos != 0)
{
if (fseek (*pfp, pos, SEEK_SET) != 0)
error (1, 0, "cannot fseek RCS file %s", rcs->path);
}
+#endif /* ifndef HAVE_MMAP */
rcsbuf_open (prcsbuf, *pfp, rcs->path, pos);
+#ifndef HAVE_MMAP
}
+#endif /* ifndef HAVE_MMAP */
}
@@ -2514,13 +2544,25 @@ RCS_magicrev (rcs, rev)
char *rev;
{
int rev_num;
- char *xrev, *test_branch;
+ char *xrev, *test_branch, *local_branch_num;
xrev = xmalloc (strlen (rev) + 14); /* enough for .0.number */
check_rev = xrev;
+ local_branch_num = getenv("CVS_LOCAL_BRANCH_NUM");
+ if (local_branch_num)
+ {
+ rev_num = atoi(local_branch_num);
+ if (rev_num < 2)
+ rev_num = 2;
+ else
+ rev_num &= ~1;
+ }
+ else
+ rev_num = 2;
+
/* only look at even numbered branches */
- for (rev_num = 2; ; rev_num += 2)
+ for ( ; ; rev_num += 2)
{
/* see if the physical branch exists */
(void) sprintf (xrev, "%s.%d", rev, rev_num);
@@ -3506,27 +3548,31 @@ struct rcs_keyword
{
const char *string;
size_t len;
+ int expandit;
};
#define KEYWORD_INIT(s) (s), sizeof (s) - 1
-static const struct rcs_keyword keywords[] =
+static struct rcs_keyword keywords[] =
{
- { KEYWORD_INIT ("Author") },
- { KEYWORD_INIT ("Date") },
- { KEYWORD_INIT ("Header") },
- { KEYWORD_INIT ("Id") },
- { KEYWORD_INIT ("Locker") },
- { KEYWORD_INIT ("Log") },
- { KEYWORD_INIT ("Name") },
- { KEYWORD_INIT ("RCSfile") },
- { KEYWORD_INIT ("Revision") },
- { KEYWORD_INIT ("Source") },
- { KEYWORD_INIT ("State") },
- { NULL, 0 }
+ { KEYWORD_INIT ("Author"), 1 },
+ { KEYWORD_INIT ("Date"), 1 },
+ { KEYWORD_INIT ("CVSHeader"), 1 },
+ { KEYWORD_INIT ("Header"), 1 },
+ { KEYWORD_INIT ("Id"), 1 },
+ { KEYWORD_INIT ("Locker"), 1 },
+ { KEYWORD_INIT ("Log"), 1 },
+ { KEYWORD_INIT ("Name"), 1 },
+ { KEYWORD_INIT ("RCSfile"), 1 },
+ { KEYWORD_INIT ("Revision"), 1 },
+ { KEYWORD_INIT ("Source"), 1 },
+ { KEYWORD_INIT ("State"), 1 },
+ { NULL, 0, 0 },
+ { NULL, 0, 0 }
};
enum keyword
{
KEYWORD_AUTHOR = 0,
KEYWORD_DATE,
+ KEYWORD_CVSHEADER,
KEYWORD_HEADER,
KEYWORD_ID,
KEYWORD_LOCKER,
@@ -3535,8 +3581,10 @@ enum keyword
KEYWORD_RCSFILE,
KEYWORD_REVISION,
KEYWORD_SOURCE,
- KEYWORD_STATE
+ KEYWORD_STATE,
+ KEYWORD_LOCALID
};
+enum keyword keyword_local = KEYWORD_ID;
/* Convert an RCS date string into a readable string. This is like
the RCS date2str function. */
@@ -3552,8 +3600,8 @@ printable_date (rcs_date)
&sec);
if (year < 1900)
year += 1900;
- sprintf (buf, "%04d/%02d/%02d %02d:%02d:%02d", year, mon, mday,
- hour, min, sec);
+ sprintf (buf, "%04d%c%02d%c%02d %02d:%02d:%02d",
+ year, datesep, mon, datesep, mday, hour, min, sec);
return xstrdup (buf);
}
@@ -3714,7 +3762,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
slen = s - srch;
for (keyword = keywords; keyword->string != NULL; keyword++)
{
- if (keyword->len == slen
+ if (keyword->expandit
+ && keyword->len == slen
&& strncmp (keyword->string, srch, slen) == 0)
{
break;
@@ -3761,15 +3810,25 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
free_value = 1;
break;
+ case KEYWORD_CVSHEADER:
case KEYWORD_HEADER:
case KEYWORD_ID:
+ case KEYWORD_LOCALID:
{
const char *path;
int free_path;
char *date;
+ char *old_path;
- if (kw == KEYWORD_HEADER)
+ old_path = NULL;
+ if (kw == KEYWORD_HEADER ||
+ (kw == KEYWORD_LOCALID &&
+ keyword_local == KEYWORD_HEADER))
path = rcs->path;
+ else if (kw == KEYWORD_CVSHEADER ||
+ (kw == KEYWORD_LOCALID &&
+ keyword_local == KEYWORD_CVSHEADER))
+ path = getfullCVSname(rcs->path, &old_path);
else
path = last_component (rcs->path);
path = escape_keyword_value (path, &free_path);
@@ -3792,6 +3851,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
* and we can discard the const.
*/
free ((char *)path);
+ if (old_path)
+ free (old_path);
free (date);
free_value = 1;
}
@@ -4140,8 +4201,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
{
int free_rev = 0;
enum kflag expand;
- FILE *fp;
- FILE *ofp = NULL;
+ FILE *fp, *ofp;
struct stat sb;
struct rcsbuffer rcsbuf;
char *key;
@@ -6260,25 +6320,6 @@ findtag (node, arg)
return 0;
}
-static int findmagictag PROTO ((Node *, void *));
-
-/* Return a nonzero value if a magic tag rooted at ARG is found. */
-
-static int
-findmagictag (node, arg)
- Node *node;
- void *arg;
-{
- char *rev = (char *)arg;
- size_t len = strlen (rev);
-
- if (strncmp (node->data, rev, len) == 0 &&
- strncmp ((char *)node->data + len, ".0.", 3) == 0)
- return 1;
- else
- return 0;
-}
-
/* Delete revisions between REV1 and REV2. The changes between the two
revisions must be collapsed, and the result stored in the revision
immediately preceding the lower one. Return 0 for successful completion,
@@ -6538,9 +6579,8 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
/* Doing this only for the :: syntax is for compatibility.
See cvs.texinfo for somewhat more discussion. */
- if (!inclusive &&
- (walklist (RCS_symbols (rcs), findtag, revp->version) ||
- walklist (RCS_symbols (rcs), findmagictag, revp->version)))
+ if (!inclusive
+ && walklist (RCS_symbols (rcs), findtag, revp->version))
{
/* We don't print which file this happens to on the theory
that the caller will print the name of the file in a
@@ -6997,6 +7037,31 @@ linevector_add (vec, text, len, vers, pos)
return 1;
}
+static void linevector_delete PROTO ((struct linevector *, unsigned int,
+ unsigned int));
+
+/* Remove NLINES lines from VEC at position POS (where line 0 is the
+ first line). */
+static void
+linevector_delete (vec, pos, nlines)
+ struct linevector *vec;
+ unsigned int pos;
+ unsigned int nlines;
+{
+ unsigned int i;
+ unsigned int last;
+
+ last = vec->nlines - nlines;
+ for (i = pos; i < pos + nlines; ++i)
+ {
+ if (--vec->vector[i]->refcount == 0)
+ free (vec->vector[i]);
+ }
+ for (i = pos; i < last; ++i)
+ vec->vector[i] = vec->vector[i + nlines];
+ vec->nlines -= nlines;
+}
+
static void linevector_copy PROTO ((struct linevector *, struct linevector *));
/* Copy FROM to TO, copying the vectors but not the lines pointed to. */
@@ -7040,7 +7105,7 @@ linevector_free (vec)
if (vec->vector != NULL)
{
for (ln = 0; ln < vec->nlines; ++ln)
- if (vec->vector[ln] && --vec->vector[ln]->refcount == 0)
+ if (--vec->vector[ln]->refcount == 0)
free (vec->vector[ln]);
free (vec->vector);
@@ -7075,27 +7140,20 @@ apply_rcs_changes PROTO ((struct linevector *, const char *, size_t,
const char *, RCSVers *, RCSVers *));
/* Apply changes to the line vector LINES. DIFFBUF is a buffer of
- * length DIFFLEN holding the change text from an RCS file (the output
- * of diff -n). NAME is used in error messages. The VERS field of
- * any line added is set to ADDVERS. The VERS field of any line
- * deleted is set to DELVERS, unless DELVERS is NULL, in which case
- * the VERS field of deleted lines is unchanged.
- *
- * RETURNS
- * Non-zero if the change text is applied successfully to ORIG_LINES.
- *
- * If the change text does not appear to apply to ORIG_LINES (e.g., a
- * line number is invalid), this function will return zero and ORIG_LINES
- * will remain unmolested.
- *
- * ERRORS
- * If the change text is improperly formatted (e.g., it is not the output
- * of diff -n), the function calls error with a status of 1, causing the
- * program to exit.
- */
+ length DIFFLEN holding the change text from an RCS file (the output
+ of diff -n). NAME is used in error messages. The VERS field of
+ any line added is set to ADDVERS. The VERS field of any line
+ deleted is set to DELVERS, unless DELVERS is NULL, in which case
+ the VERS field of deleted lines is unchanged. The function returns
+ non-zero if the change text is applied successfully. It returns
+ zero if the change text does not appear to apply to LINES (e.g., a
+ line number is invalid). If the change text is improperly
+ formatted (e.g., it is not the output of diff -n), the function
+ calls error with a status of 1, causing the program to exit. */
+
static int
-apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
- struct linevector *orig_lines;
+apply_rcs_changes (lines, diffbuf, difflen, name, addvers, delvers)
+ struct linevector *lines;
const char *diffbuf;
size_t difflen;
const char *name;
@@ -7117,15 +7175,10 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
struct deltafrag *next;
};
struct deltafrag *dfhead;
- struct deltafrag **dftail;
struct deltafrag *df;
- unsigned long numlines, lastmodline, offset;
- struct linevector lines;
int err;
dfhead = NULL;
- dftail = &dfhead;
- numlines = orig_lines->nlines; /* start with init # of lines */
for (p = diffbuf; p != NULL && p < diffbuf + difflen; )
{
op = *p++;
@@ -7134,9 +7187,9 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
of op determines the syntax. */
error (1, 0, "unrecognized operation '\\x%x' in %s",
op, name);
- *dftail = df = xmalloc (sizeof *df);
- *(dftail = &df->next) = NULL;
-
+ df = (struct deltafrag *) xmalloc (sizeof (struct deltafrag));
+ df->next = dfhead;
+ dfhead = df;
df->pos = strtoul (p, (char **) &q, 10);
if (p == q)
@@ -7177,7 +7230,6 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
df->len = q - p;
p = q;
- numlines += df->nlines;
}
else
{
@@ -7187,155 +7239,41 @@ apply_rcs_changes (orig_lines, diffbuf, difflen, name, addvers, delvers)
assert (op == 'd');
df->type = FRAG_DELETE;
- numlines -= df->nlines;
}
}
- /* New temp data structure to hold new org before
- copy back into original structure. */
- lines.nlines = lines.lines_alloced = numlines;
- lines.vector = xmalloc (numlines * sizeof *lines.vector);
-
- /* We changed the list order to first to last -- so the
- list never gets larger than the size numlines. */
- lastmodline = 0;
-
- /* offset created when adding/removing lines
- between new and original structure */
- offset = 0;
err = 0;
- for (df = dfhead; df != NULL; )
+ for (df = dfhead; df != NULL;)
{
unsigned int ln;
- unsigned long deltaend;
-
- if (df->pos > orig_lines->nlines)
- err = 1;
- /* On error, just free the rest of the list. */
+ /* Once an error is encountered, just free the rest of the list and
+ * return.
+ */
if (!err)
- {
- /* Here we need to get to the line where the next insert will
- begin, which is DF->pos in ORIG_LINES. We will fill up to
- DF->pos - OFFSET in LINES with original items. */
- for (deltaend = df->pos - offset;
- lastmodline < deltaend;
- lastmodline++)
- {
- /* we need to copy from the orig structure into new one */
- lines.vector[lastmodline] =
- orig_lines->vector[lastmodline + offset];
- lines.vector[lastmodline]->refcount++;
- }
-
switch (df->type)
{
- case FRAG_ADD:
- {
- const char *textend, *p;
- const char *nextline_text;
- struct line *q;
- int nextline_newline;
- size_t nextline_len;
-
- textend = df->new_lines + df->len;
- nextline_newline = 0;
- nextline_text = df->new_lines;
- for (p = df->new_lines; p < textend; ++p)
- {
- if (*p == '\n')
- {
- nextline_newline = 1;
- if (p + 1 == textend)
- {
- /* If there are no characters beyond the
- last newline, we don't consider it
- another line. */
- break;
- }
-
- nextline_len = p - nextline_text;
- q = xmalloc (sizeof *q + nextline_len);
- q->vers = addvers;
- q->text = (char *)(q + 1);
- q->len = nextline_len;
- q->has_newline = nextline_newline;
- q->refcount = 1;
- memcpy (q->text, nextline_text, nextline_len);
- lines.vector[lastmodline++] = q;
- offset--;
-
- nextline_text = (char *)p + 1;
- nextline_newline = 0;
- }
- }
- nextline_len = p - nextline_text;
- q = xmalloc (sizeof *q + nextline_len);
- q->vers = addvers;
- q->text = (char *)(q + 1);
- q->len = nextline_len;
- q->has_newline = nextline_newline;
- q->refcount = 1;
- memcpy (q->text, nextline_text, nextline_len);
- lines.vector[lastmodline++] = q;
-
- /* For each line we add the offset between the #'s
- decreases. */
- offset--;
- break;
- }
-
- case FRAG_DELETE:
- /* we are removing this many lines from the source. */
- offset += df->nlines;
-
- if (df->pos + df->nlines > orig_lines->nlines)
- err = 1;
- else if (delvers)
- for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
- if (orig_lines->vector[ln]->refcount > 1)
- /* Annotate needs this but, since the original
- * vector is disposed of before returning from
- * this function, we only need keep track if
- * there are multiple references.
- */
- orig_lines->vector[ln]->vers = delvers;
- break;
+ case FRAG_ADD:
+ if (! linevector_add (lines, df->new_lines, df->len, addvers,
+ df->pos))
+ err = 1;
+ break;
+ case FRAG_DELETE:
+ if (df->pos > lines->nlines
+ || df->pos + df->nlines > lines->nlines)
+ return 0;
+ if (delvers != NULL)
+ for (ln = df->pos; ln < df->pos + df->nlines; ++ln)
+ lines->vector[ln]->vers = delvers;
+ linevector_delete (lines, df->pos, df->nlines);
+ break;
}
- }
df = df->next;
free (dfhead);
dfhead = df;
}
- if (err)
- {
- /* No reason to try and move a half-mutated and known invalid
- * text into the output buffer.
- */
- linevector_free (&lines);
- }
- else
- {
- /* add the rest of the remaining lines to the data vector */
- for (; lastmodline < numlines; lastmodline++)
- {
- /* we need to copy from the orig structure into new one */
- lines.vector[lastmodline] = orig_lines->vector[lastmodline
- + offset];
- lines.vector[lastmodline]->refcount++;
- }
-
- /* Move the lines vector to the original structure for output,
- * first deleting the old.
- */
- linevector_free (orig_lines);
- orig_lines->vector = lines.vector;
- orig_lines->lines_alloced = numlines;
- orig_lines->nlines = lines.nlines;
- }
-
return !err;
}
@@ -8408,8 +8346,10 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
char *bufrest;
int nls;
size_t buflen;
+#ifndef HAVE_MMAP
char buf[8192];
int got;
+#endif
/* Count the number of versions for which we have to do some
special operation. */
@@ -8523,30 +8463,29 @@ RCS_copydeltas (rcs, fin, rcsbufin, fout, newdtext, insertpt)
fwrite (bufrest, 1, buflen, fout);
}
- if (!rcsbufin->mmapped)
+#ifndef HAVE_MMAP
+ /* This bit isn't necessary when using mmap since the entire file
+ * will already be available via the RCS buffer. Besides, the
+ * mmap code doesn't always keep the file pointer up to date, so
+ * this adds some data twice.
+ */
+ while ((got = fread (buf, 1, sizeof buf, fin)) != 0)
{
- /* This bit isn't necessary when using mmap since the entire file
- * will already be available via the RCS buffer. Besides, the
- * mmap code doesn't always keep the file pointer up to date, so
- * this adds some data twice.
- */
- while ((got = fread (buf, 1, sizeof buf, fin)) != 0)
+ if (nls > 0
+ && got >= nls
+ && buf[0] == '\n'
+ && strncmp (buf, "\n\n\n", nls) == 0)
{
- if (nls > 0
- && got >= nls
- && buf[0] == '\n'
- && strncmp (buf, "\n\n\n", nls) == 0)
- {
- fwrite (buf + 1, 1, got - 1, fout);
- }
- else
- {
- fwrite (buf, 1, got, fout);
- }
+ fwrite (buf + 1, 1, got - 1, fout);
+ }
+ else
+ {
+ fwrite (buf, 1, got, fout);
+ }
nls = 0;
- }
}
+#endif /* HAVE_MMAP */
}
/* A helper procedure for RCS_copydeltas. This is called via walklist
@@ -8934,3 +8873,105 @@ make_file_label (path, rev, rcs)
}
return label;
}
+
+void
+RCS_setlocalid (arg)
+ const char *arg;
+{
+ char *copy, *next, *key;
+
+ copy = xstrdup(arg);
+ next = copy;
+ key = strtok(next, "=");
+
+ keywords[KEYWORD_LOCALID].string = xstrdup(key);
+ keywords[KEYWORD_LOCALID].len = strlen(key);
+ keywords[KEYWORD_LOCALID].expandit = 1;
+
+ /* options? */
+ while (key = strtok(NULL, ",")) {
+ if (!strcmp(key, keywords[KEYWORD_ID].string))
+ keyword_local = KEYWORD_ID;
+ else if (!strcmp(key, keywords[KEYWORD_HEADER].string))
+ keyword_local = KEYWORD_HEADER;
+ else if (!strcmp(key, keywords[KEYWORD_CVSHEADER].string))
+ keyword_local = KEYWORD_CVSHEADER;
+ else
+ error(1, 0, "Unknown LocalId mode: %s", key);
+ }
+ free(copy);
+}
+
+void
+RCS_setincexc (arg)
+ const char *arg;
+{
+ char *key;
+ char *copy, *next;
+ int include = 0;
+ struct rcs_keyword *keyword;
+
+ copy = xstrdup(arg);
+ next = copy;
+ switch (*next++) {
+ case 'e':
+ include = 0;
+ break;
+ case 'i':
+ include = 1;
+ break;
+ default:
+ free(copy);
+ return;
+ }
+
+ if (include)
+ for (keyword = keywords; keyword->string != NULL; keyword++)
+ {
+ keyword->expandit = 0;
+ }
+
+ key = strtok(next, ",");
+ while (key) {
+ for (keyword = keywords; keyword->string != NULL; keyword++) {
+ if (strcmp (keyword->string, key) == 0)
+ keyword->expandit = include;
+ }
+ key = strtok(NULL, ",");
+ }
+ free(copy);
+ return;
+}
+
+#define ATTIC "/" CVSATTIC
+static char *
+getfullCVSname(CVSname, pathstore)
+ char *CVSname, **pathstore;
+{
+ if (current_parsed_root->directory) {
+ int rootlen;
+ char *c = NULL;
+ int alen = sizeof(ATTIC) - 1;
+
+ *pathstore = xstrdup(CVSname);
+ if ((c = strrchr(*pathstore, '/')) != NULL) {
+ if (c - *pathstore >= alen) {
+ if (!strncmp(c - alen, ATTIC, alen)) {
+ while (*c != '\0') {
+ *(c - alen) = *c;
+ c++;
+ }
+ *(c - alen) = '\0';
+ }
+ }
+ }
+
+ rootlen = strlen(current_parsed_root->directory);
+ if (!strncmp(*pathstore, current_parsed_root->directory, rootlen) &&
+ (*pathstore)[rootlen] == '/')
+ CVSname = (*pathstore + rootlen + 1);
+ else
+ CVSname = (*pathstore);
+ }
+ return CVSname;
+}
diff --git a/contrib/cvs/src/rcs.h b/contrib/cvs/src/rcs.h
index 3a66640..08b8a5f 100644
--- a/contrib/cvs/src/rcs.h
+++ b/contrib/cvs/src/rcs.h
@@ -11,6 +11,8 @@
* specified in the README file that comes with the CVS source distribution.
*
* RCS source control definitions needed by rcs.c and friends
+ *
+ * $FreeBSD$
*/
/* Strings which indicate a conflict if they occur at the start of a line. */
@@ -250,8 +252,11 @@ int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, const char *,
enum rcs_delta_op, char **, size_t *,
char **, size_t *));
+void RCS_setincexc PROTO ((const char *arg));
+void RCS_setlocalid PROTO ((const char *arg));
char *make_file_label PROTO ((const char *, const char *, RCSNode *));
+extern int datesep;
extern int preserve_perms;
/* From import.c. */
diff --git a/contrib/cvs/src/rcscmds.c b/contrib/cvs/src/rcscmds.c
index a9e576a..18182ff 100644
--- a/contrib/cvs/src/rcscmds.c
+++ b/contrib/cvs/src/rcscmds.c
@@ -12,6 +12,8 @@
*
* The functions in this file provide an interface for performing
* operations directly on RCS files.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index fb865a9..1fb33c1 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 1986-2008 The Free Software Foundation, Inc.
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
@@ -12,6 +12,7 @@
*
* General recursion handler
*
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -662,6 +663,7 @@ do_recursion (frame)
{
repository = frame->repository;
assert (repository != NULL);
+ assert (strstr (repository, "/./") == NULL);
}
fileattr_startdir (repository);
@@ -764,7 +766,7 @@ do_recursion (frame)
have writelocks in place, and there is no way to get writelocks
here. */
if (current_parsed_root->isremote)
- cvs_notify_check (repository, update_dir);
+ notify_check (repository, update_dir);
#endif /* CLIENT_SUPPORT */
finfo_struct.repository = repository;
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index 374c7d3..3262bba 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -8,6 +8,10 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. */
+/*
+ * $FreeBSD$
+ */
+
#include <assert.h>
#include "cvs.h"
#include "watch.h"
@@ -759,19 +763,6 @@ serve_root (arg)
return;
}
- /* We need to check :ext: server here, :pserver: checks happen below. */
- if (root_allow_used() && !root_allow_ok (arg)
-# ifdef AUTH_SERVER_SUPPORT
- && Pserver_Repos == NULL
-# endif
- )
- {
- if (alloc_pending (80 + strlen (arg)))
- sprintf (pending_error_text,
- "E Bad root %s", arg);
- return;
- }
-
#ifdef AUTH_SERVER_SUPPORT
if (Pserver_Repos != NULL)
{
@@ -795,6 +786,9 @@ E Protocol error: Root says \"%s\" but pserver says \"%s\"",
nothing. But for rsh, we need to do it now. */
parse_config (current_parsed_root->directory);
+ /* Now is a good time to read CVSROOT/options too. */
+ parseopts(current_parsed_root->directory);
+
path = xmalloc (strlen (current_parsed_root->directory)
+ sizeof (CVSROOTADM)
+ 2);
@@ -2767,7 +2761,7 @@ do_cvs_command (cmd_name, command)
int dev_null_fd = -1;
- int errs = 0;
+ int errs;
command_pid = -1;
stdout_pipe[0] = -1;
@@ -2966,8 +2960,9 @@ error \n");
#ifdef SERVER_FLOWCONTROL
{
char junk;
+ ssize_t status;
set_block_fd (flowcontrol_pipe[0]);
- while (read (flowcontrol_pipe[0], &junk, 1) > 0);
+ while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0);
}
/* FIXME: No point in printing an error message with error(),
* as STDERR is already closed, but perhaps this could be syslogged?
@@ -3999,11 +3994,38 @@ static void
serve_init (arg)
char *arg;
{
- if (alloc_pending (80 + strlen (arg)))
- sprintf (pending_error_text, "E init may not be run remotely");
+ cvsroot_t *saved_parsed_root;
+
+ if (!isabsolute (arg))
+ {
+ if (alloc_pending (80 + strlen (arg)))
+ sprintf (pending_error_text,
+ "E init %s must be an absolute pathname", arg);
+ }
+#ifdef AUTH_SERVER_SUPPORT
+ else if (Pserver_Repos != NULL)
+ {
+ if (strcmp (Pserver_Repos, arg) != 0)
+ {
+ if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
+ /* The explicitness is to aid people who are writing clients.
+ I don't see how this information could help an
+ attacker. */
+ sprintf (pending_error_text, "\
+E Protocol error: init says \"%s\" but pserver says \"%s\"",
+ arg, Pserver_Repos);
+ }
+ }
+#endif
if (print_pending_error ())
return;
+
+ saved_parsed_root = current_parsed_root;
+ current_parsed_root = local_cvsroot (arg);
+ do_cvs_command ("init", init);
+ free_cvsroot_t (current_parsed_root);
+ current_parsed_root = saved_parsed_root;
}
static void serve_annotate PROTO ((char *));
@@ -5665,7 +5687,10 @@ check_password (username, password, repository)
password file. If so, that's enough to authenticate with. If
not, we'll check /etc/passwd. */
- rc = check_repository_password (username, password, repository,
+ if (require_real_user)
+ rc = 0; /* "not found" */
+ else
+ rc = check_repository_password (username, password, repository,
&host_user);
if (rc == 2)
diff --git a/contrib/cvs/src/stamp-h2.in b/contrib/cvs/src/stamp-h2.in
deleted file mode 100644
index 9788f70..0000000
--- a/contrib/cvs/src/stamp-h2.in
+++ /dev/null
@@ -1 +0,0 @@
-timestamp
diff --git a/contrib/cvs/src/tag.c b/contrib/cvs/src/tag.c
index 6525eb2..43451ce 100644
--- a/contrib/cvs/src/tag.c
+++ b/contrib/cvs/src/tag.c
@@ -15,6 +15,8 @@
* Add or delete a symbolic name to an RCS file, or a collection of RCS files.
* Tag uses the checked out revision in the current directory, rtag uses
* the modules database, if necessary.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -1363,6 +1365,9 @@ Numeric tag %s contains characters other than digits and '.'", name);
|| strcmp (name, TAG_HEAD) == 0)
return;
+ if (readonlyfs)
+ return;
+
/* Verify that the tag is valid syntactically. Some later code once made
* assumptions about this.
*/
diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c
index 117561a..3d82ee4 100644
--- a/contrib/cvs/src/update.c
+++ b/contrib/cvs/src/update.c
@@ -36,6 +36,8 @@
* versions, these are updated too. If the -d option was specified, new
* directories added to the repository are automatically created and updated
* as well.
+ *
+ * $FreeBSD$
*/
#include "cvs.h"
@@ -101,10 +103,10 @@ static char *join_rev2, *date_rev2;
static int aflag = 0;
static int toss_local_changes = 0;
static int force_tag_match = 1;
+static int pull_template = 0;
static int update_build_dirs = 0;
static int update_prune_dirs = 0;
static int pipeout = 0;
-static int dotemplate = 0;
#ifdef SERVER_SUPPORT
static int patches = 0;
static int rcs_diff_patches = 0;
@@ -129,6 +131,7 @@ static const char *const update_usage[] =
"\t-j rev\tMerge in changes made between current revision and rev.\n",
"\t-I ign\tMore files to ignore (! to reset).\n",
"\t-W spec\tWrappers specification line.\n",
+ "\t-T\tCreate CVS/Template.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -144,6 +147,7 @@ update (argc, argv)
int c, err;
int local = 0; /* recursive by default */
int which; /* where to look for files and dirs */
+ int xpull_template = 0;
if (argc == -1)
usage (update_usage);
@@ -153,7 +157,7 @@ update (argc, argv)
/* parse the args */
optind = 0;
- while ((c = getopt (argc, argv, "+ApCPflRQqduk:r:D:j:I:W:")) != -1)
+ while ((c = getopt (argc, argv, "+ApCPflRQTqduk:r:D:j:I:W:")) != -1)
{
switch (c)
{
@@ -189,6 +193,9 @@ update (argc, argv)
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
break;
+ case 'T':
+ xpull_template = 1;
+ break;
case 'd':
update_build_dirs = 1;
break;
@@ -418,8 +425,8 @@ update (argc, argv)
/* call the command line interface */
err = do_update (argc, argv, options, tag, date, force_tag_match,
local, update_build_dirs, aflag, update_prune_dirs,
- pipeout, which, join_rev1, join_rev2, (char *) NULL, 1,
- (char *) NULL);
+ pipeout, which, join_rev1, join_rev2, (char *) NULL,
+ xpull_template, (char *) NULL);
/* free the space Make_Date allocated if necessary */
if (date != NULL)
@@ -436,7 +443,7 @@ update (argc, argv)
int
do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir,
- xdotemplate, repository)
+ xpull_template, repository)
int argc;
char **argv;
char *xoptions;
@@ -452,7 +459,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
char *xjoin_rev1;
char *xjoin_rev2;
char *preload_update_dir;
- int xdotemplate;
+ int xpull_template;
char *repository;
{
int err = 0;
@@ -467,7 +474,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
aflag = xaflag;
update_prune_dirs = xprune;
pipeout = xpipeout;
- dotemplate = xdotemplate;
+ pull_template = xpull_template;
/* setup the join support */
join_rev1 = xjoin_rev1;
@@ -604,7 +611,7 @@ update_fileproc (callerdat, finfo)
&& tag != NULL
&& finfo->rcs != NULL)
{
- char *rev = RCS_getversion (finfo->rcs, tag, NULL, 1, NULL);
+ char *rev = RCS_getversion (finfo->rcs, tag, date, 1, NULL);
if (rev != NULL
&& !RCS_nodeisbranch (finfo->rcs, tag))
nonbranch = 1;
@@ -937,7 +944,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
via WriteTag. */
0,
0,
- dotemplate);
+ pull_template);
rewrite_tag = 1;
nonbranch = 0;
Subdir_Register (entries, (char *) NULL, dir);
@@ -996,6 +1003,12 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
nonbranch = 0;
}
+ /* keep the CVS/Template file current */
+ if (pull_template)
+ {
+ WriteTemplate (dir, update_dir);
+ }
+
/* initialize the ignore list for this directory */
ignlist = getlist ();
}
@@ -1435,10 +1448,8 @@ VERS: ", 0);
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
{
- /* FIXME: It seems like we should be preserving ts_user
- * & ts_rcs here, but setting them causes problems in
- * join_file().
- */
+ /* FIXME: Throwing away the original revision info is almost
+ certainly wrong -- what if join_rev1 is "BASE"? */
if (vers_ts->vn_user != NULL)
free (vers_ts->vn_user);
if (vers_ts->vn_rcs != NULL)
@@ -1647,11 +1658,21 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum)
data.final_nl = 0;
data.compute_checksum = 0;
- /* Duplicating the client working file, so use the original sticky options.
+ /* FIXME - Passing vers_ts->tag here is wrong in the least number
+ * of cases. Since we don't know whether vn_user was checked out
+ * using a tag, we pass vers_ts->tag, which, assuming the user did
+ * not specify a new TAG to -r, will be the branch we are on.
+ *
+ * The only thing it is used for is to substitute in for the Name
+ * RCS keyword, so in the error case, the patch fails to apply on
+ * the client end and we end up resending the whole file.
+ *
+ * At least, if we are keeping track of the tag vn_user came from,
+ * I don't know where yet. -DRP
*/
retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
- vers_ts->vn_user, vers_ts->entdata->tag,
- vers_ts->entdata->options, RUN_TTY,
+ vers_ts->vn_user, vers_ts->tag,
+ vers_ts->options, RUN_TTY,
patch_file_write, (void *) &data);
if (fclose (e) < 0)
@@ -2209,7 +2230,6 @@ join_file (finfo, vers)
if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2))
{
char *mrev;
- short conflict = 0;
if (rev2 != NULL)
free (rev2);
@@ -2260,7 +2280,8 @@ join_file (finfo, vers)
|| vers->vn_user[0] == '-'
|| RCS_isdead (vers->srcfile, vers->vn_user))
{
- free (rev1);
+ if (rev1 != NULL)
+ free (rev1);
return;
}
@@ -2269,107 +2290,56 @@ join_file (finfo, vers)
resolve. No_Difference will already have been called in
this case, so comparing the timestamps is sufficient to
determine whether the file is locally modified. */
- if (/* may have changed on destination branch */
- /* file added locally */
- !strcmp (vers->vn_user, "0")
- || /* destination branch modified in repository */
- strcmp (rev1, vers->vn_user)
- || /* locally modified */
- vers->ts_user && strcmp (vers->ts_user, vers->ts_rcs))
+ if (strcmp (vers->vn_user, "0") == 0
+ || (vers->ts_user != NULL
+ && strcmp (vers->ts_user, vers->ts_rcs) != 0))
{
- /* The removal should happen if either the file has never changed
- * on the destination or the file has changed to be identical to
- * the first join revision.
- *
- * ------R-----------D
- * |
- * \----J1---J2-----S
- *
- * So:
- *
- * J2 is dead.
- * D is destination.
- * R is source branch root/GCA.
- * if J1 == D removal should happen
- * if D == R removal should happen
- * otherwise, fail.
- *
- * (In the source, J2 = REV2, D = user file (potentially VN_USER),
- * R = GCA computed below)
- */
- char *gca_rev1 = gca (rev1, vers->vn_user);
-#ifdef SERVER_SUPPORT
- if (server_active && !isreadable (finfo->file))
- {
- int retcode;
- /* The file is up to date. Need to check out the current
- * contents.
- */
- /* FIXME - see the FIXME comment above the call to RCS_checkout
- * in the patch_file function.
- */
- retcode = RCS_checkout (vers->srcfile, finfo->file,
- vers->vn_user, vers->tag,
- NULL, RUN_TTY, NULL, NULL);
- if (retcode)
- error (1, 0,
- "failed to check out %s file", finfo->fullname);
- }
-#endif
- if (/* genuinely changed on destination branch */
- RCS_cmp_file (vers->srcfile, gca_rev1, NULL,
- NULL, vers->options, finfo->file)
- && /* genuinely different from REV1 */
- RCS_cmp_file (vers->srcfile, rev1, NULL,
- NULL, vers->options, finfo->file))
- conflict = 1;
- }
-
- free (rev1);
-
- if (conflict)
- {
- char *cp;
-
- if (jdate2)
+ if (jdate2 != NULL)
error (0, 0,
- "file %s has been removed in revision %s as of %s, but the destination is incompatibly modified",
+ "file %s is locally modified, but has been removed in revision %s as of %s",
finfo->fullname, jrev2, jdate2);
else
error (0, 0,
- "file %s has been removed in revision %s, but the destination is incompatibly modified",
+ "file %s is locally modified, but has been removed in revision %s",
finfo->fullname, jrev2);
- /* Register the conflict with the client. */
+ /* FIXME: Should we arrange to return a non-zero exit
+ status? */
- /* FIXME: vers->ts_user should always be set here but sometimes
- * isn't, namely when checkout_file() has just created the file,
- * but simply setting it in checkout_file() appears to cause other
- * problems.
- */
- if (isfile (finfo->file))
- cp = time_stamp (finfo->file);
+ if (rev1 != NULL)
+ free (rev1);
+
+ return;
+ }
+
+ /* If only one join tag was specified, and the user file has
+ been changed since the greatest common ancestor (rev1),
+ then there is a conflict we can not resolve. See above for
+ the rationale. */
+ if (join_rev2 == NULL
+ && strcmp (rev1, vers->vn_user) != 0)
+ {
+ if (jdate2 != NULL)
+ error (0, 0,
+ "file %s has been modified, but has been removed in revision %s as of %s",
+ finfo->fullname, jrev2, jdate2);
else
- cp = xstrdup (vers->ts_user);
+ error (0, 0,
+ "file %s has been modified, but has been removed in revision %s",
+ finfo->fullname, jrev2);
- Register (finfo->entries, finfo->file, vers->vn_user,
- "Result of merge", vers->options, vers->tag, vers->date,
- cp);
- write_letter (finfo, 'C');
- free (cp);
+ /* FIXME: Should we arrange to return a non-zero exit
+ status? */
-#ifdef SERVER_SUPPORT
- /* Abuse server_checked_in() to send the updated entry without
- * needing to update the file.
- */
- if (server_active)
- server_checked_in (finfo->file, finfo->update_dir,
- finfo->repository);
-#endif
+ if (rev1 != NULL)
+ free (rev1);
return;
}
+ if (rev1 != NULL)
+ free (rev1);
+
/* The user file exists and has not been modified. Mark it
for removal. FIXME: If we are doing a checkout, this has
the effect of first checking out the file, and then
diff --git a/contrib/cvs/src/update.h b/contrib/cvs/src/update.h
index 8d581b1..c886b4c 100644
--- a/contrib/cvs/src/update.h
+++ b/contrib/cvs/src/update.h
@@ -10,10 +10,14 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. */
+/*
+ * $FreeBSD$
+ */
+
int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag,
char *xdate, int xforce, int local, int xbuild,
int xaflag, int xprune, int xpipeout, int which,
char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir,
- int xdotemplate, char *repository));
+ int xpull_template, char *repository));
int joining PROTO((void));
extern int isemptydir PROTO ((const char *dir, int might_not_exist));
diff --git a/contrib/cvs/src/version.c.in b/contrib/cvs/src/version.c.in
deleted file mode 100644
index aa2f97f..0000000
--- a/contrib/cvs/src/version.c.in
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 1994 david d `zoo' zuhn
- * Copyright (c) 1994 Free Software Foundation, Inc.
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with this CVS source distribution.
- *
- * version.c - the CVS version number
- */
-
-#include "cvs.h"
-
-char *version_string = "Concurrent Versions System (CVS) @VERSION@";
-
-#ifdef CLIENT_SUPPORT
-#ifdef SERVER_SUPPORT
-char *config_string = " (client/server)\n";
-#else
-char *config_string = " (client)\n";
-#endif
-#else
-#ifdef SERVER_SUPPORT
-char *config_string = " (server)\n";
-#else
-char *config_string = "\n";
-#endif
-#endif
-
-
-
-static const char *const version_usage[] =
-{
- "Usage: %s %s\n",
- NULL
-};
-
-
-
-/*
- * Output a version string for the client and server.
- *
- * This function will output the simple version number (for the '--version'
- * option) or the version numbers of the client and server (using the 'version'
- * command).
- */
-int
-version (argc, argv)
- int argc;
- char **argv;
-{
- int err = 0;
-
- if (argc == -1)
- usage (version_usage);
-
-#ifdef CLIENT_SUPPORT
- if (current_parsed_root && current_parsed_root->isremote)
- (void) fputs ("Client: ", stdout);
-#endif
-
- /* Having the year here is a good idea, so people have
- some idea of how long ago their version of CVS was
- released. */
- (void) fputs (version_string, stdout);
- (void) fputs (config_string, stdout);
-
-#ifdef CLIENT_SUPPORT
- if (current_parsed_root && current_parsed_root->isremote)
- {
- (void) fputs ("Server: ", stdout);
- start_server ();
- if (supported_request ("version"))
- send_to_server ("version\012", 0);
- else
- {
- send_to_server ("noop\012", 0);
- fputs ("(unknown)\n", stdout);
- }
- err = get_responses_and_close ();
- }
-#endif
- return err;
-}
-
diff --git a/contrib/cvs/src/version.h.in b/contrib/cvs/src/version.h.in
deleted file mode 100644
index 48580cb..0000000
--- a/contrib/cvs/src/version.h.in
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- c -*-
- *
- * Copyright (c) 1992, Brian Berliner and Jeff Polk
- * Copyright (c) 1989-1992, Brian Berliner
- *
- * You may distribute under the terms of the GNU General Public License as
- * specified in the README file that comes with the CVS kit.
- */
-
-#ifndef VERSION_H
-#define VERSION_H 1
-
-#define version_string "Concurrent Versions System (CVS) @VERSION@"
-
-#endif /* VERSION_H */
OpenPOWER on IntegriCloud