summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/import.c
diff options
context:
space:
mode:
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