We use the stock versions of these files.

Reviewed/begged-for by: peter
This commit is contained in:
David E. O'Brien 2008-01-13 06:20:11 +00:00
parent 45930893e8
commit 6a06c310cf
9 changed files with 482 additions and 307 deletions

View File

@ -1,4 +1,16 @@
#! @CSH@ -f
# Copyright (C) 1995-2005 The Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# Sccs2rcs is a script to convert an existing SCCS
# history into an RCS history without losing any of

View File

@ -1,3 +1,17 @@
/*
* Copyright (C) 1996-2005 The Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/* Code for the buffer data structure. */
/* $FreeBSD$ */
@ -112,11 +126,13 @@ allocate_buffer_datas ()
/* Allocate buffer_data structures in blocks of 16. */
#define ALLOC_COUNT (16)
alc = ((struct buffer_data *)
xmalloc (ALLOC_COUNT * sizeof (struct buffer_data)));
alc = xmalloc (ALLOC_COUNT * sizeof (struct buffer_data));
space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE);
if (alc == NULL || space == NULL)
if (!space)
{
free (alc);
return;
}
for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE)
{
alc->next = free_buffer_data;
@ -1408,10 +1424,16 @@ stdio_buffer_shutdown (buf)
{
struct stdio_buffer_closure *bc = buf->closure;
struct stat s;
int closefp = 1;
int closefp, statted;
/* Must be a pipe or a socket. What could go wrong? */
assert (fstat (fileno (bc->fp), &s) != -1);
/* Must be a pipe or a socket. What could go wrong?
* Well, apparently for disconnected clients under AIX, the
* fstat() will return -1 on the server if the client has gone
* away.
*/
if (fstat(fileno(bc->fp), &s) == -1) statted = 0;
else statted = 1;
closefp = statted;
/* Flush the buffer if we can */
if (buf->flush)
@ -1434,7 +1456,7 @@ stdio_buffer_shutdown (buf)
# ifndef NO_SOCKET_TO_FD
{
/* shutdown() sockets */
if (S_ISSOCK (s.st_mode))
if (statted && S_ISSOCK (s.st_mode))
shutdown (fileno (bc->fp), 0);
}
# endif /* NO_SOCKET_TO_FD */
@ -1442,7 +1464,7 @@ stdio_buffer_shutdown (buf)
/* Can't be set with SHUTDOWN_SERVER defined */
else if (pclose (bc->fp) == EOF)
{
error (1, errno, "closing connection to %s",
error (0, errno, "closing connection to %s",
current_parsed_root->hostname);
closefp = 0;
}
@ -1462,7 +1484,7 @@ stdio_buffer_shutdown (buf)
# endif
# ifndef NO_SOCKET_TO_FD
/* shutdown() sockets */
if (S_ISSOCK (s.st_mode))
if (statted && S_ISSOCK (s.st_mode))
shutdown (fileno (bc->fp), 1);
# else
{
@ -1475,19 +1497,19 @@ stdio_buffer_shutdown (buf)
buf->output = NULL;
}
if (closefp && fclose (bc->fp) == EOF)
if (statted && closefp && fclose (bc->fp) == EOF)
{
if (0
# ifdef SERVER_SUPPORT
|| server_active
# endif /* SERVER_SUPPORT */
)
if (server_active)
{
/* Syslog this? */
}
# ifdef CLIENT_SUPPORT
/* We are already closing the connection.
* On error, print a warning and try to
* continue to avoid infinte loops.
*/
else
error (1, errno,
error (0, errno,
"closing down connection to %s",
current_parsed_root->hostname);
# endif /* CLIENT_SUPPORT */
@ -1501,8 +1523,13 @@ stdio_buffer_shutdown (buf)
do
w = waitpid (bc->child_pid, (int *) 0, 0);
while (w == -1 && errno == EINTR);
/* We are already closing the connection.
* On error, print a warning and try to
* continue to avoid infinte loops.
*/
if (w == -1)
error (1, errno, "waiting for process %d", bc->child_pid);
error (0, errno, "waiting for process %d", bc->child_pid);
}
return 0;
}
@ -1835,7 +1862,7 @@ packetizing_buffer_output (closure, data, have, wrote)
struct packetizing_buffer *pb = (struct packetizing_buffer *) closure;
char inbuf[BUFFER_DATA_SIZE + 2];
char stack_outbuf[BUFFER_DATA_SIZE + PACKET_SLOP + 4];
struct buffer_data *outdata;
struct buffer_data *outdata = NULL;
char *outbuf;
int size, status, translated;
@ -1890,6 +1917,11 @@ packetizing_buffer_output (closure, data, have, wrote)
buf_output (pb->buf, outbuf, translated + 2);
else
{
/* if ((have + PACKET_SLOP + 4) > BUFFER_DATA_SIZE), then
outdata may be NULL. */
if (outdata == NULL)
abort ();
outdata->size = translated + 2;
buf_append_data (pb->buf, outdata, outdata);
}

View File

@ -1,6 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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 source distribution.
@ -384,12 +389,8 @@ commit (argc, argv)
/* FIXME: Shouldn't this check be much more closely related to the
readonly user stuff (CVSROOT/readers, &c). That is, why should
root be able to "cvs init", "cvs import", &c, but not "cvs ci"? */
if (geteuid () == (uid_t) 0
# ifdef CLIENT_SUPPORT
/* Who we are on the client side doesn't affect logging. */
&& !current_parsed_root->isremote
# endif
)
/* Who we are on the client side doesn't affect logging. */
if (geteuid () == (uid_t) 0 && !current_parsed_root->isremote)
{
struct passwd *pw;
@ -412,6 +413,7 @@ commit (argc, argv)
/* Silently ignore -n for compatibility with old
* clients.
*/
if (!server_active) error(0, 0, "the `-n' option is obsolete");
break;
#endif /* SERVER_SUPPORT */
case 'm':
@ -642,7 +644,8 @@ commit (argc, argv)
fp = cvs_temp_file (&fname);
if (fp == NULL)
error (1, 0, "cannot create temporary file %s", fname);
error (1, 0, "cannot create temporary file %s",
fname ? fname : "(null)");
if (fwrite (saved_message, 1, strlen (saved_message), fp)
!= strlen (saved_message))
error (1, errno, "cannot write temporary file %s", fname);
@ -713,10 +716,8 @@ commit (argc, argv)
Lock_Cleanup ();
dellist (&mulist);
#ifdef SERVER_SUPPORT
if (server_active)
return err;
#endif
/* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
@ -871,11 +872,11 @@ check_fileproc (callerdat, finfo)
case T_CHECKOUT:
case T_PATCH:
case T_NEEDS_MERGE:
case T_CONFLICT:
case T_REMOVE_ENTRY:
error (0, 0, "Up-to-date check failed for `%s'", finfo->fullname);
freevers_ts (&vers);
return 1;
case T_CONFLICT:
case T_MODIFIED:
case T_ADDED:
case T_REMOVED:
@ -913,40 +914,30 @@ check_fileproc (callerdat, finfo)
return 1;
}
}
if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
if (status == T_CONFLICT && !force_ci)
{
/*
* We found a "conflict" marker.
*
* If the timestamp on the file is the same as the
* timestamp stored in the Entries file, we block the commit.
*/
if ( file_has_conflict ( finfo, vers->ts_conflict ) )
{
error (0, 0,
"file `%s' had a conflict and has not been modified",
finfo->fullname);
freevers_ts (&vers);
return 1;
}
if (file_has_markers (finfo))
{
/* Make this a warning, not an error, because we have
no way of knowing whether the "conflict indicators"
are really from a conflict or whether they are part
of the document itself (cvs.texinfo and sanity.sh in
CVS itself, for example, tend to want to have strings
like ">>>>>>>" at the start of a line). Making people
kludge this the way they need to kludge keyword
expansion seems undesirable. And it is worse than
keyword expansion, because there is no -ko
analogue. */
error (0, 0,
"\
error (0, 0,
"file `%s' had a conflict and has not been modified",
finfo->fullname);
freevers_ts (&vers);
return 1;
}
if (status == T_MODIFIED && !force_ci && file_has_markers (finfo))
{
/* Make this a warning, not an error, because we have
no way of knowing whether the "conflict indicators"
are really from a conflict or whether they are part
of the document itself (cvs.texinfo and sanity.sh in
CVS itself, for example, tend to want to have strings
like ">>>>>>>" at the start of a line). Making people
kludge this the way they need to kludge keyword
expansion seems undesirable. And it is worse than
keyword expansion, because there is no -ko
analogue. */
error (0, 0,
"\
warning: file `%s' seems to still contain conflict indicators",
finfo->fullname);
}
finfo->fullname);
}
if (status == T_REMOVED)
@ -1285,11 +1276,7 @@ commit_fileproc (callerdat, finfo)
if (!got_message)
{
got_message = 1;
if (
#ifdef SERVER_SUPPORT
!server_active &&
#endif
use_editor)
if (!server_active && use_editor)
do_editor (finfo->update_dir, &saved_message,
finfo->repository, ulist);
do_verify (&saved_message, finfo->repository);
@ -1475,6 +1462,8 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
Node *p;
List *ulist;
assert (repository);
p = findnode (mulist, update_dir);
if (p == NULL)
return err;
@ -1565,11 +1554,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
/* get commit message */
real_repos = Name_Repository (dir, update_dir);
got_message = 1;
if (
#ifdef SERVER_SUPPORT
!server_active &&
#endif
use_editor)
if (!server_active && use_editor)
do_editor (update_dir, &saved_message, real_repos, ulist);
do_verify (&saved_message, real_repos);
free (real_repos);
@ -1753,18 +1738,22 @@ remove_file (finfo, tag, message)
if (corev != NULL)
free (corev);
retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev,
retcode = RCS_checkin (finfo->rcs, finfo->file, message, rev, 0,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
if (retcode != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
"failed to commit dead revision for `%s'", finfo->fullname);
if (prev_rev != NULL)
free (prev_rev);
return 1;
}
/* At this point, the file has been committed as removed. We should
probably tell the history file about it */
history_write ('R', NULL, finfo->rcs->head, finfo->file, finfo->repository);
corev = rev ? RCS_getbranch (finfo->rcs, rev, 1) : RCS_head (finfo->rcs);
history_write ('R', NULL, corev, finfo->file, finfo->repository);
free (corev);
if (rev != NULL)
free (rev);
@ -2086,7 +2075,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* and lock it */
if (lock_RCS (file, rcs, rev, repository))
{
error (0, 0, "cannot lock `%s'.", rcs->path);
error (0, 0, "cannot lock revision %s in `%s'.",
rev ? rev : tag ? tag : "HEAD", rcs->path);
if (rev != NULL)
free (rev);
goto out;
@ -2124,13 +2114,14 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* commit a dead revision. */
(void) sprintf (tmp, "file %s was initially added on branch %s.",
file, tag);
retcode = RCS_checkin (rcs, NULL, tmp, NULL,
retcode = RCS_checkin (rcs, NULL, tmp, NULL, 0,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
free (tmp);
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not create initial dead revision %s", rcs->path);
free (fname);
goto out;
}
@ -2143,7 +2134,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
rcs = RCS_parse (file, repository);
if (rcs == NULL)
{
error (0, 0, "could not read %s", rcs->path);
error (0, 0, "could not read %s in %s", file, repository);
goto out;
}
*rcsnode = rcs;
@ -2151,7 +2142,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* and lock it once again. */
if (lock_RCS (file, rcs, NULL, repository))
{
error (0, 0, "cannot lock `%s'.", rcs->path);
error (0, 0, "cannot lock initial revision in `%s'.",
rcs->path);
goto out;
}
}
@ -2164,12 +2156,25 @@ checkaddfile (file, repository, tag, options, rcsnode)
char *head;
char *magicrev;
int retcode;
time_t headtime = -1;
char *revnum, *tmp;
FILE *fp;
time_t t = -1;
struct tm *ct;
fixbranch (rcs, sbranch);
head = RCS_getversion (rcs, NULL, NULL, 0, (int *) NULL);
if (!head)
error (1, 0, "No head revision in archive file `%s'.",
rcs->path);
magicrev = RCS_magicrev (rcs, head);
/* If this is not a new branch, then we will want a dead
version created before this one. */
if (!newfile)
headtime = RCS_getrevtime (rcs, head, 0, 0);
retcode = RCS_settag (rcs, tag, magicrev);
RCS_rewrite (rcs, NULL, NULL);
@ -2182,13 +2187,76 @@ checkaddfile (file, repository, tag, options, rcsnode)
"could not stub branch %s for %s", tag, rcs->path);
goto out;
}
/* We need to add a dead version here to avoid -rtag -Dtime
checkout problems between when the head version was
created and now. */
if (!newfile && headtime != -1)
{
/* move the new file out of the way. */
fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ sizeof (CVSPREFIX) + 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
rename_file (file, fname);
/* Create empty FILE. Can't use copy_file with a DEVNULL
argument -- copy_file now ignores device files. */
fp = fopen (file, "w");
if (fp == NULL)
error (1, errno, "cannot open %s for writing", file);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", file);
/* As we will be hacking the delta date, put the time
this was added into the log message. */
t = time(NULL);
ct = gmtime(&t);
tmp = xmalloc (strlen (file) + strlen (tag) + 80);
(void) sprintf (tmp,
"file %s was added on branch %s on %d-%02d-%02d %02d:%02d:%02d +0000",
file, tag,
ct->tm_year + (ct->tm_year < 100 ? 0 : 1900),
ct->tm_mon + 1, ct->tm_mday,
ct->tm_hour, ct->tm_min, ct->tm_sec);
/* commit a dead revision. */
revnum = RCS_whatbranch (rcs, tag);
retcode = RCS_checkin (rcs, NULL, tmp, revnum, headtime,
RCS_FLAGS_DEAD |
RCS_FLAGS_QUIET |
RCS_FLAGS_USETIME);
free (revnum);
free (tmp);
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not created dead stub %s for %s", tag,
rcs->path);
goto out;
}
/* put the new file back where it was */
rename_file (fname, file);
free (fname);
/* double-check that the file was written correctly */
freercsnode (&rcs);
rcs = RCS_parse (file, repository);
if (rcs == NULL)
{
error (0, 0, "could not read %s", rcs->path);
goto out;
}
*rcsnode = rcs;
}
}
else
{
/* lock the branch. (stubbed branches need not be locked.) */
if (lock_RCS (file, rcs, NULL, repository))
{
error (0, 0, "cannot lock `%s'.", rcs->path);
error (0, 0, "cannot lock head revision in `%s'.", rcs->path);
goto out;
}
}

View File

@ -1,6 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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 source distribution.
@ -86,17 +91,14 @@ import (argc, argv)
{
case 'Q':
case 'q':
#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
break;
case 'd':
#ifdef SERVER_SUPPORT
if (server_active)
{
/* CVS 1.10 and older clients will send this, but it
@ -106,7 +108,6 @@ import (argc, argv)
"warning: not setting the time of import from the file");
error (0, 0, "due to client limitations");
}
#endif
use_file_modtime = 1;
break;
case 'b':
@ -119,6 +120,7 @@ import (argc, argv)
#else
use_editor = 0;
#endif
if (message) free (message);
message = xstrdup(optarg);
break;
case 'I':
@ -145,7 +147,6 @@ import (argc, argv)
if (argc < 3)
usage (import_usage);
#ifdef SERVER_SUPPORT
/* This is for handling the Checkin-time request. It might seem a
bit odd to enable the use_file_modtime code even in the case
where Checkin-time was not sent for a particular file. The
@ -157,7 +158,6 @@ import (argc, argv)
if (server_active)
use_file_modtime = 1;
#endif
/* Don't allow "CVS" as any directory in module path.
*
@ -214,11 +214,22 @@ import (argc, argv)
* support branching to a single level, so the specified vendor branch
* must only have two dots in it (like "1.1.1").
*/
for (cp = vbranch; *cp != '\0'; cp++)
if (!isdigit ((unsigned char) *cp) && *cp != '.')
error (1, 0, "%s is not a numeric branch", vbranch);
if (numdots (vbranch) != 2)
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
{
regex_t pat;
int ret = regcomp (&pat, "^[1-9][0-9]*\\.[1-9][0-9]*\\.[1-9][0-9]*$",
REG_EXTENDED);
assert (!ret);
if (regexec (&pat, vbranch, 0, NULL, 0))
{
error (1, 0,
"Only numeric branch specifications with two dots are\n"
"supported by import, not `%s'. For example: `1.1.1'.",
vbranch);
}
regfree (&pat);
}
/* Set vhead to the branch's parent. */
vhead = xstrdup (vbranch);
cp = strrchr (vhead, '.');
*cp = '\0';
@ -232,17 +243,10 @@ import (argc, argv)
}
#endif
if (
#ifdef SERVER_SUPPORT
!server_active &&
#endif
use_editor)
if (!server_active && use_editor)
{
do_editor ((char *) NULL, &message,
#ifdef CLIENT_SUPPORT
current_parsed_root->isremote ? (char *) NULL :
#endif
repository,
current_parsed_root->isremote ? (char *) NULL : repository,
(List *) NULL);
}
do_verify (&message, repository);
@ -315,7 +319,8 @@ import (argc, argv)
/* Create the logfile that will be logged upon completion */
if ((logfp = cvs_temp_file (&tmpfile)) == NULL)
error (1, errno, "cannot create temporary file `%s'", tmpfile);
error (1, errno, "cannot create temporary file `%s'",
tmpfile ? tmpfile : "(null)");
/* On systems where we can unlink an open file, do so, so it will go
away no matter how we exit. FIXME-maybe: Should be checking for
errors but I'm not sure which error(s) we get if we are on a system
@ -436,6 +441,9 @@ import_descend (message, vtag, targc, targv)
ign_add_file (CVSDOTIGNORE, 1);
wrap_add_file (CVSDOTWRAPPER, 1);
if (!current_parsed_root->isremote)
lock_dir_for_write (repository);
if ((dirp = CVS_OPENDIR (".")) == NULL)
{
error (0, errno, "cannot open directory");
@ -448,13 +456,13 @@ import_descend (message, vtag, targc, targv)
{
if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0)
goto one_more_time_boys;
#ifdef SERVER_SUPPORT
/* CVS directories are created in the temp directory by
server.c because it doesn't special-case import. So
don't print a message about them, regardless of -I!. */
if (server_active && strcmp (dp->d_name, CVSADM) == 0)
goto one_more_time_boys;
#endif
if (ign_name (dp->d_name))
{
add_log ('I', dp->d_name);
@ -518,6 +526,9 @@ import_descend (message, vtag, targc, targv)
(void) CVS_CLOSEDIR (dirp);
}
if (!current_parsed_root->isremote)
Lock_Cleanup ();
if (dirlist != NULL)
{
Node *head, *p;
@ -750,7 +761,7 @@ add_rev (message, rcs, vfile, vers)
tocvsPath = wrap_tocvs_process_file (vfile);
status = RCS_checkin (rcs, tocvsPath == NULL ? vfile : tocvsPath,
message, vbranch,
message, vbranch, 0,
(RCS_FLAGS_QUIET | RCS_FLAGS_KEEPFILE
| (use_file_modtime ? RCS_FLAGS_MODTIME : 0)));
ierrno = errno;
@ -1586,11 +1597,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
repository = new;
}
#ifdef CLIENT_SUPPORT
if (!quiet && !current_parsed_root->isremote)
#else
if (!quiet)
#endif
error (0, 0, "Importing %s", repository);
if ( CVS_CHDIR (dir) < 0)
@ -1601,11 +1608,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
err = 1;
goto out;
}
#ifdef CLIENT_SUPPORT
if (!current_parsed_root->isremote && !isdir (repository))
#else
if (!isdir (repository))
#endif
{
rcs = xmalloc (strlen (repository) + sizeof (RCSEXT) + 5);
(void) sprintf (rcs, "%s%s", repository, RCSEXT);

View File

@ -1,5 +1,10 @@
/*
* Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (c) 1995, Cyclic Software, Bloomington, IN, USA
*
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with CVS.
@ -384,7 +389,8 @@ internal error: can only call password_entry_operation with pserver method");
/* create and open a temp file */
if ((tmp_fp = cvs_temp_file (&tmp_name)) == NULL)
error (1, errno, "unable to open temp file %s", tmp_name);
error (1, errno, "unable to open temp file %s",
tmp_name ? tmp_name : "(null)");
line = 0;
while ((line_length = getline (&linebuf, &linebuf_len, fp)) >= 0)
@ -457,7 +463,7 @@ internal error: can only call password_entry_operation with pserver method");
if (fprintf (fp, "/1 %s %s\n", cvsroot_canonical, newpassword) == EOF)
error (1, errno, "cannot write %s", passfile);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", passfile);
error (1, errno, "cannot close %s", passfile);
}
/* Utter, total, raving paranoia, I know. */

View File

@ -1,6 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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.
@ -284,7 +289,7 @@ static const char *const modules_contents[] = {
static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
"#SystemAuth=no\n",
"#SystemAuth=yes\n",
"\n",
"# Put CVS lock files in this directory rather than directly in the repository.\n",
"#LockDir=/var/lock/cvs\n",
@ -305,7 +310,7 @@ static const char *const config_contents[] = {
"#LogHistory=" ALL_HISTORY_REC_TYPES "\n",
"\n",
"# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg\n",
"# script to change the log message. Set it to `stat' to force CVS to verify",
"# script to change the log message. Set it to `stat' to force CVS to verify\n",
"# that the file has changed before reading it (this can take up to an extra\n",
"# second per directory being committed, so it is not recommended for large\n",
"# repositories. Set it to `never' (the previous CVS behavior) to prevent\n",
@ -579,7 +584,17 @@ checkout_file (file, temp)
free (rcs);
return (1);
}
rcsnode = RCS_parsercsfile (rcs);
if (!rcsnode)
{
/* Probably not necessary (?); RCS_parsercsfile already printed a
message. */
error (0, 0, "Failed to parse `%s'.", rcs);
free (rcs);
return 1;
}
retcode = RCS_checkout (rcsnode, NULL, NULL, NULL, NULL, temp,
(RCSCHECKOUTPROC) NULL, (void *) NULL);
if (retcode != 0)

View File

@ -1,6 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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 source distribution.
@ -44,7 +49,7 @@ static int unidiff = 0;
static const char *const patch_usage[] =
{
"Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d]\n",
"Usage: %s %s [-flR] [-c|-u] [-s|-t] [-V %%d] [-k kopt]\n",
" -r rev|-D date [-r rev2 | -D date2] modules...\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
@ -53,9 +58,10 @@ static const char *const patch_usage[] =
"\t-u\tUnidiff format.\n",
"\t-s\tShort patch - one liner per file.\n",
"\t-t\tTop two diffs - last change made to the file.\n",
"\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
"\t-k kopt\tSpecify keyword expansion mode.\n",
"\t-D date\tDate.\n",
"\t-r rev\tRevision - symbolic or numeric.\n",
"\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@ -83,11 +89,9 @@ patch (argc, argv)
{
case 'Q':
case 'q':
#ifdef SERVER_SUPPORT
/* The CVS 1.5 client sends these options (in addition to
Global_option requests), so we must ignore them. */
if (!server_active)
#endif
error (1, 0,
"-q or -Q must be specified before \"%s\"",
cvs_cmd_name);
@ -340,6 +344,7 @@ patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
error (0, errno, "cannot chdir to %s", repository);
free (repository);
free (where);
return 1;
}
@ -402,6 +407,9 @@ patch_fileproc (callerdat, finfo)
char *cp1, *cp2;
FILE *fp;
int line_length;
int dargc = 0;
size_t darg_allocated = 0;
char **dargv = NULL;
line1 = NULL;
line1_chars_allocated = 0;
@ -512,7 +520,8 @@ patch_fileproc (callerdat, finfo)
*/
if ((fp1 = cvs_temp_file (&tmpfile1)) == NULL)
{
error (0, errno, "cannot create temporary file %s", tmpfile1);
error (0, errno, "cannot create temporary file %s",
tmpfile1 ? tmpfile1 : "(null)");
ret = 1;
goto out;
}
@ -521,7 +530,8 @@ patch_fileproc (callerdat, finfo)
error (0, errno, "warning: cannot close %s", tmpfile1);
if ((fp2 = cvs_temp_file (&tmpfile2)) == NULL)
{
error (0, errno, "cannot create temporary file %s", tmpfile2);
error (0, errno, "cannot create temporary file %s",
tmpfile2 ? tmpfile2 : "(null)");
ret = 1;
goto out;
}
@ -530,7 +540,8 @@ patch_fileproc (callerdat, finfo)
error (0, errno, "warning: cannot close %s", tmpfile2);
if ((fp3 = cvs_temp_file (&tmpfile3)) == NULL)
{
error (0, errno, "cannot create temporary file %s", tmpfile3);
error (0, errno, "cannot create temporary file %s",
tmpfile3 ? tmpfile3 : "(null)");
ret = 1;
goto out;
}
@ -581,8 +592,10 @@ patch_fileproc (callerdat, finfo)
(void)utime (tmpfile2, &t);
}
switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, unidiff ? "-u" : "-c",
tmpfile3))
if (unidiff) run_add_arg_p (&dargc, &darg_allocated, &dargv, "-u");
else run_add_arg_p (&dargc, &darg_allocated, &dargv, "-c");
switch (diff_exec (tmpfile1, tmpfile2, NULL, NULL, dargc, dargv,
tmpfile3))
{
case -1: /* fork/wait failure */
error (1, errno, "fork for diff failed on %s", rcs);
@ -744,16 +757,33 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
free (line1);
if (line2)
free (line2);
if (CVS_UNLINK (tmpfile1) < 0)
error (0, errno, "cannot unlink %s", tmpfile1);
if (CVS_UNLINK (tmpfile2) < 0)
error (0, errno, "cannot unlink %s", tmpfile2);
if (CVS_UNLINK (tmpfile3) < 0)
error (0, errno, "cannot unlink %s", tmpfile3);
free (tmpfile1);
free (tmpfile2);
free (tmpfile3);
tmpfile1 = tmpfile2 = tmpfile3 = NULL;
if (tmpfile1 != NULL)
{
if (CVS_UNLINK (tmpfile1) < 0)
error (0, errno, "cannot unlink %s", tmpfile1);
free (tmpfile1);
tmpfile1 = NULL;
}
if (tmpfile2 != NULL)
{
if (CVS_UNLINK (tmpfile2) < 0)
error (0, errno, "cannot unlink %s", tmpfile2);
free (tmpfile2);
tmpfile2 = NULL;
}
if (tmpfile3 != NULL)
{
if (CVS_UNLINK (tmpfile3) < 0)
error (0, errno, "cannot unlink %s", tmpfile3);
free (tmpfile3);
tmpfile3 = NULL;
}
if (dargc)
{
run_arg_free_p (dargc, dargv);
free (dargv);
}
out2:
if (vers_tag != NULL)

View File

@ -1,6 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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 source distribution.
@ -53,8 +58,8 @@
On a related note, see the comments at diff_exec, later in this file,
for more on the diff library. */
static void RCS_output_diff_options PROTO ((const char *, const char *,
const char *, const char *));
static void RCS_output_diff_options PROTO ((int, char *const *, const char *,
const char *, const char *));
/* Stuff to deal with passing arguments the way libdiff.a wants to deal
@ -66,17 +71,18 @@ static void RCS_output_diff_options PROTO ((const char *, const char *,
argument will be parsed into whitespace separated words and added
to the global call_diff_argv list.
Then, optionally, call call_diff_arg for each additional argument
Then, optionally, call call_diff_add_arg for each additional argument
that you'd like to pass to the diff library.
Finally, call call_diff or call_diff3 to produce the diffs. */
static char **call_diff_argv;
static int call_diff_argc;
static int call_diff_argc_allocated;
static size_t call_diff_argc_allocated;
static void call_diff_add_arg PROTO ((const char *));
static void call_diff_setup PROTO ((const char *prog));
static void call_diff_setup PROTO ((const char *prog,
int argc, char * const *argv));
static int call_diff PROTO ((const char *out));
static int call_diff3 PROTO ((char *out));
@ -85,63 +91,38 @@ static void call_diff_flush_output PROTO((void));
static void call_diff_write_stdout PROTO((const char *));
static void call_diff_error PROTO((const char *, const char *, const char *));
/* VARARGS */
static void
call_diff_setup (prog)
const char *prog;
{
char *cp;
int i;
char *call_diff_prog;
/* clean out any malloc'ed values from call_diff_argv */
for (i = 0; i < call_diff_argc; i++)
{
if (call_diff_argv[i])
{
free (call_diff_argv[i]);
call_diff_argv[i] = (char *) 0;
}
}
call_diff_argc = 0;
call_diff_prog = xstrdup (prog);
/* put each word into call_diff_argv, allocating it as we go */
for (cp = strtok (call_diff_prog, " \t");
cp != NULL;
cp = strtok ((char *) NULL, " \t"))
call_diff_add_arg (cp);
free (call_diff_prog);
}
static void
call_diff_arg (s)
const char *s;
{
call_diff_add_arg (s);
}
static void
call_diff_add_arg (s)
const char *s;
{
/* allocate more argv entries if we've run out */
if (call_diff_argc >= call_diff_argc_allocated)
{
call_diff_argc_allocated += 50;
call_diff_argv = (char **)
xrealloc ((char *) call_diff_argv,
call_diff_argc_allocated * sizeof (char **));
}
if (s)
call_diff_argv[call_diff_argc++] = xstrdup (s);
else
/* Not post-incremented on purpose! */
call_diff_argv[call_diff_argc] = (char *) 0;
run_add_arg_p (&call_diff_argc, &call_diff_argc_allocated, &call_diff_argv,
s);
}
/* VARARGS */
static void
call_diff_setup (prog, argc, argv)
const char *prog;
int argc;
char * const *argv;
{
int i;
/* clean out any malloc'ed values from call_diff_argv */
run_arg_free_p (call_diff_argc, call_diff_argv);
call_diff_argc = 0;
/* put each word into call_diff_argv, allocating it as we go */
call_diff_add_arg (prog);
for (i = 0; i < argc; i++)
call_diff_add_arg (argv[i]);
}
/* Callback function for the diff library to write data to the output
file. This is used when we are producing output to stdout. */
@ -213,6 +194,8 @@ static int
call_diff (out)
const char *out;
{
call_diff_add_arg (NULL);
if (out == RUN_TTY)
return diff_run (call_diff_argc, call_diff_argv, NULL,
&call_diff_stdout_callbacks);
@ -264,6 +247,7 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
symbolic). */
xrev1 = RCS_gettag (rcs, rev1, 0, NULL);
xrev2 = RCS_gettag (rcs, rev2, 0, NULL);
assert (xrev1 && xrev2);
/* Check out chosen revisions. The error message when RCS_checkout
fails is not very informative -- it is taken verbatim from RCS 5.7,
@ -304,21 +288,21 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
/* Remember that the first word in the `call_diff_setup' string is used now
only for diagnostic messages -- CVS no longer forks to run diff3. */
diffout = cvs_temp_name();
call_diff_setup ("diff3");
call_diff_arg ("-E");
call_diff_arg ("-am");
call_diff_setup ("diff3", 0, NULL);
call_diff_add_arg ("-E");
call_diff_add_arg ("-am");
call_diff_arg ("-L");
call_diff_arg (workfile);
call_diff_arg ("-L");
call_diff_arg (xrev1);
call_diff_arg ("-L");
call_diff_arg (xrev2);
call_diff_add_arg ("-L");
call_diff_add_arg (workfile);
call_diff_add_arg ("-L");
call_diff_add_arg (xrev1);
call_diff_add_arg ("-L");
call_diff_add_arg (xrev2);
call_diff_arg ("--");
call_diff_arg (workfile);
call_diff_arg (tmp1);
call_diff_arg (tmp2);
call_diff_add_arg ("--");
call_diff_add_arg (workfile);
call_diff_add_arg (tmp1);
call_diff_add_arg (tmp2);
retval = call_diff3 (diffout);
@ -384,10 +368,11 @@ RCS_merge(rcs, path, workfile, options, rev1, rev2)
about this--any such features are undocumented in the context of
CVS, and I'm not sure how important to users. */
int
RCS_exec_rcsdiff(rcsfile, opts, options, rev1, rev1_cache, rev2,
label1, label2, workfile )
RCS_exec_rcsdiff (rcsfile, diff_argc, diff_argv, options, rev1, rev1_cache,
rev2, label1, label2, workfile)
RCSNode *rcsfile;
const char *opts;
int diff_argc;
char * const *diff_argv;
const char *options;
const char *rev1;
const char *rev1_cache;
@ -467,8 +452,9 @@ RCS file: ", 0);
use_file2 = tmpfile2;
}
RCS_output_diff_options (opts, rev1, rev2, workfile);
status = diff_exec( use_file1, use_file2, label1, label2, opts, RUN_TTY );
RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile);
status = diff_exec (use_file1, use_file2, label1, label2,
diff_argc, diff_argv, RUN_TTY);
if (status >= 0)
{
retval = status;
@ -547,16 +533,15 @@ RCS file: ", 0);
message on stderr. */
int
diff_exec (file1, file2, label1, label2, options, out)
diff_exec (file1, file2, label1, label2, dargc, dargv, out)
const char *file1;
const char *file2;
const char *label1;
const char *label2;
const char *options;
int dargc;
char * const *dargv;
const char *out;
{
char *args;
#ifdef PRESERVE_PERMISSIONS_SUPPORT
/* If either file1 or file2 are special files, pretend they are
/dev/null. Reason: suppose a file that represents a block
@ -590,18 +575,15 @@ diff_exec (file1, file2, label1, label2, options, out)
}
#endif
args = xmalloc (strlen (options) + 10);
/* The first word in this string is used only for error reporting. */
sprintf (args, "diff %s", options);
call_diff_setup (args);
/* The first arg to call_diff_setup is used only for error reporting. */
call_diff_setup ("diff", dargc, dargv);
if (label1)
call_diff_arg (label1);
call_diff_add_arg (label1);
if (label2)
call_diff_arg (label2);
call_diff_arg ("--");
call_diff_arg (file1);
call_diff_arg (file2);
free (args);
call_diff_add_arg (label2);
call_diff_add_arg ("--");
call_diff_add_arg (file1);
call_diff_add_arg (file2);
return call_diff (out);
}
@ -613,19 +595,23 @@ diff_exec (file1, file2, label1, label2, options, out)
that I have seen. */
static void
RCS_output_diff_options (opts, rev1, rev2, workfile)
const char *opts;
RCS_output_diff_options (diff_argc, diff_argv, rev1, rev2, workfile)
int diff_argc;
char * const *diff_argv;
const char *rev1;
const char *rev2;
const char *workfile;
{
char *tmp;
tmp = (char *) xmalloc (strlen (opts) + strlen (rev1) + 10);
sprintf (tmp, "diff%s -r%s", opts, rev1);
cvs_output (tmp, 0);
free (tmp);
int i;
cvs_output ("diff", 0);
for (i = 0; i < diff_argc; i++)
{
cvs_output (" ", 1);
cvs_output (diff_argv[i], 0);
}
cvs_output (" -r", 3);
cvs_output (rev1, 0);
if (rev2)
{

View File

@ -1,5 +1,11 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (C) 1986-2005 The Free Software Foundation, Inc.
*
* Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
* and others.
*
* Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
* 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 source distribution.
@ -135,6 +141,25 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
frame.aflag = aflag;
frame.locktype = locktype;
frame.dosrcs = dosrcs;
/* If our repository_in has a trailing "/.", remove it before storing it
* for do_recursion().
*
* FIXME: This is somewhat of a hack in the sense that many of our callers
* painstakingly compute and add the trailing '.' we now remove.
*/
while (repository_in && strlen (repository_in) >= 2
&& repository_in[strlen (repository_in) - 2] == '/'
&& repository_in[strlen (repository_in) - 1] == '.')
{
/* Beware the case where the string is exactly "/." or "//.".
* Paths with a leading "//" are special on some early UNIXes.
*/
if (strlen (repository_in) == 2 || strlen (repository_in) == 3)
repository_in[strlen (repository_in) - 1] = '\0';
else
repository_in[strlen (repository_in) - 2] = '\0';
}
frame.repository = repository_in;
expand_wild (argc, argv, &argc, &argv);
@ -172,21 +197,24 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
&& CVSroot_cmdline == NULL
&& current_parsed_root->isremote)
{
char *root = Name_Root (NULL, update_dir);
if (root && strcmp (root, current_parsed_root->original) != 0)
/* We're skipping this directory because it is for
a different root. Therefore, we just want to
do the subdirectories only. Processing files would
cause a working directory from one repository to be
processed against a different repository, which could
cause all kinds of spurious conflicts and such.
Question: what about the case of "cvs update foo"
where we process foo/bar and not foo itself? That
seems to be handled somewhere (else) but why should
it be a separate case? Needs investigation... */
just_subdirs = 1;
free (root);
cvsroot_t *root = Name_Root (NULL, update_dir);
if (root)
{
if (strcmp (root->original, current_parsed_root->original))
/* We're skipping this directory because it is for
* a different root. Therefore, we just want to
* do the subdirectories only. Processing files would
* cause a working directory from one repository to be
* processed against a different repository, which could
* cause all kinds of spurious conflicts and such.
*
* Question: what about the case of "cvs update foo"
* where we process foo/bar and not foo itself? That
* seems to be handled somewhere (else) but why should
* it be a separate case? Needs investigation... */
just_subdirs = 1;
free_cvsroot_t (root);
}
}
#endif
@ -307,11 +335,8 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
addfile (&files_by_dir, dir, comp);
else if (isdir (dir))
{
if ((which & W_LOCAL) && isdir (CVSADM)
#ifdef CLIENT_SUPPORT
&& !current_parsed_root->isremote
#endif
)
if ((which & W_LOCAL) && isdir (CVSADM) &&
!current_parsed_root->isremote)
{
/* otherwise, look for it in the repository. */
char *tmp_update_dir;
@ -567,7 +592,7 @@ do_recursion (frame)
* generating data, to give the buffers a chance to drain to the
* remote client. We should not have locks active at this point,
* but if there are writelocks around, we cannot pause here. */
if (server_active && locktype != CVS_LOCK_NONE)
if (server_active && locktype != CVS_LOCK_WRITE)
server_pause_check();
#endif
@ -583,43 +608,41 @@ do_recursion (frame)
directories, since we're guaranteed to have only one CVSROOT --
our own. */
if (
/* If -d was specified, it should override CVS/Root.
/* If -d was specified, it should override CVS/Root.
In the single-repository case, it is long-standing CVS behavior
and makes sense - the user might want another access method,
another server (which mounts the same repository), &c.
In the single-repository case, it is long-standing CVS behavior
and makes sense - the user might want another access method,
another server (which mounts the same repository), &c.
In the multiple-repository case, -d overrides all CVS/Root
files. That is the only plausible generalization I can
think of. */
CVSroot_cmdline == NULL
#ifdef SERVER_SUPPORT
&& ! server_active
#endif
)
In the multiple-repository case, -d overrides all CVS/Root
files. That is the only plausible generalization I can
think of. */
if (CVSroot_cmdline == NULL && !server_active)
{
char *this_root = Name_Root ((char *) NULL, update_dir);
cvsroot_t *this_root = Name_Root ((char *) NULL, update_dir);
if (this_root != NULL)
{
if (findnode (root_directories, this_root) == NULL)
if (findnode (root_directories, this_root->original))
{
process_this_directory = !strcmp (current_parsed_root->original,
this_root->original);
free_cvsroot_t (this_root);
}
else
{
/* Add it to our list. */
Node *n = getnode ();
n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
n->key = xstrdup (this_root->original);
n->data = this_root;
if (addnode (root_directories, n))
error (1, 0, "cannot add new CVSROOT %s", this_root);
}
process_this_directory =
(strcmp (current_parsed_root->original, this_root) == 0);
error (1, 0, "cannot add new CVSROOT %s",
this_root->original);
free (this_root);
process_this_directory = 0;
}
}
}
@ -682,7 +705,8 @@ do_recursion (frame)
if (repository == NULL)
{
Name_Repository ((char *) NULL, update_dir);
assert (!"Not reached. Please report this problem to <bug-cvs@gnu.org>");
assert (!"Not reached. Please report this problem to <"
PACKAGE_BUGREPORT ">");
}
/* find the files and fill in entries if appropriate */
@ -1031,42 +1055,41 @@ but CVS uses %s for its own purposes; skipping %s directory",
/* Only process this directory if the root matches. This nearly
duplicates code in do_recursion. */
if (
/* If -d was specified, it should override CVS/Root.
/* If -d was specified, it should override CVS/Root.
In the single-repository case, it is long-standing CVS behavior
and makes sense - the user might want another access method,
another server (which mounts the same repository), &c.
In the single-repository case, it is long-standing CVS behavior
and makes sense - the user might want another access method,
another server (which mounts the same repository), &c.
In the multiple-repository case, -d overrides all CVS/Root
files. That is the only plausible generalization I can
think of. */
CVSroot_cmdline == NULL
#ifdef SERVER_SUPPORT
&& ! server_active
#endif
)
In the multiple-repository case, -d overrides all CVS/Root
files. That is the only plausible generalization I can
think of. */
if (CVSroot_cmdline == NULL && !server_active)
{
char *this_root = Name_Root (dir, update_dir);
cvsroot_t *this_root = Name_Root (dir, update_dir);
if (this_root != NULL)
{
if (findnode (root_directories, this_root) == NULL)
if (findnode (root_directories, this_root->original))
{
process_this_directory = !strcmp (current_parsed_root->original,
this_root->original);
free_cvsroot_t (this_root);
}
else
{
/* Add it to our list. */
Node *n = getnode ();
n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
n->key = xstrdup (this_root->original);
n->data = this_root;
if (addnode (root_directories, n))
error (1, 0, "cannot add new CVSROOT %s", this_root);
error (1, 0, "cannot add new CVSROOT %s",
this_root->original);
process_this_directory = 0;
}
process_this_directory = (strcmp (current_parsed_root->original, this_root) == 0);
free (this_root);
}
}