diff options
author | peter <peter@FreeBSD.org> | 2004-06-10 19:05:38 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2004-06-10 19:05:38 +0000 |
commit | 8416bda1d23bda4666a5b880a9d78eccaa640036 (patch) | |
tree | 7d97944b58f1e30ab542f9c3d6720b69314cec4d /contrib/cvs/src | |
parent | 3d101ef985844544d089e129157a94a0640fd246 (diff) | |
download | FreeBSD-src-8416bda1d23bda4666a5b880a9d78eccaa640036.zip FreeBSD-src-8416bda1d23bda4666a5b880a9d78eccaa640036.tar.gz |
Import cvs-1.11.17 onto vendor branch.
Diffstat (limited to 'contrib/cvs/src')
-rw-r--r-- | contrib/cvs/src/ChangeLog | 108 | ||||
-rw-r--r-- | contrib/cvs/src/add.c | 24 | ||||
-rw-r--r-- | contrib/cvs/src/client.c | 2 | ||||
-rw-r--r-- | contrib/cvs/src/commit.c | 125 | ||||
-rw-r--r-- | contrib/cvs/src/cvs.h | 5 | ||||
-rw-r--r-- | contrib/cvs/src/filesubr.c | 8 | ||||
-rw-r--r-- | contrib/cvs/src/history.c | 33 | ||||
-rw-r--r-- | contrib/cvs/src/ignore.c | 4 | ||||
-rw-r--r-- | contrib/cvs/src/log.c | 6 | ||||
-rwxr-xr-x | contrib/cvs/src/sanity.sh | 134 | ||||
-rw-r--r-- | contrib/cvs/src/server.c | 76 | ||||
-rw-r--r-- | contrib/cvs/src/subr.c | 41 | ||||
-rw-r--r-- | contrib/cvs/src/update.c | 50 | ||||
-rw-r--r-- | contrib/cvs/src/vers_ts.c | 2 | ||||
-rw-r--r-- | contrib/cvs/src/wrapper.c | 34 |
15 files changed, 522 insertions, 130 deletions
diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog index f7e9470..87caf76 100644 --- a/contrib/cvs/src/ChangeLog +++ b/contrib/cvs/src/ChangeLog @@ -1,3 +1,111 @@ +2004-06-09 Derek Price <derek@ximbiot.com> + + * commit.c, filesubr.c, history.c, server.c, wrapper.c: Various + security fixes. + (Original patch from Stefan Essler <s.esser@e-matters.de> & Sebastian + Krahmer <krahmer@suse.de>.) + + * cvs.h: Include xsize.h. + +2004-06-09 Derek Price <derek@ximbiot.com> + + * server.c (serve_entry, serve_is_modified, serve_unchanged): Protect + against malformed entries. + * sanity.sh (server): Tests for same. + +2004-06-07 Larry Jones <lawrence.jones@ugsplm.com> + + * sanity.sh (basica): More tests for string-based revision inc. + +2004-06-04 Larry Jones <lawrence.jones@ugsplm.com> + + * subr.c (increment_revnum): Rewrite ala RCS to work directly on + the string rather than converting to int to avoid overflow. + * sanity.sh (basica): New tests for above, update others to match. + +2004-05-19 Derek Price <derek@ximbiot.com> + + * server.c (serve_unchanged, serve_is_modified): Overwrite existing + data in timefields. Fixes CAN-2004-0396. + +2004-05-14 Derek Price <derek@ximbiot.com> + + * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Don't + require '=' to be the only character here, as this is potentially + destabilizing. + +2004-05-14 Mark D. Baushke <mdb@cvshome.org> + + * sanity.sh (trailingslashes): During cleanup remove topfile,v to + avoid problems in later tests (editor-1). + +2004-05-13 Derek Price <derek@ximbiot.com> + + * sanity.sh (trailingslashes): Note TODO item #205 in the comment. + +2004-05-13 Derek Price <derek@ximbiot.com> + + * sanity.sh (trailingslashes): New tests to expose a bug in CVS when + paths are specified with trailing slashes. This relates to TODO #205. + +2004-05-12 Derek Price <derek@ximbiot.com> + + * subr.c (file_has_conflict), vers_ts.c (time_stamp_server): Only + special case "=" when it is the only character in a timestamp field. + Gratuitous reformatting. + * vers_ts.c (time_stamp_server): Check for NULL in a consistent manner. + Gratuitous reformatting. + +2004-05-10 Derek Price <derek@ximbiot.com> + + * sanity.sh (top-level): Rename to... + (rstar-toplevel): ...this for clarity. + +2004-05-10 Derek Price <derek@ximbiot.com> + + * sanity.sh (dirs2-10ar): Remove unnecessary empty argument. + +2004-05-02 Larry Jones <lawrence.jones@ugsplm.com> + + * log.c (log_expand_revlist): Suppress warnings if really_quiet. + +2004-05-07 Derek Price <derek@ximbiot.com> + + * sanity.sh (basica): Remove unnecessary empty arguments. + +2004-05-07 Derek Price <derek@ximbiot.com> + + * cvs.h (fopen_case): Remove obsolescent prototype. + +2004-05-05 Derek Price <derek@ximbiot.com> + + * sanity.sh: Wait a second and retry if cvs-serv* directories are + discovered to avoid race conditions on some systems. + (Patch from Pavel Roskin <proski@gnu.org>.) + +2004-05-05 Derek Price <derek@ximbiot.com> + + * commit.c: Some gratuitous reformatting. + +2004-05-04 Derek Price <derek@ximbiot.com> + + * update.c: Some gratuitous reformatting. + +2004-05-04 Derek Price <derek@ximbiot.com> + + * add.c (add): Remove obsolete FIXME comment. + (*): Some gratuitous reformatting. + +2004-04-26 Derek Price <derek@ximbiot.com> + + * client.c (start_rsh_server): Don't rely on GNU argument processing + capabilities in the RSH command. + (Report from Mark Andrews <Mark_Andrews@isc.org>.) + +2004-04-19 Derek Price <derek@ximbiot.com> + + * ignore.c: Gratuitous reformatting. + 2004-04-11 Derek Price <derek@ximbiot.com> * client.c (call_in_directory): Check paths the server sends us to make diff --git a/contrib/cvs/src/add.c b/contrib/cvs/src/add.c index d71716b..4f3f55e 100644 --- a/contrib/cvs/src/add.c +++ b/contrib/cvs/src/add.c @@ -187,16 +187,6 @@ add (argc, argv) /* FIXME: Does this erroneously call Create_Admin in error conditions which are only detected once the server gets its hands on things? */ - /* FIXME-also: if filenames are case-insensitive on the - client, and the directory in the repository already - exists and is named "foo", and the command is "cvs add - FOO", this call to Create_Admin puts the wrong thing in - CVS/Repository and so a subsequent "cvs update" will - give an error. The fix will be to have the server report - back what it actually did (e.g. use tagged text for the - "Directory %s added" message), and then Create_Admin, - which should also fix the error handling concerns. */ - if (isdir (argv[j])) { char *tag; @@ -698,9 +688,11 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname); if (options) free (options); - return (err); + return err; } + + /* * The specified user file is really a directory. So, let's make sure that * it is created in the RCS source repository, and that the user's directory @@ -728,12 +720,12 @@ add_directory (finfo) /* "Can't happen". */ error (0, 0, "directory %s not added; must be a direct sub-directory", dir); - return (1); + return 1; } if (fncmp (dir, CVSADM) == 0) { error (0, 0, "cannot add a `%s' directory", CVSADM); - return (1); + return 1; } /* before we do anything else, see if we have any per-directory tags */ @@ -875,7 +867,7 @@ out: free_cwd (&cwd); if (rcsdir != NULL) free (rcsdir); - return (0); + return 0; } @@ -898,7 +890,7 @@ build_entry (repository, user, options, message, entries, tag) FILE *fp; if (noexec) - return (0); + return 0; /* * The requested log is read directly from the user and stored in the @@ -923,5 +915,5 @@ build_entry (repository, user, options, message, entries, tag) (void) sprintf (line, "Initial %s", user); Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0); free (line); - return (0); + return 0; } diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c index 1b7f7c8..91c61a4 100644 --- a/contrib/cvs/src/client.c +++ b/contrib/cvs/src/client.c @@ -4814,7 +4814,6 @@ start_rsh_server (root, to_server, from_server) const char **p = argv; *p++ = cvs_rsh; - *p++ = root->hostname; /* If the login names differ between client and server * pass it on to rsh. @@ -4825,6 +4824,7 @@ start_rsh_server (root, to_server, from_server) *p++ = root->username; } + *p++ = root->hostname; *p++ = command; *p++ = NULL; diff --git a/contrib/cvs/src/commit.c b/contrib/cvs/src/commit.c index 1548045..86c8106 100644 --- a/contrib/cvs/src/commit.c +++ b/contrib/cvs/src/commit.c @@ -155,7 +155,7 @@ find_dirent_proc (callerdat, dir, repository, update_dir, entries) is that it (or some variant thereof) should go in all the dirent procs. Unless someone has some better idea... */ if (!isdir (dir)) - return (R_SKIP_ALL); + return R_SKIP_ALL; /* initialize the ignore list for this directory */ find_data->ignlist = getlist (); @@ -225,6 +225,8 @@ find_filesdoneproc (callerdat, err, repository, update_dir, entries) return err; } + + static int find_fileproc PROTO ((void *callerdat, struct file_info *finfo)); /* Machinery to find out what is modified, added, and removed. It is @@ -341,6 +343,8 @@ find_fileproc (callerdat, finfo) return 0; } + + static int copy_ulist PROTO ((Node *, void *)); static int @@ -389,15 +393,16 @@ commit (argc, argv) struct passwd *pw; if ((pw = (struct passwd *) getpwnam (getcaller ())) == NULL) - error (1, 0, "your apparent username (%s) is unknown to this system", - getcaller ()); + error (1, 0, + "your apparent username (%s) is unknown to this system", + getcaller ()); if (pw->pw_uid == (uid_t) 0) error (1, 0, "'root' is not allowed to commit files"); } #endif /* CVS_BADROOT */ optind = 0; - while( ( c = getopt( argc, argv, COMMIT_OPTIONS ) ) != -1 ) + while ((c = getopt (argc, argv, COMMIT_OPTIONS)) != -1) { switch (c) { @@ -518,7 +523,12 @@ commit (argc, argv) operate on, and only work with those files in the future. This saves time--we don't want to search the file system of the working directory twice. */ - find_args.argv = (char **) xmalloc (find_args.argc * sizeof (char **)); + if (size_overflow_p (xtimes (find_args.argc, sizeof (char **)))) + { + find_args.argc = 0; + return 0; + } + find_args.argv = xmalloc (xtimes (find_args.argc, sizeof (char **))); find_args.argc = 0; walklist (find_args.ulist, copy_ulist, &find_args); @@ -713,9 +723,11 @@ commit (argc, argv) sleep_past (last_register_time); } - return (err); + return err; } + + /* This routine determines the status of a given file and retrieves the version information that is associated with that file. */ @@ -803,6 +815,8 @@ classify_file_internal (finfo, vers) return status; } + + /* * Check to see if a file is ok to commit and make sure all files are * up-to-date @@ -826,10 +840,11 @@ check_fileproc (callerdat, finfo) if (!finfo->repository) { error (0, 0, "nothing known about `%s'", finfo->fullname); - return (1); + return 1; } - if (strncmp (finfo->repository, current_parsed_root->directory, cvsroot_len) == 0 + if (strncmp (finfo->repository, current_parsed_root->directory, + cvsroot_len) == 0 && ISDIRSEP (finfo->repository[cvsroot_len]) && strncmp (finfo->repository + cvsroot_len + 1, CVSROOTADM, @@ -859,7 +874,7 @@ check_fileproc (callerdat, finfo) case T_REMOVE_ENTRY: error (0, 0, "Up-to-date check failed for `%s'", finfo->fullname); freevers_ts (&vers); - return (1); + return 1; case T_MODIFIED: case T_ADDED: case T_REMOVED: @@ -885,7 +900,7 @@ check_fileproc (callerdat, finfo) "cannot commit with sticky date for file `%s'", finfo->fullname); freevers_ts (&vers); - return (1); + return 1; } if (status == T_MODIFIED && vers->tag && !RCS_isbranch (finfo->rcs, vers->tag)) @@ -894,7 +909,7 @@ check_fileproc (callerdat, finfo) "sticky tag `%s' for file `%s' is not a branch", vers->tag, finfo->fullname); freevers_ts (&vers); - return (1); + return 1; } } if (status == T_MODIFIED && !force_ci && vers->ts_conflict) @@ -911,7 +926,7 @@ check_fileproc (callerdat, finfo) "file `%s' had a conflict and has not been modified", finfo->fullname); freevers_ts (&vers); - return (1); + return 1; } if (file_has_markers (finfo)) @@ -955,7 +970,7 @@ warning: file `%s' seems to still contain conflict indicators", "cannot remove file `%s' which has a numeric sticky" " tag of `%s'", finfo->fullname, vers->tag); freevers_ts (&vers); - return (1); + return 1; } } if (status == T_ADDED) @@ -969,7 +984,7 @@ warning: file `%s' seems to still contain conflict indicators", "cannot add file `%s' when RCS file `%s' already exists", finfo->fullname, finfo->rcs->path); freevers_ts (&vers); - return (1); + return 1; } } else if (isdigit ((unsigned char) *vers->tag) && @@ -979,7 +994,7 @@ warning: file `%s' seems to still contain conflict indicators", "cannot add file `%s' with revision `%s'; must be on trunk", finfo->fullname, vers->tag); freevers_ts (&vers); - return (1); + return 1; } } @@ -1082,7 +1097,7 @@ warning: file `%s' seems to still contain conflict indicators", case T_UNKNOWN: error (0, 0, "nothing known about `%s'", finfo->fullname); freevers_ts (&vers); - return (1); + return 1; case T_UPTODATE: break; default: @@ -1091,7 +1106,7 @@ warning: file `%s' seems to still contain conflict indicators", } freevers_ts (&vers); - return (0); + return 0; } @@ -1110,14 +1125,16 @@ check_direntproc (callerdat, dir, repos, update_dir, entries) List *entries; { if (!isdir (dir)) - return (R_SKIP_ALL); + return R_SKIP_ALL; if (!quiet) error (0, 0, "Examining %s", update_dir); - return (R_PROCESS); + return R_PROCESS; } + + /* * Walklist proc to run pre-commit checks */ @@ -1133,9 +1150,11 @@ precommit_list_proc (p, closure) { run_arg (p->key); } - return (0); + return 0; } + + /* * Callback proc for pre-commit checking */ @@ -1160,7 +1179,7 @@ precommit_proc (repository, filter) { error (0, errno, "cannot find pre-commit filter `%s'", s); free (s); - return (1); /* so it fails! */ + return 1; /* so it fails! */ } free (s); } @@ -1168,9 +1187,11 @@ precommit_proc (repository, filter) run_setup (filter); run_arg (repository); (void) walklist (saved_ulist, precommit_list_proc, NULL); - return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY)); + return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY); } + + /* * Run the pre-commit checks for the dir */ @@ -1195,7 +1216,7 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries) /* skip the checks if there's nothing to do */ if (saved_ulist == NULL || saved_ulist->list->next == saved_ulist->list) - return (err); + return err; /* run any pre-commit checks */ if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, 1)) > 0) @@ -1204,9 +1225,11 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries) err += n; } - return (err); + return err; } + + /* * Do the work of committing a file */ @@ -1249,7 +1272,7 @@ commit_fileproc (callerdat, finfo) * all up-to-date so nothing really needs to be done */ if (p == NULL) - return (0); + return 0; ulist = ((struct master_lists *) p->data)->ulist; cilist = ((struct master_lists *) p->data)->cilist; @@ -1273,7 +1296,7 @@ commit_fileproc (callerdat, finfo) p = findnode (cilist, finfo->file); if (p == NULL) - return (0); + return 0; ci = p->data; if (ci->status == T_MODIFIED) @@ -1431,9 +1454,11 @@ out: if (SIG_inCrSect ()) SIG_endCrSect (); - return (err); + return err; } + + /* * Log the commit and clean up the update list */ @@ -1451,7 +1476,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries) p = findnode (mulist, update_dir); if (p == NULL) - return (err); + return err; ulist = ((struct master_lists *) p->data)->ulist; @@ -1501,9 +1526,11 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries) } } - return (err); + return err; } + + /* * Get the log message for a dir */ @@ -1521,7 +1548,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries) char *real_repos; if (!isdir (dir)) - return (R_SKIP_ALL); + return R_SKIP_ALL; /* find the update list for this dir */ p = findnode (mulist, update_dir); @@ -1532,7 +1559,7 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries) /* skip the files as an optimization */ if (ulist == NULL || ulist->list->next == ulist->list) - return (R_SKIP_FILES); + return R_SKIP_FILES; /* get commit message */ real_repos = Name_Repository (dir, update_dir); @@ -1545,9 +1572,11 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries) do_editor (update_dir, &saved_message, real_repos, ulist); do_verify (&saved_message, real_repos); free (real_repos); - return (R_PROCESS); + return R_PROCESS; } + + /* * Process the post-commit proc if necessary */ @@ -1572,9 +1601,11 @@ commit_dirleaveproc (callerdat, dir, err, update_dir, entries) free (repos); } - return (err); + return err; } + + /* * find the maximum major rev number in an entries file */ @@ -1661,7 +1692,7 @@ remove_file (finfo, tag, message) if (rev == NULL) { error (0, 0, "cannot find branch \"%s\".", tag); - return (1); + return 1; } branchname = RCS_getbranch (finfo->rcs, rev, 1); @@ -1693,7 +1724,7 @@ remove_file (finfo, tag, message) { error (0, 0, "cannot change branch to default for %s", finfo->fullname); - return (1); + return 1; } RCS_rewrite (finfo->rcs, NULL, NULL); } @@ -1707,7 +1738,7 @@ remove_file (finfo, tag, message) { error (0, 0, "failed to check out `%s'", finfo->fullname); - return (1); + return 1; } /* Except when we are creating a branch, lock the revision so that @@ -1728,7 +1759,7 @@ remove_file (finfo, tag, message) if (!quiet) error (0, retcode == -1 ? errno : 0, "failed to commit dead revision for `%s'", finfo->fullname); - return (1); + return 1; } /* At this point, the file has been committed as removed. We should probably tell the history file about it */ @@ -1753,9 +1784,11 @@ remove_file (finfo, tag, message) free (old_path); Scratch_Entry (finfo->entries, finfo->file); - return (0); + return 0; } + + /* * Do the actual checkin for added files */ @@ -1784,9 +1817,11 @@ finaladd (finfo, rev, tag, options) (void) time (&last_register_time); - return (ret); + return ret; } + + /* * Unlock an rcs file */ @@ -1852,6 +1887,8 @@ fixbranch (rcs, branch) } } + + /* * do the initial part of a file add for the named file. if adding * with a tag, put the file in the Attic and point the symbolic tag @@ -2189,6 +2226,8 @@ checkaddfile (file, repository, tag, options, rcsnode) return retval; } + + /* * Attempt to place a lock on the RCS file; returns 0 if it could and 1 if it * couldn't. If the RCS file currently has a branch as the head, we must @@ -2226,7 +2265,7 @@ lock_RCS (user, rcs, rev, repository) rcs->path); if (branch) free (branch); - return (1); + return 1; } } err = RCS_lock (rcs, NULL, 1); @@ -2260,7 +2299,7 @@ lock_RCS (user, rcs, rev, repository) if (sbranch != NULL) free (sbranch); sbranch = branch; - return (0); + return 0; } /* try to restore the branch if we can on error */ @@ -2269,9 +2308,11 @@ lock_RCS (user, rcs, rev, repository) if (branch) free (branch); - return (1); + return 1; } + + /* * free an UPDATE node's data */ diff --git a/contrib/cvs/src/cvs.h b/contrib/cvs/src/cvs.h index 42c08f5..9f601ce 100644 --- a/contrib/cvs/src/cvs.h +++ b/contrib/cvs/src/cvs.h @@ -40,6 +40,10 @@ #include "popen.h" #endif +/* Begin GNULIB headers. */ +#include "xsize.h" +/* End GNULIB headers. */ + #ifdef STDC_HEADERS #include <stdlib.h> #else @@ -608,7 +612,6 @@ extern void expand_wild PROTO ((int argc, char **argv, #ifdef SERVER_SUPPORT extern int cvs_casecmp PROTO ((const char *, const char *)); -extern int fopen_case PROTO ((char *, char *, FILE **, char **)); #endif void strip_trailing_slashes PROTO((char *path)); diff --git a/contrib/cvs/src/filesubr.c b/contrib/cvs/src/filesubr.c index 57511f4..8b5990a 100644 --- a/contrib/cvs/src/filesubr.c +++ b/contrib/cvs/src/filesubr.c @@ -1029,8 +1029,14 @@ expand_wild (argc, argv, pargc, pargv) char ***pargv; { int i; + if (size_overflow_p (xtimes (argc, sizeof (char *)))) { + *pargc = 0; + *pargv = NULL; + error (0, 0, "expand_wild: too many arguments"); + return; + } *pargc = argc; - *pargv = (char **) xmalloc (argc * sizeof (char *)); + *pargv = xmalloc (xtimes (argc, sizeof (char *))); for (i = 0; i < argc; ++i) (*pargv)[i] = xstrdup (argv[i]); } diff --git a/contrib/cvs/src/history.c b/contrib/cvs/src/history.c index 8e8d607..154c2de 100644 --- a/contrib/cvs/src/history.c +++ b/contrib/cvs/src/history.c @@ -416,8 +416,11 @@ history (argc, argv) working = 1; break; case 'X': /* Undocumented debugging flag */ +#ifdef DEBUG histfile = optarg; +#endif break; + case 'D': /* Since specified date */ if (*since_rev || *since_tag || *backto) { @@ -906,9 +909,13 @@ save_user (name) { if (user_count == user_max) { - user_max += USER_INCREMENT; - user_list = (char **) xrealloc ((char *) user_list, - (int) user_max * sizeof (char *)); + user_max = xsum (user_max, USER_INCREMENT); + if (size_overflow_p (xtimes (user_max, sizeof (char *)))) + { + error (0, 0, "save_user: too many users"); + return; + } + user_list = xrealloc (user_list, xtimes (user_max, sizeof (char *))); } user_list[user_count++] = xstrdup (name); } @@ -936,9 +943,13 @@ save_file (dir, name, module) if (file_count == file_max) { - file_max += FILE_INCREMENT; - file_list = (struct file_list_str *) xrealloc ((char *) file_list, - file_max * sizeof (*fl)); + file_max = xsum (file_max, FILE_INCREMENT); + if (size_overflow_p (xtimes (file_max, sizeof (*fl)))) + { + error (0, 0, "save_file: too many files"); + return; + } + file_list = xrealloc (file_list, xtimes (file_max, sizeof (*fl))); } fl = &file_list[file_count++]; fl->l_file = cp = xmalloc (strlen (dir) + strlen (name) + 2); @@ -977,9 +988,13 @@ save_module (module) { if (mod_count == mod_max) { - mod_max += MODULE_INCREMENT; - mod_list = (char **) xrealloc ((char *) mod_list, - mod_max * sizeof (char *)); + mod_max = xsum (mod_max, MODULE_INCREMENT); + if (size_overflow_p (xtimes (mod_max, sizeof (char *)))) + { + error (0, 0, "save_module: too many modules"); + return; + } + mod_list = xrealloc (mod_list, xtimes (mod_max, sizeof (char *))); } mod_list[mod_count++] = xstrdup (module); } diff --git a/contrib/cvs/src/ignore.c b/contrib/cvs/src/ignore.c index 26c39e7..e9bcf79 100644 --- a/contrib/cvs/src/ignore.c +++ b/contrib/cvs/src/ignore.c @@ -44,6 +44,8 @@ const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\ no longer ask the server about what is in CVSROOTADM_IGNORE. */ int ign_inhibit_server; + + /* * To the "ignore list", add the hard-coded default ignored wildcards above, * the wildcards found in $CVSROOT/CVSROOT/cvsignore, the wildcards found in @@ -100,6 +102,8 @@ ign_setup () /* Later, add ignore entries found in -I arguments */ } + + /* * Open a file and read lines, feeding each line to a line parser. Arrange * for keeping a temporary list of wildcards at the end, if the "hold" diff --git a/contrib/cvs/src/log.c b/contrib/cvs/src/log.c index 1de1b94..9e10bd9 100644 --- a/contrib/cvs/src/log.c +++ b/contrib/cvs/src/log.c @@ -1078,7 +1078,7 @@ log_expand_revlist (rcs, revlist, default_branch) free (branch); } } - if (nr->first == NULL) + if (nr->first == NULL && !really_quiet) { error (0, 0, "warning: no branch `%s' in `%s'", r->first, rcs->path); @@ -1101,7 +1101,7 @@ log_expand_revlist (rcs, revlist, default_branch) nr->first = RCS_whatbranch (rcs, r->first); else nr->first = RCS_gettag (rcs, r->first, 1, (int *) NULL); - if (nr->first == NULL) + if (nr->first == NULL && !really_quiet) { error (0, 0, "warning: no revision `%s' in `%s'", r->first, rcs->path); @@ -1119,7 +1119,7 @@ log_expand_revlist (rcs, revlist, default_branch) nr->last = RCS_whatbranch (rcs, r->last); else nr->last = RCS_gettag (rcs, r->last, 1, (int *) NULL); - if (nr->last == NULL) + if (nr->last == NULL && !really_quiet) { error (0, 0, "warning: no revision `%s' in `%s'", r->last, rcs->path); diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh index 015d83e..acbb8d0 100755 --- a/contrib/cvs/src/sanity.sh +++ b/contrib/cvs/src/sanity.sh @@ -792,7 +792,7 @@ if test x"$*" = x; then tests="${tests} modules modules2 modules3 modules4 modules5 modules6" tests="${tests} mkmodules co-d" tests="${tests} cvsadm emptydir abspath abspath2 toplevel toplevel2" - tests="${tests} top-level checkout_repository" + tests="${tests} rstar-toplevel trailingslashes checkout_repository" # Log messages, error messages. tests="${tests} mflag editor errmsg1 errmsg2 adderrmsg opterrmsg" # Watches, binary files, history browsing, &c. @@ -1920,12 +1920,45 @@ done" ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile new revision: 2\.0; previous revision: 1\.3 done" + dotest basica-8a1a "${testcvs} -q ci -m bump-it -r 2.9" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.9; previous revision: 2\.0 +done" + # Test string-based revion number increment rollover + dotest basica-8a1b "${testcvs} -q ci -m bump-it -f -r 2" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.10; previous revision: 2\.9 +done" + dotest basica-8a1c "${testcvs} -q ci -m bump-it -r 2.99" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.99; previous revision: 2\.10 +done" + # Test string-based revion number increment rollover + dotest basica-8a1d "${testcvs} -q ci -m bump-it -f -r 2" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.100; previous revision: 2\.99 +done" + dotest basica-8a1e "${testcvs} -q ci -m bump-it -r 2.1099" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.1099; previous revision: 2\.100 +done" + # Test string-based revion number increment rollover + dotest basica-8a1f "${testcvs} -q ci -m bump-it -f -r 2" \ +"Checking in ssfile; +${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile +new revision: 2\.1100; previous revision: 2\.1099 +done" # -f should not be necessary, but it should be harmless. # Also test the "-r 3" (rather than "-r 3.0") usage. dotest basica-8a2 "${testcvs} -q ci -m bump-it -f -r 3" \ "Checking in ssfile; ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v <-- ssfile -new revision: 3\.1; previous revision: 2\.0 +new revision: 3\.1; previous revision: 2\.1100 done" # Test using -r to create a branch @@ -1943,9 +1976,8 @@ done" dotest basica-8a5 "${testcvs} -q up -A ./" "[UP] ssfile" cd ../.. - dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" '' - dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" \ -'' + dotest basica-8b "${testcvs} -q diff -r1.2 -r1.3" + dotest basica-8b1 "${testcvs} -q diff -r1.2 -r1.3 -C 3isacrowd" # The .* here will normally be "No such file or directory", # but if memory serves some systems (AIX?) have a different message. @@ -2013,11 +2045,23 @@ done" done" dotest basica-o5a "${testcvs} -n admin -o 1.2::3.1 ssfile" \ "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 2\.1100 +deleting revision 2\.1099 +deleting revision 2\.100 +deleting revision 2\.99 +deleting revision 2\.10 +deleting revision 2\.9 deleting revision 2\.0 deleting revision 1\.3 done" dotest basica-o6 "${testcvs} admin -o 1.2::3.1 ssfile" \ "RCS file: ${CVSROOT_DIRNAME}/first-dir/sdir/ssdir/ssfile,v +deleting revision 2\.1100 +deleting revision 2\.1099 +deleting revision 2\.100 +deleting revision 2\.99 +deleting revision 2\.10 +deleting revision 2\.9 deleting revision 2\.0 deleting revision 1\.3 done" @@ -6018,8 +6062,7 @@ ${QUESTION} sdir" "${QUESTION} sdir ${PROG} \[update aborted\]: no such tag br" dotest dirs2-10ar \ -"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" \ -"" +"${testcvs} -q rdiff -u -r 1.1 -r br first-dir/sdir/file1" dotest_fail dirs2-10-again "${testcvs} update -d -r br" \ "${QUESTION} sdir ${PROG} update: Updating \. @@ -13849,14 +13892,14 @@ ${PROG} commit: Rebuilding administrative file database" - top-level) + rstar-toplevel) # FIXCVS: # This test confirms a bug that exists in the r* commands currently # when run against the top-level project. # # The assertion failure is something like: # do_recursion: Assertion \`strstr (repository, \"/\./\") == ((void \*)0)' failed\..*" - dotest_fail top-level-1 "$testcvs rlog ." \ + dotest_fail rstar-toplevel-1 "$testcvs rlog ." \ "${DOTSTAR}ssertion.*failed${DOTSTAR}" "${DOTSTAR}failed assertion${DOTSTAR}" if $keep; then @@ -13867,6 +13910,52 @@ ${PROG} commit: Rebuilding administrative file database" + trailingslashes) + # Some tests of CVS's reactions to path specifications containing + # trailing slashes. + mkdir trailingslashes; cd trailingslashes + dotest trailingslashes-init-1 "$testcvs -Q co -ldt ." + dotest trailingslashes-init-2 "$testcvs -Q co -dt2 ." + cd t + echo "Ahh'll be baaack." >topfile + dotest trailingslashes-init-3 "$testcvs -Q add topfile" + dotest trailingslashes-init-4 "$testcvs -Q ci -mto-top" \ +"RCS file: $CVSROOT_DIRNAME/topfile,v +done +Checking in topfile; +$CVSROOT_DIRNAME/topfile,v <-- topfile +initial revision: 1\.1 +done" + + # First, demonstrate the usual case. + cd ../t2 + dotest trailingslashes-1 "$testcvs -q up CVSROOT" + dotest_fail trailingslashes-1a "test -f topfile" + + # FIXCVS: + # Now the one that fails in remote mode. + # This highlights one of the failure cases mentioned in TODO item + # #205. + if $remote; then + dotest trailingslashes-2 "$testcvs -q up CVSROOT/" \ +"U topfile" + dotest trailingslashes-2a "test -f topfile" + else + dotest trailingslashes-2 "$testcvs -q up CVSROOT/" + dotest_fail trailingslashes-2a "test -f topfile" + fi + + if $keep; then + echo Keeping $TESTDIR and exiting due to --keep + exit 0 + fi + + cd ../.. + rm -rf trailingslashes $CVSROOT_DIRNAME/topfile,v + ;; + + + checkout_repository) dotest_fail checkout_repository-1 \ "${testcvs} co -d ${CVSROOT_DIRNAME} CVSROOT" \ @@ -26973,6 +27062,27 @@ Global_option -l noop EOF + # There used to be some exploits based on malformed Entry requests + dotest server-17 "$testcvs server" \ +"E protocol error: Malformed Entry +error " <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos/dir1 +Entry X/file1/1.1//// +noop +EOF + + dotest server-18 "$testcvs server" \ +"E protocol error: Malformed Entry +error " <<EOF +Root $TESTDIR/crerepos +Directory . +$TESTDIR/crerepos/dir1 +Entry /CC/CC/CC +noop +EOF + if $keep; then echo Keeping ${TESTDIR} and exiting due to --keep exit 0 @@ -27494,7 +27604,11 @@ done" # files. We would like to not leave any behind. if $remote && ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then # A true value means ls found files/directories with these names. - fail "Found cvs-serv* directories in $TMPDIR." + # Give the server some time to finish, then retry. + sleep 1 + if ls $TMPDIR/cvs-serv* >/dev/null 2>&1; then + fail "Found cvs-serv* directories in $TMPDIR." + fi fi if ls $TMPDIR/cvs?????? >/dev/null 2>&1; then # A true value means ls found files/directories with these names. diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c index 3d36ad6..bc6578d 100644 --- a/contrib/cvs/src/server.c +++ b/contrib/cvs/src/server.c @@ -917,7 +917,7 @@ serve_max_dotdot (arg) int i; char *p; - if (lim < 0) + if (lim < 0 || lim > 10000) return; p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10); if (p == NULL) @@ -1622,8 +1622,7 @@ serve_unchanged (arg) char *cp; char *timefield; - if (error_pending ()) - return; + if (error_pending ()) return; if (outside_dir (arg)) return; @@ -1637,7 +1636,16 @@ serve_unchanged (arg) && strlen (arg) == cp - name && strncmp (arg, name, cp - name) == 0) { - timefield = strchr (cp + 1, '/') + 1; + if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') + { + /* We didn't find the record separator or it is followed by + * the end of the string, so just exit. + */ + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Malformed Entry encountered."); + return; + } /* If the time field is not currently empty, then one of * serve_modified, serve_is_modified, & serve_unchanged were * already called for this file. We would like to ignore the @@ -1684,8 +1692,7 @@ serve_is_modified (arg) /* Have we found this file in "entries" yet. */ int found; - if (error_pending ()) - return; + if (error_pending ()) return; if (outside_dir (arg)) return; @@ -1700,7 +1707,16 @@ serve_is_modified (arg) && strlen (arg) == cp - name && strncmp (arg, name, cp - name) == 0) { - timefield = strchr (cp + 1, '/') + 1; + if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') + { + /* We didn't find the record separator or it is followed by + * the end of the string, so just exit. + */ + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Malformed Entry encountered."); + return; + } /* If the time field is not currently empty, then one of * serve_modified, serve_is_modified, & serve_unchanged were * already called for this file. We would like to ignore the @@ -1785,8 +1801,29 @@ serve_entry (arg) { struct an_entry *p; char *cp; + int i = 0; if (error_pending()) return; - p = (struct an_entry *) xmalloc (sizeof (struct an_entry)); + + /* Verify that the entry is well-formed. This can avoid problems later. + * At the moment we only check that the Entry contains five slashes in + * approximately the correct locations since some of the code makes + * assumptions about this. + */ + cp = arg; + if (*cp == 'D') cp++; + while (i++ < 5) + { + if (!cp || *cp != '/') + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E protocol error: Malformed Entry"); + return; + } + cp = strchr (cp + 1, '/'); + } + + p = xmalloc (sizeof (struct an_entry)); if (p == NULL) { pending_error = ENOMEM; @@ -2018,6 +2055,9 @@ serve_notify (arg) { char *cp; + if (!data[0]) + goto error; + if (strchr (data, '+')) goto error; @@ -2149,6 +2189,14 @@ serve_argument (arg) char *p; if (error_pending()) return; + + if (argument_count >= 10000) + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Protocol error: too many arguments"); + return; + } if (argument_vector_size <= argument_count) { @@ -2179,6 +2227,14 @@ serve_argumentx (arg) char *p; if (error_pending()) return; + + if (argument_count <= 1) + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Protocol error: called argumentx without prior call to argument"); + return; + } p = argument_vector[argument_count - 1]; p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1); @@ -2512,7 +2568,7 @@ check_command_legal_p (cmd_name) save some code here... -kff */ /* Chop newline by hand, for strcmp()'s sake. */ - if (linebuf[num_red - 1] == '\n') + if (num_red > 0 && linebuf[num_red - 1] == '\n') linebuf[num_red - 1] = '\0'; if (strcmp (linebuf, CVS_Username) == 0) @@ -2567,7 +2623,7 @@ check_command_legal_p (cmd_name) while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) { /* Chop newline by hand, for strcmp()'s sake. */ - if (linebuf[num_red - 1] == '\n') + if (num_red > 0 && linebuf[num_red - 1] == '\n') linebuf[num_red - 1] = '\0'; if (strcmp (linebuf, CVS_Username) == 0) diff --git a/contrib/cvs/src/subr.c b/contrib/cvs/src/subr.c index 94f5bbd..da8d478 100644 --- a/contrib/cvs/src/subr.c +++ b/contrib/cvs/src/subr.c @@ -311,6 +311,9 @@ compare_revnums (rev1, rev2) return result; } +/* Increment a revision number. Working on the string is a bit awkward, + but it avoid problems with integer overflow should the revision numbers + get really big. */ char * increment_revnum (rev) const char *rev; @@ -319,17 +322,29 @@ increment_revnum (rev) int lastfield; size_t len = strlen (rev); - newrev = (char *) xmalloc (len + 2); + newrev = xmalloc (len + 2); memcpy (newrev, rev, len + 1); - p = strrchr (newrev, '.'); - if (p == NULL) + for (p = newrev + len; p != newrev; ) { - free (newrev); - return NULL; + --p; + if (!isdigit(*p)) + { + ++p; + break; + } + if (*p != '9') + { + ++*p; + return newrev; + } + *p = '0'; } - lastfield = atoi (++p); - sprintf (p, "%d", lastfield + 1); - + /* The number was all 9s, so change the first character to 1 and add + a 0 to the end. */ + *p = '1'; + p = newrev + len; + *p++ = '0'; + *p = '\0'; return newrev; } @@ -659,7 +674,7 @@ file_has_conflict (finfo, ts_conflict) /* If ts_conflict is NULL, there was no merge since the last * commit and there can be no conflict. */ - assert ( ts_conflict ); + assert (ts_conflict); /* * If the timestamp has changed and no @@ -668,14 +683,14 @@ file_has_conflict (finfo, ts_conflict) */ #ifdef SERVER_SUPPORT - if ( server_active ) + if (server_active) retcode = ts_conflict[0] == '='; else #endif /* SERVER_SUPPORT */ { - filestamp = time_stamp ( finfo->file ); - retcode = !strcmp ( ts_conflict, filestamp ); - free ( filestamp ); + filestamp = time_stamp (finfo->file); + retcode = !strcmp (ts_conflict, filestamp); + free (filestamp); } return retcode; diff --git a/contrib/cvs/src/update.c b/contrib/cvs/src/update.c index e245e7b..62a6c63 100644 --- a/contrib/cvs/src/update.c +++ b/contrib/cvs/src/update.c @@ -420,9 +420,11 @@ update (argc, argv) if (date != NULL) free (date); - return (err); + return err; } + + /* * Command line interface to update (used by checkout) */ @@ -496,7 +498,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, argc, argv, local, which, aflag, CVS_LOCK_READ, preload_update_dir, 1, (char *) NULL); if (err) - return (err); + return err; /* FIXME-twp: at this point we should walk the hardlist and update the `links' field of each hardlink_info struct @@ -523,7 +525,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, sleep_past (last_register_time); } - return (err); + return err; } #ifdef PRESERVE_PERMISSIONS_SUPPORT @@ -856,7 +858,7 @@ update_filesdone_proc (callerdat, err, repository, update_dir, entries) Create_Root ((char *) NULL, current_parsed_root->original); } - return (err); + return err; } @@ -889,7 +891,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries) { /* if we aren't building dirs, blow it off */ if (!update_build_dirs) - return (R_SKIP_ALL); + return R_SKIP_ALL; /* Various CVS administrators are in the habit of removing the repository directory for things they don't want any @@ -917,7 +919,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries) { /* ignore the missing dir if -n is specified */ error (0, 0, "New directory `%s' -- ignored", update_dir); - return (R_SKIP_ALL); + return R_SKIP_ALL; } else { @@ -1015,7 +1017,7 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries) if (!quiet) error (0, 0, "Updating %s", update_dir); - return (R_PROCESS); + return R_PROCESS; } @@ -1075,9 +1077,11 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries) } } - return (err); + return err; } + + static int isremoved PROTO ((Node *, void *)); /* Returns 1 if the file indicated by node has been removed. */ @@ -1093,6 +1097,8 @@ isremoved (node, closure) return (entdata->version && entdata->version[0] == '-') ? 1 : 0; } + + /* Returns 1 if the argument directory is completely empty, other than the existence of the CVS directory entry. Zero otherwise. If MIGHT_NOT_EXIST and the directory doesn't exist, then just return 0. */ @@ -1109,7 +1115,7 @@ isemptydir (dir, might_not_exist) if (might_not_exist && existence_error (errno)) return 0; error (0, errno, "cannot open directory %s for empty check", dir); - return (0); + return 0; } errno = 0; while ((dp = CVS_READDIR (dirp)) != NULL) @@ -1122,7 +1128,7 @@ isemptydir (dir, might_not_exist) /* An entry other than the CVS directory. The directory is certainly not empty. */ (void) CVS_CLOSEDIR (dirp); - return (0); + return 0; } else { @@ -1153,7 +1159,7 @@ isemptydir (dir, might_not_exist) /* There are files that have been removed, but not committed! Do not consider the directory empty. */ (void) CVS_CLOSEDIR (dirp); - return (0); + return 0; } } } @@ -1163,12 +1169,14 @@ isemptydir (dir, might_not_exist) { error (0, errno, "cannot read directory %s", dir); (void) CVS_CLOSEDIR (dirp); - return (0); + return 0; } (void) CVS_CLOSEDIR (dirp); - return (1); + return 1; } + + /* * scratch the Entries file entry associated with a file */ @@ -1213,9 +1221,11 @@ scratch_file (finfo, vers) vers->ts_user = NULL; } } - return (0); + return 0; } + + /* * Check out a file. */ @@ -1503,9 +1513,11 @@ VERS: ", 0); if (revbuf != NULL) buf_free (revbuf); - return (retval); + return retval; } + + #ifdef SERVER_SUPPORT /* This function is used to write data from a file being checked out @@ -1847,9 +1859,11 @@ patch_file (finfo, vers_ts, docheckout, file_info, checksum) free (backup); free (file1); free (file2); - return (retval); + return retval; } + + /* Write data to a file. Record whether the last byte written was a newline. Optionally compute a checksum. This is called by patch_file via RCS_checkout. */ @@ -2989,8 +3003,10 @@ special_file_mismatch (finfo, rev1, rev2) #endif } + + int joining () { - return (join_rev1 != NULL); + return join_rev1 != NULL; } diff --git a/contrib/cvs/src/vers_ts.c b/contrib/cvs/src/vers_ts.c index 8ad9c4e..69eaa4c 100644 --- a/contrib/cvs/src/vers_ts.c +++ b/contrib/cvs/src/vers_ts.c @@ -287,7 +287,7 @@ time_stamp_server (file, vers_ts, entdata) else if (entdata->timestamp && entdata->timestamp[0] == '=') mark_unchanged (vers_ts); - else if (entdata->timestamp != NULL + else if (entdata->timestamp && (entdata->timestamp[0] == 'M' || entdata->timestamp[0] == 'D') && entdata->timestamp[1] == '\0') diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c index 8d7a8ef..548b3a5 100644 --- a/contrib/cvs/src/wrapper.c +++ b/contrib/cvs/src/wrapper.c @@ -237,6 +237,30 @@ wrap_unparse_rcs_options (line, first_call_p) #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */ /* + * Remove fmt str specifier other than %% or %s. And allow + * only max_s %s specifiers + */ +wrap_clean_fmt_str(char *fmt, int max_s) +{ + while (*fmt) { + if (fmt[0] == '%' && fmt[1]) + { + if (fmt[1] == '%') + fmt++; + else + if (fmt[1] == 's' && max_s > 0) + { + max_s--; + fmt++; + } else + *fmt = ' '; + } + fmt++; + } + return; +} + +/* * Open a file and read lines, feeding each line to a line parser. Arrange * for keeping a temporary list of wrappers at the end, if the "temp" * argument is set. @@ -556,9 +580,8 @@ wrap_tocvs_process_file(fileName) args = xmalloc (strlen (e->tocvsFilter) + strlen (fileName) + strlen (buf)); - /* FIXME: sprintf will blow up if the format string contains items other - than %s, or contains too many %s's. We should instead be parsing - e->tocvsFilter ourselves and giving a real error. */ + + wrap_clean_fmt_str(e->tocvsFilter, 2); sprintf (args, e->tocvsFilter, fileName, buf); run_setup (args); run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY ); @@ -590,9 +613,8 @@ wrap_fromcvs_process_file(fileName) args = xmalloc (strlen (e->fromcvsFilter) + strlen (fileName)); - /* FIXME: sprintf will blow up if the format string contains items other - than %s, or contains too many %s's. We should instead be parsing - e->fromcvsFilter ourselves and giving a real error. */ + + wrap_clean_fmt_str(e->fromcvsFilter, 1); sprintf (args, e->fromcvsFilter, fileName); run_setup (args); run_exec(RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL ); |