summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/recurse.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-05-15 22:46:24 +0000
committerpeter <peter@FreeBSD.org>1997-05-15 22:46:24 +0000
commit4f40fe8334ad5f056e1d9105f23fe7ac859c39ba (patch)
tree3b2f0092fa216d9f61059ba94b7f10b5bacf9496 /contrib/cvs/src/recurse.c
parent8982e501c77217c860f79bba431f46a62b607a21 (diff)
downloadFreeBSD-src-4f40fe8334ad5f056e1d9105f23fe7ac859c39ba.zip
FreeBSD-src-4f40fe8334ad5f056e1d9105f23fe7ac859c39ba.tar.gz
Import of cvs-1.9.9-970515 onto vendor branch.
Obtained from: cyclic.com
Diffstat (limited to 'contrib/cvs/src/recurse.c')
-rw-r--r--contrib/cvs/src/recurse.c431
1 files changed, 270 insertions, 161 deletions
diff --git a/contrib/cvs/src/recurse.c b/contrib/cvs/src/recurse.c
index ec51a98..e18d576 100644
--- a/contrib/cvs/src/recurse.c
+++ b/contrib/cvs/src/recurse.c
@@ -19,79 +19,113 @@ static void addlist PROTO((List ** listp, char *key));
static int unroll_files_proc PROTO((Node *p, void *closure));
static void addfile PROTO((List **listp, char *dir, char *file));
-
-/*
- * Local static versions eliminates the need for globals
- */
-static FILEPROC fileproc;
-static FILESDONEPROC filesdoneproc;
-static DIRENTPROC direntproc;
-static DIRLEAVEPROC dirleaveproc;
-static int which;
-static Dtype flags;
-static int aflag;
-static int readlock;
-static int dosrcs;
-static char update_dir[PATH_MAX];
+static char *update_dir;
static char *repository = NULL;
static List *filelist = NULL; /* holds list of files on which to operate */
static List *dirlist = NULL; /* holds list of directories on which to operate */
struct recursion_frame {
- FILEPROC fileproc;
- FILESDONEPROC filesdoneproc;
- DIRENTPROC direntproc;
- DIRLEAVEPROC dirleaveproc;
- Dtype flags;
- int which;
- int aflag;
- int readlock;
- int dosrcs;
+ FILEPROC fileproc;
+ FILESDONEPROC filesdoneproc;
+ DIRENTPROC direntproc;
+ DIRLEAVEPROC dirleaveproc;
+ void *callerdat;
+ Dtype flags;
+ int which;
+ int aflag;
+ int readlock;
+ int dosrcs;
};
-/*
- * Called to start a recursive command.
- *
- * Command line arguments dictate the directories and files on which
- * we operate. In the special case of no arguments, we default to
- * ".".
- *
- * The general algorithm is as follows.
- */
+static int do_recursion PROTO ((struct recursion_frame *frame));
+
+/* I am half tempted to shove a struct file_info * into the struct
+ recursion_frame (but then we would need to modify or create a
+ recursion_frame for each file), or shove a struct recursion_frame *
+ into the struct file_info (more tempting, although it isn't completely
+ clear that the struct file_info should contain info about recursion
+ processor internals). So instead use this struct. */
+
+struct frame_and_file {
+ struct recursion_frame *frame;
+ struct file_info *finfo;
+};
+
+/* Similarly, we need to pass the entries list to do_dir_proc. */
+
+struct frame_and_entries {
+ struct recursion_frame *frame;
+ List *entries;
+};
+
+/* Start a recursive command.
+
+ Command line arguments (ARGC, ARGV) dictate the directories and
+ files on which we operate. In the special case of no arguments, we
+ default to ".". */
int
-start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
+start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
argc, argv, local, which, aflag, readlock,
- update_preload, dosrcs, wd_is_repos)
+ update_preload, dosrcs)
FILEPROC fileproc;
FILESDONEPROC filesdoneproc;
DIRENTPROC direntproc;
DIRLEAVEPROC dirleaveproc;
+ void *callerdat;
+
int argc;
char **argv;
int local;
+
+ /* This specifies the kind of recursion. There are several cases:
+
+ 1. W_LOCAL is not set but W_REPOS or W_ATTIC is. The current
+ directory when we are called must be the repository and
+ recursion proceeds according to what exists in the repository.
+
+ 2a. W_LOCAL is set but W_REPOS and W_ATTIC are not. The
+ current directory when we are called must be the working
+ directory. Recursion proceeds according to what exists in the
+ working directory, never (I think) consulting any part of the
+ repository which does not correspond to the working directory
+ ("correspond" == Name_Repository).
+
+ 2b. W_LOCAL is set and so is W_REPOS or W_ATTIC. This is the
+ weird one. The current directory when we are called must be
+ the working directory. We recurse through working directories,
+ but we recurse into a directory if it is exists in the working
+ directory *or* it exists in the repository. If a directory
+ does not exist in the working directory, the direntproc must
+ either tell us to skip it (R_SKIP_ALL), or must create it (I
+ think those are the only two cases). */
int which;
+
int aflag;
int readlock;
char *update_preload;
int dosrcs;
- int wd_is_repos; /* Set if caller has already cd'd to the repository */
{
int i, err = 0;
- Dtype flags;
List *files_by_dir = NULL;
struct recursion_frame frame;
+ frame.fileproc = fileproc;
+ frame.filesdoneproc = filesdoneproc;
+ frame.direntproc = direntproc;
+ frame.dirleaveproc = dirleaveproc;
+ frame.callerdat = callerdat;
+ frame.flags = local ? R_SKIP_DIRS : R_PROCESS;
+ frame.which = which;
+ frame.aflag = aflag;
+ frame.readlock = readlock;
+ frame.dosrcs = dosrcs;
+
expand_wild (argc, argv, &argc, &argv);
if (update_preload == NULL)
- update_dir[0] = '\0';
- else
- (void) strcpy (update_dir, update_preload);
-
- if (local)
- flags = R_SKIP_DIRS;
+ update_dir = xstrdup ("");
else
- flags = R_PROCESS;
+ update_dir = xstrdup (update_preload);
/* clean up from any previous calls to start_recursion */
if (repository)
@@ -101,10 +135,17 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
}
if (filelist)
dellist (&filelist); /* FIXME-krp: no longer correct. */
-/* FIXME-krp: clean up files_by_dir */
if (dirlist)
dellist (&dirlist);
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ {
+ for (i = 0; i < argc; ++i)
+ server_pathname_check (argv[i]);
+ }
+#endif
+
if (argc == 0)
{
@@ -116,14 +157,12 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
* called with the list of sub-dirs of the current dir as args
*/
if ((which & W_LOCAL) && !isdir (CVSADM))
- dirlist = Find_Directories ((char *) NULL, W_LOCAL);
+ dirlist = Find_Directories ((char *) NULL, W_LOCAL, (List *) NULL);
else
addlist (&dirlist, ".");
- err += do_recursion (fileproc, filesdoneproc, direntproc,
- dirleaveproc, flags, which, aflag,
- readlock, dosrcs);
- return(err);
+ err += do_recursion (&frame);
+ goto out;
}
@@ -151,7 +190,6 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
/* otherwise, split argument into directory and component names. */
char *dir;
char *comp;
- char tmp[PATH_MAX];
char *file_to_try;
/* Now break out argv[i] into directory part (DIR) and file part (COMP).
@@ -174,45 +212,55 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
/* if this argument exists as a file in the current
working directory tree, then add it to the files list. */
- if (wd_is_repos)
+ if (!(which & W_LOCAL))
{
/* If doing rtag, we've done a chdir to the repository. */
- sprintf (tmp, "%s%s", argv[i], RCSEXT);
- file_to_try = tmp;
+ file_to_try = xmalloc (strlen (argv[i]) + sizeof (RCSEXT) + 5);
+ sprintf (file_to_try, "%s%s", argv[i], RCSEXT);
}
else
- file_to_try = argv[i];
+ file_to_try = xstrdup (argv[i]);
- if(isfile(file_to_try))
+ if (isfile (file_to_try))
addfile (&files_by_dir, dir, comp);
else if (isdir (dir))
{
- if (isdir (CVSADM))
+ if ((which & W_LOCAL) && isdir (CVSADM)
+#ifdef CLIENT_SUPPORT
+ && !client_active
+#endif
+ )
{
/* otherwise, look for it in the repository. */
- char *save_update_dir;
+ char *tmp_update_dir;
char *repos;
-
- /* save & set (aka push) update_dir */
- save_update_dir = xstrdup (update_dir);
+ char *reposfile;
+
+ tmp_update_dir = xmalloc (strlen (update_dir)
+ + strlen (dir)
+ + 5);
+ strcpy (tmp_update_dir, update_dir);
- if (*update_dir != '\0')
- (void) strcat (update_dir, "/");
+ if (*tmp_update_dir != '\0')
+ (void) strcat (tmp_update_dir, "/");
+
+ (void) strcat (tmp_update_dir, dir);
- (void) strcat (update_dir, dir);
-
/* look for it in the repository. */
- repos = Name_Repository (dir, update_dir);
- (void) sprintf (tmp, "%s/%s", repos, comp);
+ repos = Name_Repository (dir, tmp_update_dir);
+ reposfile = xmalloc (strlen (repos)
+ + strlen (comp)
+ + 5);
+ (void) sprintf (reposfile, "%s/%s", repos, comp);
free (repos);
- if (!wrap_name_has (comp, WRAP_TOCVS) && isdir(tmp))
+ if (!wrap_name_has (comp, WRAP_TOCVS) && isdir (reposfile))
addlist (&dirlist, argv[i]);
else
addfile (&files_by_dir, dir, comp);
- (void) sprintf (update_dir, "%s", save_update_dir);
- free (save_update_dir);
+ free (tmp_update_dir);
+ free (reposfile);
}
else
addfile (&files_by_dir, dir, comp);
@@ -220,6 +268,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
else
error (1, 0, "no such directory `%s'", dir);
+ free (file_to_try);
free (dir);
free (comp);
}
@@ -229,29 +278,21 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
a coupla lists. Now we unroll the lists, setting up and
calling do_recursion. */
- frame.fileproc = fileproc;
- frame.filesdoneproc = filesdoneproc;
- frame.direntproc = direntproc;
- frame.dirleaveproc = dirleaveproc;
- frame.flags = flags;
- frame.which = which;
- frame.aflag = aflag;
- frame.readlock = readlock;
- frame.dosrcs = dosrcs;
err += walklist (files_by_dir, unroll_files_proc, (void *) &frame);
+ dellist(&files_by_dir);
/* then do_recursion on the dirlist. */
if (dirlist != NULL)
- err += do_recursion (frame.fileproc, frame.filesdoneproc,
- frame.direntproc, frame.dirleaveproc,
- frame.flags, frame.which, frame.aflag,
- frame.readlock, frame.dosrcs);
+ err += do_recursion (&frame);
/* Free the data which expand_wild allocated. */
for (i = 0; i < argc; ++i)
free (argv[i]);
free (argv);
+ out:
+ free (update_dir);
+ update_dir = NULL;
return (err);
}
@@ -259,38 +300,21 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
* Implement the recursive policies on the local directory. This may be
* called directly, or may be called by start_recursion
*/
-int
-do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
- xflags, xwhich, xaflag, xreadlock, xdosrcs)
- FILEPROC xfileproc;
- FILESDONEPROC xfilesdoneproc;
- DIRENTPROC xdirentproc;
- DIRLEAVEPROC xdirleaveproc;
- Dtype xflags;
- int xwhich;
- int xaflag;
- int xreadlock;
- int xdosrcs;
+static int
+do_recursion (frame)
+ struct recursion_frame *frame;
{
int err = 0;
int dodoneproc = 1;
char *srepository;
List *entries = NULL;
+ int should_readlock;
/* do nothing if told */
- if (xflags == R_SKIP_ALL)
+ if (frame->flags == R_SKIP_ALL)
return (0);
- /* set up the static vars */
- fileproc = xfileproc;
- filesdoneproc = xfilesdoneproc;
- direntproc = xdirentproc;
- dirleaveproc = xdirleaveproc;
- flags = xflags;
- which = xwhich;
- aflag = xaflag;
- readlock = noexec ? 0 : xreadlock;
- dosrcs = xdosrcs;
+ should_readlock = noexec ? 0 : frame->readlock;
/* The fact that locks are not active here is what makes us fail to have
the
@@ -332,14 +356,14 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
*/
if (server_active
/* If there are writelocks around, we cannot pause here. */
- && (readlock || noexec))
+ && (should_readlock || noexec))
server_pause_check();
#endif
/*
* Fill in repository with the current repository
*/
- if (which & W_LOCAL)
+ if (frame->which & W_LOCAL)
{
if (isdir (CVSADM))
repository = Name_Repository ((char *) NULL, update_dir);
@@ -348,8 +372,9 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
}
else
{
- repository = xmalloc (PATH_MAX);
- (void) getwd (repository);
+ repository = xgetwd ();
+ if (repository == NULL)
+ error (1, errno, "could not get working directory");
}
srepository = repository; /* remember what to free */
@@ -373,41 +398,52 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
if (filelist == NULL && dirlist == NULL)
{
/* both lists were NULL, so start from scratch */
- if (fileproc != NULL && flags != R_SKIP_FILES)
+ if (frame->fileproc != NULL && frame->flags != R_SKIP_FILES)
{
- int lwhich = which;
+ int lwhich = frame->which;
/* be sure to look in the attic if we have sticky tags/date */
if ((lwhich & W_ATTIC) == 0)
if (isreadable (CVSADM_TAG))
lwhich |= W_ATTIC;
+ /* In the !(which & W_LOCAL) case, we filled in repository
+ earlier in the function. In the (which & W_LOCAL) case,
+ the Find_Names function is going to look through the
+ Entries file. If we do not have a repository, that
+ does not make sense, so we insist upon having a
+ repository at this point. Name_Repository will give a
+ reasonable error message. */
+ if (repository == NULL)
+ repository = Name_Repository ((char *) NULL, update_dir);
+
/* find the files and fill in entries if appropriate */
- filelist = Find_Names (repository, lwhich, aflag, &entries);
+ filelist = Find_Names (repository, lwhich, frame->aflag, &entries);
}
/* find sub-directories if we will recurse */
- if (flags != R_SKIP_DIRS)
- dirlist = Find_Directories (repository, which);
+ if (frame->flags != R_SKIP_DIRS)
+ dirlist = Find_Directories (repository, frame->which, entries);
}
else
{
/* something was passed on the command line */
- if (filelist != NULL && fileproc != NULL)
+ if (filelist != NULL && frame->fileproc != NULL)
{
/* we will process files, so pre-parse entries */
- if (which & W_LOCAL)
- entries = Entries_Open (aflag);
+ if (frame->which & W_LOCAL)
+ entries = Entries_Open (frame->aflag);
}
}
/* process the files (if any) */
- if (filelist != NULL && fileproc)
+ if (filelist != NULL && frame->fileproc)
{
struct file_info finfo_struct;
+ struct frame_and_file frfile;
/* read lock it if necessary */
- if (readlock && repository && Reader_Lock (repository) != 0)
+ if (should_readlock && repository && Reader_Lock (repository) != 0)
error (1, 0, "read lock failed - giving up");
#ifdef CLIENT_SUPPORT
@@ -424,39 +460,50 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
finfo_struct.entries = entries;
/* do_file_proc will fill in finfo_struct.file. */
+ frfile.finfo = &finfo_struct;
+ frfile.frame = frame;
+
/* process the files */
- err += walklist (filelist, do_file_proc, &finfo_struct);
+ err += walklist (filelist, do_file_proc, &frfile);
/* unlock it */
- if (readlock)
+ if (should_readlock)
Lock_Cleanup ();
/* clean up */
dellist (&filelist);
}
- if (entries)
- {
- Entries_Close (entries);
- entries = NULL;
- }
-
/* call-back files done proc (if any) */
- if (dodoneproc && filesdoneproc != NULL)
- err = filesdoneproc (err, repository, update_dir[0] ? update_dir : ".");
+ if (dodoneproc && frame->filesdoneproc != NULL)
+ err = frame->filesdoneproc (frame->callerdat, err, repository,
+ update_dir[0] ? update_dir : ".",
+ entries);
fileattr_write ();
fileattr_free ();
/* process the directories (if necessary) */
if (dirlist != NULL)
- err += walklist (dirlist, do_dir_proc, NULL);
-#ifdef notdef
- else if (dirleaveproc != NULL)
- err += dirleaveproc(".", err, ".");
+ {
+ struct frame_and_entries frent;
+
+ frent.frame = frame;
+ frent.entries = entries;
+ err += walklist (dirlist, do_dir_proc, (void *) &frent);
+ }
+#if 0
+ else if (frame->dirleaveproc != NULL)
+ err += frame->dirleaveproc (frame->callerdat, ".", err, ".");
#endif
dellist (&dirlist);
+ if (entries)
+ {
+ Entries_Close (entries);
+ entries = NULL;
+ }
+
/* free the saved copy of the pointer if necessary */
if (srepository)
{
@@ -475,7 +522,8 @@ do_file_proc (p, closure)
Node *p;
void *closure;
{
- struct file_info *finfo = (struct file_info *)closure;
+ struct frame_and_file *frfile = (struct frame_and_file *)closure;
+ struct file_info *finfo = frfile->finfo;
int ret;
finfo->file = p->key;
@@ -490,15 +538,20 @@ do_file_proc (p, closure)
}
strcat (finfo->fullname, finfo->file);
- if (dosrcs && repository)
+ if (frfile->frame->dosrcs && repository)
finfo->rcs = RCS_parse (finfo->file, repository);
else
finfo->rcs = (RCSNode *) NULL;
- ret = fileproc (finfo);
+ ret = frfile->frame->fileproc (frfile->frame->callerdat, finfo);
freercsnode(&finfo->rcs);
free (finfo->fullname);
+ /* Allow the user to monitor progress with tail -f. Doing this once
+ per file should be no big deal, but we don't want the performance
+ hit of flushing on every line like previous versions of CVS. */
+ cvs_flushout ();
+
return (ret);
}
@@ -510,8 +563,11 @@ do_dir_proc (p, closure)
Node *p;
void *closure;
{
+ struct frame_and_entries *frent = (struct frame_and_entries *) closure;
+ struct recursion_frame *frame = frent->frame;
+ struct recursion_frame xframe;
char *dir = p->key;
- char newrepos[PATH_MAX];
+ char *newrepos;
List *sdirlist;
char *srepository;
char *cp;
@@ -519,6 +575,46 @@ do_dir_proc (p, closure)
int stripped_dot = 0;
int err = 0;
struct saved_cwd cwd;
+ char *saved_update_dir;
+
+ if (fncmp (dir, CVSADM) == 0)
+ {
+ /* This seems to most often happen when users (beginning users,
+ generally), try "cvs ci *" or something similar. On that
+ theory, it is possible that we should just silently skip the
+ CVSADM directories, but on the other hand, using a wildcard
+ like this isn't necessarily a practice to encourage (it operates
+ only on files which exist in the working directory, unlike
+ regular CVS recursion). */
+
+ /* FIXME-reentrancy: printed_cvs_msg should be in a "command
+ struct" or some such, so that it gets cleared for each new
+ command (this is possible using the remote protocol and a
+ custom-written client). The struct recursion_frame is not
+ far back enough though, some commands (commit at least)
+ will call start_recursion several times. An alternate solution
+ would be to take this whole check and move it to a new function
+ validate_arguments or some such that all the commands call
+ and which snips the offending directory from the argc,argv
+ vector. */
+ static int printed_cvs_msg = 0;
+ if (!printed_cvs_msg)
+ {
+ error (0, 0, "warning: directory %s specified in argument",
+ dir);
+ error (0, 0, "\
+but CVS uses %s for its own purposes; skipping %s directory",
+ CVSADM, dir);
+ printed_cvs_msg = 1;
+ }
+ return 0;
+ }
+
+ saved_update_dir = update_dir;
+ update_dir = xmalloc (strlen (saved_update_dir)
+ + strlen (dir)
+ + 5);
+ strcpy (update_dir, saved_update_dir);
/* set up update_dir - skip dots if not at start */
if (strcmp (dir, ".") != 0)
@@ -539,9 +635,12 @@ do_dir_proc (p, closure)
* update -d and in that case the generated name will be correct.
*/
if (repository == NULL)
- newrepos[0] = '\0';
+ newrepos = xstrdup ("");
else
+ {
+ newrepos = xmalloc (strlen (repository) + strlen (dir) + 5);
(void) sprintf (newrepos, "%s/%s", repository, dir);
+ }
}
else
{
@@ -549,31 +648,33 @@ do_dir_proc (p, closure)
(void) strcpy (update_dir, dir);
if (repository == NULL)
- newrepos[0] = '\0';
+ newrepos = xstrdup ("");
else
- (void) strcpy (newrepos, repository);
+ newrepos = xstrdup (repository);
}
/* call-back dir entry proc (if any) */
- if (direntproc != NULL)
- dir_return = direntproc (dir, newrepos, update_dir);
+ if (frame->direntproc != NULL)
+ dir_return = frame->direntproc (frame->callerdat, dir, newrepos,
+ update_dir, frent->entries);
+ free (newrepos);
/* only process the dir if the return code was 0 */
if (dir_return != R_SKIP_ALL)
{
/* save our current directory and static vars */
if (save_cwd (&cwd))
- exit (EXIT_FAILURE);
+ error_exit ();
sdirlist = dirlist;
srepository = repository;
dirlist = NULL;
/* cd to the sub-directory */
- if (chdir (dir) < 0)
+ if ( CVS_CHDIR (dir) < 0)
error (1, errno, "could not chdir to %s", dir);
/* honor the global SKIP_DIRS (a.k.a. local) */
- if (flags == R_SKIP_DIRS)
+ if (frame->flags == R_SKIP_DIRS)
dir_return = R_SKIP_DIRS;
/* remember if the `.' will be stripped for subsequent dirs */
@@ -584,31 +685,37 @@ do_dir_proc (p, closure)
}
/* make the recursive call */
- err += do_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
- dir_return, which, aflag, readlock, dosrcs);
+ xframe = *frame;
+ xframe.flags = dir_return;
+ err += do_recursion (&xframe);
/* put the `.' back if necessary */
if (stripped_dot)
(void) strcpy (update_dir, ".");
/* call-back dir leave proc (if any) */
- if (dirleaveproc != NULL)
- err = dirleaveproc (dir, err, update_dir);
+ if (frame->dirleaveproc != NULL)
+ err = frame->dirleaveproc (frame->callerdat, dir, err, update_dir,
+ frent->entries);
/* get back to where we started and restore state vars */
if (restore_cwd (&cwd, NULL))
- exit (EXIT_FAILURE);
+ error_exit ();
free_cwd (&cwd);
dirlist = sdirlist;
repository = srepository;
}
- /* put back update_dir */
+ /* Put back update_dir. I think this is the same as just setting
+ update_dir back to saved_update_dir, but there are a few cases I'm
+ not sure about (in particular, if DIR is "." and update_dir is
+ not ""), so for conservatism I'm leaving this here. */
cp = last_component (update_dir);
if (cp > update_dir)
cp[-1] = '\0';
else
update_dir[0] = '\0';
+ free (saved_update_dir);
return (err);
}
@@ -675,17 +782,22 @@ unroll_files_proc (p, closure)
/* otherwise, call dorecusion for this list of files. */
filelist = (List *) p->data;
+ p->data = NULL;
save_dirlist = dirlist;
dirlist = NULL;
if (strcmp(p->key, ".") != 0)
{
if (save_cwd (&cwd))
- exit (EXIT_FAILURE);
- if (chdir (p->key) < 0)
+ error_exit ();
+ if ( CVS_CHDIR (p->key) < 0)
error (1, errno, "could not chdir to %s", p->key);
- save_update_dir = xstrdup (update_dir);
+ save_update_dir = update_dir;
+ update_dir = xmalloc (strlen (save_update_dir)
+ + strlen (p->key)
+ + 5);
+ strcpy (update_dir, save_update_dir);
if (*update_dir != '\0')
(void) strcat (update_dir, "/");
@@ -693,18 +805,15 @@ unroll_files_proc (p, closure)
(void) strcat (update_dir, p->key);
}
- err += do_recursion (frame->fileproc, frame->filesdoneproc,
- frame->direntproc, frame->dirleaveproc,
- frame->flags, frame->which, frame->aflag,
- frame->readlock, frame->dosrcs);
+ err += do_recursion (frame);
if (save_update_dir != NULL)
{
- (void) strcpy (update_dir, save_update_dir);
- free (save_update_dir);
+ free (update_dir);
+ update_dir = save_update_dir;
if (restore_cwd (&cwd, NULL))
- exit (EXIT_FAILURE);
+ error_exit ();
free_cwd (&cwd);
}
OpenPOWER on IntegriCloud