summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/import.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-01-26 03:09:57 +0000
committerpeter <peter@FreeBSD.org>1998-01-26 03:09:57 +0000
commite6e45661e44f15cb8c5c6f063080509bd910b98d (patch)
treea9812ba7ade0fde6f62c1626b45d522ba104c314 /contrib/cvs/src/import.c
parent571cfa0005d94d99d1341bf8ab02be04d4df5f9f (diff)
downloadFreeBSD-src-e6e45661e44f15cb8c5c6f063080509bd910b98d.zip
FreeBSD-src-e6e45661e44f15cb8c5c6f063080509bd910b98d.tar.gz
Import cvs-1.9.23 as at 19980123. There are a number of really nice
things fixed in here, including the '-ko' vs. -A problem with remote cvs which caused all files with -ko to be resent each time (which is damn painful over a modem, I can tell you). It also found a heap of stray empty directories that should have been pruned with the -P flag to cvs update but were not for some reason. It also has the fully integrated rcs and diff, so no more fork/exec overheads for rcs,ci,patch,diff,etc. This means that it parses the control data in the rcs files only once rather than twice or more. If the 'cvs diff' vs. Index thing is going to be fixed for future patch compatability, this is the place to do it.
Diffstat (limited to 'contrib/cvs/src/import.c')
-rw-r--r--contrib/cvs/src/import.c325
1 files changed, 203 insertions, 122 deletions
diff --git a/contrib/cvs/src/import.c b/contrib/cvs/src/import.c
index 3243a96..0a2af7f 100644
--- a/contrib/cvs/src/import.c
+++ b/contrib/cvs/src/import.c
@@ -3,7 +3,7 @@
* 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 1.4 kit.
+ * specified in the README file that comes with the CVS source distribution.
*
* "import" checks in the vendor release located in the current directory into
* the CVS source repository. The CVS vendor branch support is utilized.
@@ -23,7 +23,6 @@
#define FILE_HOLDER ".#cvsxxx"
static char *get_comment PROTO((char *user));
-static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp));
static int add_rev PROTO((char *message, RCSNode *rcs, char *vfile,
char *vers));
static int add_tags PROTO((RCSNode *rcs, char *vfile, char *vtag, int targc,
@@ -56,6 +55,7 @@ static const char *const import_usage[] =
"\t-b bra\tVendor branch id.\n",
"\t-m msg\tLog message.\n",
"\t-W spec\tWrappers specification line.\n",
+ "(Specify the --help global option for a list of other help options)\n",
NULL
};
@@ -104,9 +104,9 @@ import (argc, argv)
break;
case 'm':
#ifdef FORCE_USE_EDITOR
- use_editor = TRUE;
+ use_editor = 1;
#else
- use_editor = FALSE;
+ use_editor = 0;
#endif
message = xstrdup(optarg);
break;
@@ -199,6 +199,7 @@ import (argc, argv)
if (msglen == 0 || message[msglen - 1] != '\n')
{
char *nm = xmalloc (msglen + 2);
+ *nm = '\0';
if (message != NULL)
{
(void) strcpy (nm, message);
@@ -467,6 +468,8 @@ process_import_file (message, vfile, vtag, targc, targv)
if (!isfile (attic_name))
{
int retval;
+ char *free_opt = NULL;
+ char *our_opt = keyword_opt;
free (attic_name);
/*
@@ -474,8 +477,42 @@ process_import_file (message, vfile, vtag, targc, targv)
* repository nor in the Attic -- create it anew.
*/
add_log ('N', vfile);
- retval = add_rcs_file (message, rcs, vfile, vhead, vbranch,
- vtag, targc, targv, logfp);
+
+#ifdef SERVER_SUPPORT
+ /* The most reliable information on whether the file is binary
+ is what the client told us. That is because if the client had
+ the wrong idea about binaryness, it corrupted the file, so
+ we might as well believe the client. */
+ if (server_active)
+ {
+ Node *node;
+ List *entries;
+
+ /* Reading all the entries for each file is fairly silly, and
+ probably slow. But I am too lazy at the moment to do
+ anything else. */
+ entries = Entries_Open (0);
+ node = findnode_fn (entries, vfile);
+ if (node != NULL)
+ {
+ Entnode *entdata = (Entnode *) node->data;
+ if (entdata->type == ENT_FILE)
+ {
+ assert (entdata->options[0] == '-'
+ && entdata->options[1] == 'k');
+ our_opt = xstrdup (entdata->options + 2);
+ free_opt = our_opt;
+ }
+ }
+ Entries_Close (entries);
+ }
+#endif
+
+ retval = add_rcs_file (message, rcs, vfile, vhead, our_opt,
+ vbranch, vtag, targc, targv,
+ NULL, 0, logfp);
+ if (free_opt != NULL)
+ free (free_opt);
free (rcs);
return retval;
}
@@ -602,12 +639,14 @@ add_rev (message, rcs, vfile, vers)
/* Before RCS_lock existed, we were directing stdout, as well as
stderr, from the RCS command, to DEVNULL. I wouldn't guess that
was necessary, but I don't know for sure. */
- if (RCS_lock (rcs, vbranch, 1) != 0)
- {
- error (0, errno, "fork failed");
- return (1);
- }
+ /* Earlier versions of this function printed a `fork failed' error
+ when RCS_lock returned an error code. That's not appropriate
+ now that RCS_lock is librarified, but should the error text be
+ preserved? */
+ if (RCS_lock (rcs, vbranch, 1) != 0)
+ return 1;
locked = 1;
+ RCS_rewrite (rcs, NULL, NULL);
}
tocvsPath = wrap_tocvs_process_file (vfile);
if (tocvsPath == NULL)
@@ -632,7 +671,7 @@ add_rev (message, rcs, vfile, vers)
}
}
- status = RCS_checkin (rcs->path, tocvsPath == NULL ? vfile : tocvsPath,
+ status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath,
message, vbranch,
(RCS_FLAGS_QUIET
| (use_file_modtime ? RCS_FLAGS_MODTIME : 0)));
@@ -656,6 +695,7 @@ add_rev (message, rcs, vfile, vers)
if (locked)
{
(void) RCS_unlock(rcs, vbranch, 0);
+ RCS_rewrite (rcs, NULL, NULL);
}
return (1);
}
@@ -693,6 +733,7 @@ add_tags (rcs, vfile, vtag, targc, targv)
"ERROR: Failed to set tag %s in %s", vtag, rcs->path);
return (1);
}
+ RCS_rewrite (rcs, NULL, NULL);
memset (&finfo, 0, sizeof finfo);
finfo.file = vfile;
@@ -705,7 +746,9 @@ add_tags (rcs, vfile, vtag, targc, targv)
vers = Version_TS (&finfo, NULL, vtag, NULL, 1, 0);
for (i = 0; i < targc; i++)
{
- if ((retcode = RCS_settag (rcs, targv[i], vers->vn_rcs)) != 0)
+ if ((retcode = RCS_settag (rcs, targv[i], vers->vn_rcs)) == 0)
+ RCS_rewrite (rcs, NULL, NULL);
+ else
{
ierrno = errno;
fperror (logfp, 0, retcode == -1 ? ierrno : 0,
@@ -879,23 +922,33 @@ get_comment (user)
/* Create a new RCS file from scratch.
This probably should be moved to rcs.c now that it is called from
- places outside import.c. */
+ places outside import.c.
+
+ Return value is 0 for success, or nonzero for failure (in which
+ case an error message will have already been printed). */
int
-add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
- add_logfp)
- /* Log message for the addition. */
+add_rcs_file (message, rcs, user, add_vhead, key_opt,
+ add_vbranch, vtag, targc, targv,
+ desctext, desclen, add_logfp)
+ /* Log message for the addition. Not used if add_vhead == NULL. */
char *message;
/* Filename of the RCS file to create. */
char *rcs;
/* Filename of the file to serve as the contents of the initial
- revision. */
+ revision. Even if add_vhead is NULL, we use this to determine
+ the modes to give the new RCS file. */
char *user;
/* Revision number of head that we are adding. Normally 1.1 but
could be another revision as long as ADD_VBRANCH is a branch
- from it. */
+ from it. If NULL, then just add an empty file without any
+ revisions (similar to the one created by "rcs -i"). */
char *add_vhead;
+ /* Keyword expansion mode, e.g., "b" for binary. NULL means the
+ default behavior. */
+ char *key_opt;
+
/* Vendor branch to import to, or NULL if none. If non-NULL, then
vtag should also be non-NULL. */
char *add_vbranch;
@@ -903,6 +956,11 @@ add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
int targc;
char *targv[];
+ /* If non-NULL, description for the file. If NULL, the description
+ will be empty. */
+ char *desctext;
+ size_t desclen;
+
/* Write errors to here as well as via error (), or NULL if we should
use only error (). */
FILE *add_logfp;
@@ -912,20 +970,24 @@ add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
struct tm *ftm;
time_t now;
char altdate1[MAXDATELEN];
-#ifndef HAVE_RCS5
- char altdate2[MAXDATELEN];
-#endif
char *author;
int i, ierrno, err = 0;
mode_t mode;
char *tocvsPath;
char *userfile;
- char *local_opt = keyword_opt;
+ char *local_opt = key_opt;
char *free_opt = NULL;
if (noexec)
return (0);
+ /* Note that as the code stands now, the -k option overrides any
+ settings in wrappers (whether CVSROOT/cvswrappers, -W, or
+ whatever). Some have suggested this should be the other way
+ around. As far as I know the documentation doesn't say one way
+ or the other. Before making a change of this sort, should think
+ about what is best, document it (in cvs.texinfo and NEWS), &c. */
+
if (local_opt == NULL)
{
if (wrap_name_has (user, WRAP_RCSOPTION))
@@ -936,7 +998,17 @@ add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
tocvsPath = wrap_tocvs_process_file (user);
userfile = (tocvsPath == NULL ? user : tocvsPath);
- fpuser = CVS_FOPEN (userfile, "r");
+
+ /* Opening in text mode is probably never the right thing for the
+ server (because the protocol encodes text files in a fashion
+ which does not depend on what the client or server OS is, as
+ documented in cvsclient.texi), but as long as the server just
+ runs on unix it is a moot point. */
+ fpuser = CVS_FOPEN (userfile,
+ ((local_opt != NULL && strcmp (local_opt, "b") == 0)
+ ? "rb"
+ : "r")
+ );
if (fpuser == NULL)
{
/* not fatal, continue import */
@@ -954,8 +1026,17 @@ add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
/*
* putadmin()
*/
- if (fprintf (fprcs, "head %s;\012", add_vhead) < 0)
- goto write_error;
+ if (add_vhead != NULL)
+ {
+ if (fprintf (fprcs, "head %s;\012", add_vhead) < 0)
+ goto write_error;
+ }
+ else
+ {
+ if (fprintf (fprcs, "head ;\012") < 0)
+ goto write_error;
+ }
+
if (add_vbranch != NULL)
{
if (fprintf (fprcs, "branch %s;\012", add_vbranch) < 0)
@@ -1001,125 +1082,125 @@ add_rcs_file (message, rcs, user, add_vhead, add_vbranch, vtag, targc, targv,
if (fprintf (fprcs, "\012") < 0)
goto write_error;
- /*
- * puttree()
- */
+ /* Get information on modtime and mode. */
if (fstat (fileno (fpuser), &sb) < 0)
error (1, errno, "cannot fstat %s", user);
- if (use_file_modtime)
- now = sb.st_mtime;
- else
- (void) time (&now);
-#ifdef HAVE_RCS5
- ftm = gmtime (&now);
-#else
- ftm = localtime (&now);
-#endif
- (void) sprintf (altdate1, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#ifdef HAVE_RCS5
-#define altdate2 altdate1
-#else
- /*
- * If you don't have RCS V5 or later, you need to lie about the ci
- * time, since RCS V4 and earlier insist that the times differ.
- */
- now++;
- ftm = localtime (&now);
- (void) sprintf (altdate2, DATEFORM,
- ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
- ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
- ftm->tm_min, ftm->tm_sec);
-#endif
- author = getcaller ();
- if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
+ /* Write the revision(s), with the date and author and so on
+ (that is "delta" rather than "deltatext" from rcsfile(5)). */
+ if (add_vhead != NULL)
+ {
+ if (use_file_modtime)
+ now = sb.st_mtime;
+ else
+ (void) time (&now);
+ ftm = gmtime (&now);
+ (void) sprintf (altdate1, DATEFORM,
+ ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
+ ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
+ ftm->tm_min, ftm->tm_sec);
+ author = getcaller ();
+
+ if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
fprintf (fprcs, "date %s; author %s; state Exp;\012",
altdate1, author) < 0)
goto write_error;
- if (fprintf (fprcs, "branches") < 0)
- goto write_error;
- if (add_vbranch != NULL)
- {
- if (fprintf (fprcs, " %s.1", add_vbranch) < 0)
+ if (fprintf (fprcs, "branches") < 0)
+ goto write_error;
+ if (add_vbranch != NULL)
+ {
+ if (fprintf (fprcs, " %s.1", add_vbranch) < 0)
+ goto write_error;
+ }
+ if (fprintf (fprcs, ";\012") < 0)
goto write_error;
- }
- if (fprintf (fprcs, ";\012") < 0)
- goto write_error;
- if (fprintf (fprcs, "next ;\012") < 0)
- goto write_error;
- if (add_vbranch != NULL)
- {
- if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
- fprintf (fprcs, "date %s; author %s; state Exp;\012",
- altdate2, author) < 0 ||
- fprintf (fprcs, "branches ;\012") < 0 ||
- fprintf (fprcs, "next ;\012\012") < 0)
+ if (fprintf (fprcs, "next ;\012") < 0)
goto write_error;
+ if (add_vbranch != NULL)
+ {
+ if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
+ fprintf (fprcs, "date %s; author %s; state Exp;\012",
+ altdate1, author) < 0 ||
+ fprintf (fprcs, "branches ;\012") < 0 ||
+ fprintf (fprcs, "next ;\012\012") < 0)
+ goto write_error;
+ }
}
- if (
- /*
- * putdesc()
- */
- fprintf (fprcs, "\012desc\012") < 0 ||
- fprintf (fprcs, "@@\012\012\012") < 0 ||
- /*
- * putdelta()
- */
- fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
- fprintf (fprcs, "log\012@") < 0)
+
+ /* Now write the description (possibly empty). */
+ if (fprintf (fprcs, "\012desc\012") < 0 ||
+ fprintf (fprcs, "@") < 0)
goto write_error;
- if (add_vbranch != NULL)
- {
- /* We are going to put the log message in the revision on the
- branch. So putting it here too seems kind of redundant, I
- guess (and that is what CVS has always done, anyway). */
- if (fprintf (fprcs, "Initial revision\012") < 0)
- goto write_error;
- }
- else
+ if (desctext != NULL)
{
- if (expand_at_signs (message, (off_t) strlen (message), fprcs) < 0)
+ /* The use of off_t not size_t for the second argument is very
+ strange, since we are dealing with something which definitely
+ fits in memory. */
+ if (expand_at_signs (desctext, (off_t) desclen, fprcs) < 0)
goto write_error;
}
- if (fprintf (fprcs, "@\012") < 0 ||
- fprintf (fprcs, "text\012@") < 0)
- {
+ if (fprintf (fprcs, "@\012\012\012") < 0)
goto write_error;
- }
- /* Now copy over the contents of the file, expanding at signs. */
+ /* Now write the log messages and contents for the revision(s) (that
+ is, "deltatext" rather than "delta" from rcsfile(5)). */
+ if (add_vhead != NULL)
{
- char buf[8192];
- unsigned int len;
+ if (fprintf (fprcs, "\012%s\012", add_vhead) < 0 ||
+ fprintf (fprcs, "log\012@") < 0)
+ goto write_error;
+ if (add_vbranch != NULL)
+ {
+ /* We are going to put the log message in the revision on the
+ branch. So putting it here too seems kind of redundant, I
+ guess (and that is what CVS has always done, anyway). */
+ if (fprintf (fprcs, "Initial revision\012") < 0)
+ goto write_error;
+ }
+ else
+ {
+ if (expand_at_signs (message, (off_t) strlen (message), fprcs) < 0)
+ goto write_error;
+ }
+ if (fprintf (fprcs, "@\012") < 0 ||
+ fprintf (fprcs, "text\012@") < 0)
+ {
+ goto write_error;
+ }
- while (1)
+ /* Now copy over the contents of the file, expanding at signs. */
{
- len = fread (buf, 1, sizeof buf, fpuser);
- if (len == 0)
+ char buf[8192];
+ unsigned int len;
+
+ while (1)
{
- if (ferror (fpuser))
- error (1, errno, "cannot read file %s for copying", user);
- break;
+ len = fread (buf, 1, sizeof buf, fpuser);
+ if (len == 0)
+ {
+ if (ferror (fpuser))
+ error (1, errno, "cannot read file %s for copying",
+ user);
+ break;
+ }
+ if (expand_at_signs (buf, len, fprcs) < 0)
+ goto write_error;
}
- if (expand_at_signs (buf, len, fprcs) < 0)
- goto write_error;
}
- }
- if (fprintf (fprcs, "@\012\012") < 0)
- goto write_error;
- if (add_vbranch != NULL)
- {
- if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
- fprintf (fprcs, "log\012@") < 0 ||
- expand_at_signs (message, (off_t) strlen (message), fprcs) < 0 ||
- fprintf (fprcs, "@\012text\012") < 0 ||
- fprintf (fprcs, "@@\012") < 0)
+ if (fprintf (fprcs, "@\012\012") < 0)
goto write_error;
+ if (add_vbranch != NULL)
+ {
+ if (fprintf (fprcs, "\012%s.1\012", add_vbranch) < 0 ||
+ fprintf (fprcs, "log\012@") < 0 ||
+ expand_at_signs (message,
+ (off_t) strlen (message), fprcs) < 0 ||
+ fprintf (fprcs, "@\012text\012") < 0 ||
+ fprintf (fprcs, "@@\012") < 0)
+ goto write_error;
+ }
}
if (fclose (fprcs) == EOF)
@@ -1184,7 +1265,7 @@ read_error:
* signs. If an error occurs, return a negative value and set errno
* to indicate the error. If not, return a nonnegative value.
*/
-static int
+int
expand_at_signs (buf, size, fp)
char *buf;
off_t size;
OpenPOWER on IntegriCloud