diff options
author | nate <nate@FreeBSD.org> | 1995-03-31 07:55:30 +0000 |
---|---|---|
committer | nate <nate@FreeBSD.org> | 1995-03-31 07:55:30 +0000 |
commit | d7c52c9238e9e6d5ef6270d6e83eee5f90073e2e (patch) | |
tree | b9b2f6a73f2de5b261625892fa9fa9e3d912ebde /gnu/usr.bin | |
parent | be14a246dbdfdafe4e22e067d862ed30754d5139 (diff) | |
download | FreeBSD-src-d7c52c9238e9e6d5ef6270d6e83eee5f90073e2e.zip FreeBSD-src-d7c52c9238e9e6d5ef6270d6e83eee5f90073e2e.tar.gz |
Merged in FreeBSD necessary changes in. Note, all of our source
modifications were *not* merged in (FreeBSD-DEVELOPER and symlink) but
the source is now the stock sources.
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r-- | gnu/usr.bin/cvs/Makefile | 4 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/Makefile | 37 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/checkin.c | 39 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/checkout.c | 91 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/cvs.h | 401 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/diff.c | 147 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/ignore.c | 51 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/import.c | 261 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/main.c | 163 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/patch.c | 83 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/release.c | 27 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvs/update.c | 567 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/cvsinit/cvsinit.sh | 26 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/doc/Makefile | 3 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/Makefile | 13 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/lib/getopt.c | 535 | ||||
-rw-r--r-- | gnu/usr.bin/cvs/mkmodules/Makefile | 5 |
17 files changed, 1513 insertions, 940 deletions
diff --git a/gnu/usr.bin/cvs/Makefile b/gnu/usr.bin/cvs/Makefile index c1a99ab..842c7e9 100644 --- a/gnu/usr.bin/cvs/Makefile +++ b/gnu/usr.bin/cvs/Makefile @@ -1,3 +1,5 @@ -SUBDIR = lib cvs mkmodules cvsinit +# $Id: Makefile,v 1.25 1995/03/22 19:39:45 nate Exp $ + +SUBDIR = lib cvs mkmodules cvsinit doc .include <bsd.subdir.mk> diff --git a/gnu/usr.bin/cvs/cvs/Makefile b/gnu/usr.bin/cvs/cvs/Makefile index 115e246..02efe02 100644 --- a/gnu/usr.bin/cvs/cvs/Makefile +++ b/gnu/usr.bin/cvs/cvs/Makefile @@ -1,33 +1,18 @@ -.if !defined(FREEBSD_DEVELOPER) -PROG = cvs -.else -PROG = ncvs -.endif - -CFLAGS += -I${.CURDIR}/../lib \ - -DDIRENT -DSTDC_HEADERS -DPOSIX -DBROKEN_SIGISMEMBER \ - -DFTIME_MISSING -DHAVE_TIMEZONE -DUTIME_NULL_MISSING -DPADD+= ${LIBCVS} ${LIBGNUREGEX} -LDADD+= -lcvs -lgnuregex - -.if defined(FREEBSD_DEVELOPER) -CFLAGS+= -DFREEBSD_DEVELOPER -BINGRP= ncvs -#BINMODE=2555 -.endif - -SRCS = add.c admin.c checkin.c checkout.c classify.c commit.c \ -create_adm.c diff.c entries.c find_names.c history.c ignore.c \ -import.c lock.c log.c logmsg.c main.c rcs.c modules.c \ -no_diff.c parseinfo.c patch.c recurse.c release.c remove.c repos.c rtag.c \ -status.c tag.c update.c vers_ts.c version.c +# $Id: Makefile,v 1.25 1995/03/22 19:39:45 nate Exp $ +PROG= cvs MAN1= cvs.1 MAN5= cvs.5 +SRCS = add.c admin.c checkin.c checkout.c classify.c commit.c create_adm.c \ + cvsrc.c diff.c entries.c find_names.c history.c ignore.c import.c \ + lock.c log.c logmsg.c main.c modules.c no_diff.c parseinfo.c patch.c \ + rcs.c recurse.c release.c remove.c repos.c root.c rtag.c status.c \ + tag.c update.c vers_ts.c + +CFLAGS+= -I${.CURDIR}/../lib -DHAVE_CONFIG_H -DHAVE_TIMEZONE -check: - @echo `pwd` ${.CURDIR} +DPADD+= ${LIBCVS} ${LIBGNUREGEX} +LDADD+= -lcvs -lgnuregex .include "../../Makefile.inc" -.include "../Makefile.inc" .include <bsd.prog.mk> diff --git a/gnu/usr.bin/cvs/cvs/checkin.c b/gnu/usr.bin/cvs/cvs/checkin.c index 44b733e..1f7691b 100644 --- a/gnu/usr.bin/cvs/cvs/checkin.c +++ b/gnu/usr.bin/cvs/cvs/checkin.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * Check In * @@ -18,22 +18,25 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)checkin.c 1.40 92/03/31"; +static char rcsid[] = "$CVSid: @(#)checkin.c 1.48 94/10/07 $"; +USE(rcsid) #endif int -Checkin (type, file, repository, rcs, rev, tag, message, entries) +Checkin (type, file, repository, rcs, rev, tag, options, message, entries) int type; char *file; char *repository; char *rcs; char *rev; char *tag; + char *options; char *message; List *entries; { char fname[PATH_MAX]; Vers_TS *vers; + int set_time; (void) printf ("Checking in %s;\n", file); (void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file); @@ -48,7 +51,8 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries) run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI, rev ? "-r" : "", rev ? rev : ""); - run_args ("-m%s", message); + run_args ("-m%s", (*message == '\0' || strcmp(message, "\n") == 0) ? + "*** empty log message ***\n" : message); run_arg (rcs); switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) @@ -64,23 +68,25 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries) * original user file. */ - /* XXX - make sure -k options are used on the co; and tag/date? */ -#ifdef FREEBSD_DEVELOPER - run_setup ("%s%s -q %s%s %s", Rcsbin, RCS_CO, - rev ? "-r" : "", rev ? rev : "", - freebsd ? "-KeAuthor,Date,Header,Id,Locker,Log," - "RCSfile,Revision,Source,State -KiFreeBSD" : ""); -#else - run_setup ("%s%s -q %s%s", Rcsbin, RCS_CO, + if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */ + options[0] = '\0'; + run_setup ("%s%s -q %s %s%s", Rcsbin, RCS_CO, options, rev ? "-r" : "", rev ? rev : ""); -#endif /* FREEBSD_DEVELOPER */ run_arg (rcs); (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL); xchmod (file, 1); if (xcmp (file, fname) == 0) + { rename_file (fname, file); + /* the time was correct, so leave it alone */ + set_time = 0; + } else + { (void) unlink_file (fname); + /* sync up with the time from the RCS file */ + set_time = 1; + } /* * If we want read-only files, muck the permissions here, before @@ -99,11 +105,11 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries) /* re-register with the new data */ vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL, - file, 1, 1, entries, (List *) NULL); + file, 1, set_time, entries, (List *) NULL); if (strcmp (vers->options, "-V4") == 0) vers->options[0] = '\0'; - Register (entries, file, vers->vn_rcs, vers->ts_user, vers->options, - vers->tag, vers->date); + Register (entries, file, vers->vn_rcs, vers->ts_user, + vers->options, vers->tag, vers->date, (char *) 0); history_write (type, (char *) 0, vers->vn_rcs, file, repository); freevers_ts (&vers); break; @@ -138,5 +144,6 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries) run_arg (rcs); (void) run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL); } + return (0); } diff --git a/gnu/usr.bin/cvs/cvs/checkout.c b/gnu/usr.bin/cvs/cvs/checkout.c index e7bc608..a5a79ad 100644 --- a/gnu/usr.bin/cvs/cvs/checkout.c +++ b/gnu/usr.bin/cvs/cvs/checkout.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * Create Version * @@ -36,22 +36,17 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)checkout.c 1.67 92/04/10"; +static char rcsid[] = "$CVSid: @(#)checkout.c 1.78 94/10/07 $"; +USE(rcsid) #endif -#if __STDC__ -static char *findslash (char *start, char *p); -static int build_dirs_and_chdir (char *dir, char *prepath, char *realdir, - int sticky); -static int checkout_proc (int *pargc, char *argv[], char *where, +static char *findslash PROTO((char *start, char *p)); +static int build_dirs_and_chdir PROTO((char *dir, char *prepath, char *realdir, + int sticky)); +static int checkout_proc PROTO((int *pargc, char *argv[], char *where, char *mwhere, char *mfile, int shorten, int local_specified, char *omodule, - char *msg); -#else -static int checkout_proc (); -static char *findslash (); -static int build_dirs_and_chdir (); -#endif /* __STDC__ */ + char *msg)); static char *checkout_usage[] = { @@ -70,7 +65,6 @@ static char *checkout_usage[] = "\t-r rev\tCheck out revision or tag. (implies -P)\n", "\t-D date\tCheck out revisions as of date. (implies -P)\n", "\t-d dir\tCheck out into dir instead of module name.\n", - "\t-K key\tUse RCS key -K option on checkout.\n", "\t-k kopt\tUse RCS kopt -k option on checkout.\n", "\t-j rev\tMerge in changes made between current revision and rev.\n", NULL @@ -85,8 +79,8 @@ static char *export_usage[] = "\t-l\tLocal directory only, not recursive\n", "\t-n\tDo not run module program (if any).\n", "\t-q\tSomewhat quiet.\n", - "\t-r rev\tCheck out revision or tag. (implies -P)\n", - "\t-D date\tCheck out revisions as of date. (implies -P)\n", + "\t-r rev\tCheck out revision or tag.\n", + "\t-D date\tCheck out revisions as of date.\n", "\t-d dir\tCheck out into dir instead of module name.\n", NULL }; @@ -101,14 +95,13 @@ static char *date = NULL; static char *join_rev1 = NULL; static char *join_rev2 = NULL; static char *preload_update_dir = NULL; -static char *K_flag = NULL; int checkout (argc, argv) int argc; char *argv[]; { - register int i; + int i; int c; DBM *db; int cat = 0, err = 0, status = 0; @@ -131,7 +124,7 @@ checkout (argc, argv) } else { - valid_options = "ANnk:d:flRpQqcsr:D:j:PK:"; + valid_options = "ANnk:d:flRpQqcsr:D:j:P"; valid_usage = checkout_usage; } @@ -141,7 +134,7 @@ checkout (argc, argv) ign_setup (); optind = 1; - while ((c = gnu_getopt (argc, argv, valid_options)) != -1) + while ((c = getopt (argc, argv, valid_options)) != -1) { switch (c) { @@ -209,9 +202,6 @@ checkout (argc, argv) else join_rev1 = optarg; break; - case 'K': - K_flag = optarg; - break; case '?': default: usage (valid_usage); @@ -221,12 +211,6 @@ checkout (argc, argv) argc -= optind; argv += optind; -#ifdef FREEBSD_DEVELOPER - if (!K_flag && freebsd) { - /* XXX Note: The leading -K is not needed, it gets added later! */ - K_flag = "eAuthor,Date,Header,Id,Locker,Log,RCSfile,Revision,Source,State -KiFreeBSD"; - } -#endif /* FREEBSD_DEVELOPER */ if (shorten == -1) shorten = 0; @@ -272,9 +256,15 @@ checkout (argc, argv) where = (char *) NULL; if (!isfile (CVSADM) && !isfile (OCVSADM)) { - (void) sprintf (repository, "%s/%s", CVSroot, CVSNULLREPOS); + (void) sprintf (repository, "%s/%s/%s", CVSroot, CVSROOTADM, + CVSNULLREPOS); if (!isfile (repository)) (void) mkdir (repository, 0777); + + /* I'm not sure whether this check is redundant. */ + if (!isdir (repository)) + error (1, 0, "there is no repository %s", repository); + Create_Admin (".", repository, (char *) NULL, (char *) NULL); if (!noexec) { @@ -294,11 +284,11 @@ checkout (argc, argv) * attempt to cd to the indicated place. where then becomes simply the * last component */ - if (where != NULL && index (where, '/') != NULL) + if (where != NULL && strchr (where, '/') != NULL) { char *slash; - slash = rindex (where, '/'); + slash = strrchr (where, '/'); *slash = '\0'; if (chdir (where) < 0) @@ -369,7 +359,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, char file[PATH_MAX]; /* if mfile is really a path, straighten it out first */ - if ((cp = rindex (mfile, '/')) != NULL) + if ((cp = strrchr (mfile, '/')) != NULL) { *cp = 0; (void) strcat (repository, "/"); @@ -397,7 +387,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, { char *slash; - if ((slash = rindex (mfile, '/')) != NULL) + if ((slash = strrchr (mfile, '/')) != NULL) mwhere = slash + 1; else mwhere = mfile; @@ -459,7 +449,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, */ if (shorten && where == NULL) { - if ((cp = rindex (argv[0], '/')) != NULL) + if ((cp = strrchr (argv[0], '/')) != NULL) { (void) strcpy (xwhere, cp + 1); where = xwhere; @@ -509,8 +499,8 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, * elements exist in where. Big Black Magic */ prepath = xstrdup (repository); - cp = rindex (where, '/'); - cp2 = rindex (prepath, '/'); + cp = strrchr (where, '/'); + cp2 = strrchr (prepath, '/'); while (cp != NULL) { cp = findslash (where, cp - 1); @@ -544,13 +534,23 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, if (!noexec && *pargc > 1) { + /* I'm not sure whether this check is redundant. */ + if (!isdir (repository)) + error (1, 0, "there is no repository %s", repository); + Create_Admin (".", repository, (char *) NULL, (char *) NULL); fp = open_file (CVSADM_ENTSTAT, "w+"); if (fclose(fp) == EOF) error(1, errno, "cannot close %s", CVSADM_ENTSTAT); } else + { + /* I'm not sure whether this check is redundant. */ + if (!isdir (repository)) + error (1, 0, "there is no repository %s", repository); + Create_Admin (".", repository, tag, date); + } } else { @@ -608,7 +608,6 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, force_tag_match, 0 /* !local */ , 1 /* update -d */ , aflag, checkout_prune_dirs, pipeout, which, join_rev1, join_rev2, - K_flag, preload_update_dir); free (preload_update_dir); preload_update_dir = oldupdate; @@ -634,8 +633,9 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, if (vers->ts_user == NULL) { (void) sprintf (line, "Initial %s", user); - Register (entries, user, vers->vn_rcs, line, vers->options, - vers->tag, vers->date); + Register (entries, user, vers->vn_rcs ? vers->vn_rcs : "0", + line, vers->options, vers->tag, + vers->date, (char *) 0); } freevers_ts (&vers); } @@ -651,7 +651,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten, err += do_update (*pargc - 1, argv + 1, options, tag, date, force_tag_match, local_specified, 1 /* update -d */, aflag, checkout_prune_dirs, pipeout, which, join_rev1, - join_rev2, K_flag, preload_update_dir); + join_rev2, preload_update_dir); free (preload_update_dir); preload_update_dir = oldupdate; return (err); @@ -662,9 +662,9 @@ findslash (start, p) char *start; char *p; { - while ((int) p >= (int) start && *p != '/') + while (p >= start && *p != '/') p--; - if ((int) p < (int) start) + if (p < start) return (NULL); else return (p); @@ -693,7 +693,7 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky) (void) strcpy (path, dir); (void) strcpy (path2, realdir); for (cp = path, cp2 = path2; - (slash = index (cp, '/')) != NULL && (slash2 = index (cp2, '/')) != NULL; + (slash = strchr (cp, '/')) != NULL && (slash2 = strchr (cp2, '/')) != NULL; cp = slash + 1, cp2 = slash2 + 1) { *slash = '\0'; @@ -708,6 +708,9 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky) strcmp (command_name, "export") != 0) { (void) sprintf (repository, "%s/%s", prepath, path2); + /* I'm not sure whether this check is redundant. */ + if (!isdir (repository)) + error (1, 0, "there is no repository %s", repository); Create_Admin (".", repository, sticky ? (char *) NULL : tag, sticky ? (char *) NULL : date); if (!noexec) diff --git a/gnu/usr.bin/cvs/cvs/cvs.h b/gnu/usr.bin/cvs/cvs/cvs.h index d8296a0..95c6a9b 100644 --- a/gnu/usr.bin/cvs/cvs/cvs.h +++ b/gnu/usr.bin/cvs/cvs/cvs.h @@ -1,50 +1,119 @@ -/* @(#)cvs.h 1.72 92/03/31 */ +/* $CVSid: @(#)cvs.h 1.86 94/10/22 $ */ + +/* + * basic information used in all source files + * + */ + + +#include "config.h" /* this is stuff found via autoconf */ +#include "options.h" /* these are some larger questions which + can't easily be automatically checked + for */ + +/* AIX requires this to be the first thing in the file. */ +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not __GNUC__ */ +#if HAVE_ALLOCA_H +#include <alloca.h> +#else /* not HAVE_ALLOCA_H */ +#ifdef _AIX + #pragma alloca +#else /* not _AIX */ +char *alloca (); +#endif /* not _AIX */ +#endif /* not HAVE_ALLOCA_H */ +#endif /* not __GNUC__ */ + +#if __STDC__ +#define CONST const +#define PTR void * +#else +#define CONST +#define PTR char * +#endif + +/* Add prototype support. */ +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +#if __GNUC__ == 2 +#define USE(var) static char sizeof##var = sizeof(sizeof##var) + sizeof(var); +#else +#define USE(var) +#endif + -#include "system.h" #include <stdio.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +#include <fnmatch.h> /* This is supposed to be available on Posix systems */ + #include <ctype.h> #include <pwd.h> #include <signal.h> + +#ifdef HAVE_ERRNO_H +#include <errno.h> +#else +#ifndef errno +extern int errno; +#endif /* !errno */ +#endif /* HAVE_ERRNO_H */ + +#include "system.h" + #include "hash.h" -#include "rcs.h" -#include "gnuregex.h" -#include "fnmatch.h" -#include "getopt.h" -#include "wait.h" -#include "config.h" + #ifdef MY_NDBM #include "myndbm.h" #else #include <ndbm.h> -#endif /* !MY_NDBM */ +#endif /* MY_NDBM */ + +#include "regex.h" +#include "getopt.h" +#include "wait.h" + +#include "rcs.h" + /* XXX - for now this is static */ -#undef PATH_MAX +#ifndef PATH_MAX #ifdef MAXPATHLEN #define PATH_MAX MAXPATHLEN+2 #else #define PATH_MAX 1024+2 #endif +#endif /* PATH_MAX */ /* just in case this implementation does not define this */ #ifndef L_tmpnam #define L_tmpnam 50 #endif -#if __STDC__ -#define CONST const -#define PTR void * -#else -#define CONST -#define PTR char * -#endif /* * Copyright (c) 1992, Brian Berliner and Jeff Polk * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * Definitions for the CVS Administrative directory and the files it contains. * Here as #define's to make changing the names a simple task. @@ -54,6 +123,7 @@ #define CVSADM_ENTBAK "CVS/Entries.Backup" #define CVSADM_ENTSTAT "CVS/Entries.Static" #define CVSADM_REP "CVS/Repository" +#define CVSADM_ROOT "CVS/Root" #define CVSADM_CIPROG "CVS/Checkin.prog" #define CVSADM_UPROG "CVS/Update.prog" #define CVSADM_TAG "CVS/Tag" @@ -80,6 +150,7 @@ #define CVSROOTADM_EDITINFO "editinfo" #define CVSROOTADM_HISTORY "history" #define CVSROOTADM_IGNORE "cvsignore" +#define CVSROOTADM_CHECKOUTLIST "checkoutlist" #define CVSNULLREPOS "Emptydir" /* an empty directory */ /* support for the modules file (CVSROOTADM_MODULES) */ @@ -98,6 +169,7 @@ #define CVSTFL "#cvs.tfl" #define CVSRFL "#cvs.rfl" #define CVSWFL "#cvs.wfl" +#define CVSRFLPAT "#cvs.rfl.*" /* wildcard expr to match read locks */ #define CVSEXT_OPT ",p" #define CVSEXT_LOG ",t" #define CVSPREFIX ",," @@ -129,7 +201,8 @@ #define RCSBIN_ENV "RCSBIN" /* RCS binary directory */ /* #define RCSBIN_DFLT Set by config.h */ -#define EDITOR_ENV "EDITOR" /* which editor to use */ +#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */ +#define EDITOR2_ENV "EDITOR" /* which editor to use */ /* #define EDITOR_DFLT Set by config.h */ #define CVSROOT_ENV "CVSROOT" /* source directory root */ @@ -154,7 +227,6 @@ #define MAXLINELEN 5000 /* max input line from a file */ #define MAXPROGLEN 30000 /* max program length to system() */ #define MAXLISTLEN 40000 /* For [A-Z]list holders */ -#define MAXMESGLEN 10000 /* max RCS log message size */ #define MAXDATELEN 50 /* max length for a date */ /* The type of request that is being done in do_module() */ @@ -198,12 +270,13 @@ struct vers_ts * empty = no user file * 0 = user file is new * -vers = user file to be removed */ - char *vn_rcs; /* the verion for the rcs file + char *vn_rcs; /* the version for the rcs file * (tag version?) */ char *ts_user; /* the timestamp for the user file */ char *ts_rcs; /* the user timestamp from entries */ char *options; /* opts from Entries file * (keyword expansion) */ + char *ts_conflict; /* Holds time_stamp of conflict */ char *tag; /* tag stored in the Entries file */ char *date; /* date stored in the Entries file */ Entnode *entdata; /* pointer to entries file node */ @@ -249,194 +322,126 @@ typedef enum direnter_type Dtype; extern char *program_name, *command_name; extern char *Rcsbin, *Editor, *CVSroot; +#ifdef CVSADM_ROOT +extern char *CVSADM_Root; +extern int cvsadmin_root; +#endif /* CVSADM_ROOT */ extern char *CurDir; extern int really_quiet, quiet; extern int use_editor; extern int cvswrite; -extern int trace; /* Show all commands */ -extern int noexec; /* Don't modify disk anywhere */ -extern int logoff; /* Don't write history entry */ -#ifdef FREEBSD_DEVELOPER -extern int freebsd; /* Assume option defaults for FreBSD */ -#endif /* FREEBSD_DEVELOPER */ +extern int trace; /* Show all commands */ +extern int noexec; /* Don't modify disk anywhere */ +extern int logoff; /* Don't write history entry */ /* Externs that are included directly in the CVS sources */ -#if __STDC__ -int Reader_Lock (char *xrepository); -DBM *open_module (void); -FILE *Fopen (char *name, char *mode); -FILE *open_file (char *name, char *mode); -List *Find_Dirs (char *repository, int which); -List *ParseEntries (int aflag); -char *Make_Date (char *rawdate); -char *Name_Repository (char *dir, char *update_dir); -char *Short_Repository (char *repository); -char *getcaller (void); -char *time_stamp (char *file); -char *xmalloc (int bytes); -char *xrealloc (char *ptr, int bytes); -char *xstrdup (char *str); -int No_Difference (char *file, Vers_TS * vers, List * entries); -int Parse_Info (char *infofile, char *repository, int (*callproc) (), int all); -int Reader_Lock (char *xrepository); -int SIG_register (int sig, SIGTYPE (*fn) ()); -int Writer_Lock (List * list); -int gethostname (char *name, int namelen); -int ign_name (char *name); -int isdir (char *file); -int isfile (char *file); -int islink (char *file); -int isreadable (char *file); -int iswritable (char *file); -int link_file (char *from, char *to); -int numdots (char *s); -int run_exec (char *stin, char *stout, char *sterr, int flags); -int unlink_file (char *f); -int update (int argc, char *argv[]); -int xcmp (char *file1, char *file2); -int yesno (void); -time_t get_date (char *date, struct timeb *now); -void Create_Admin (char *dir, char *repository, char *tag, char *date); -void Lock_Cleanup (void); -void ParseTag (char **tagp, char **datep); -void Scratch_Entry (List * list, char *fname); -void WriteTag (char *dir, char *tag, char *date); -void cat_module (int status); -void check_entries (char *dir); -void close_module (DBM * db); -void copy_file (char *from, char *to); -void error (int status, int errnum, char *message,...); -void fperror (FILE * fp, int status, int errnum, char *message,...); -void free_names (int *pargc, char *argv[]); -void freevers_ts (Vers_TS ** versp); -void ign_add (char *ign, int hold); -void ign_add_file (char *file, int hold); -void ign_setup (void); -void line2argv (int *pargc, char *argv[], char *line); -void make_directories (char *name); -void make_directory (char *name); -void rename_file (char *from, char *to); -void run_arg (char *s); -void run_args (char *fmt,...); -void run_print (FILE * fp); -void run_setup (char *fmt,...); -void strip_path (char *path); -void update_delproc (Node * p); -void usage (char **cpp); -void xchmod (char *fname, int writable); -int Checkin (int type, char *file, char *repository, char *rcs, char *rev, - char *tag, char *message, List * entries); -Ctype Classify_File (char *file, char *tag, char *date, char *options, +DBM *open_module PROTO((void)); +FILE *Fopen PROTO((char *name, char *mode)); +FILE *open_file PROTO((char *name, char *mode)); +List *Find_Dirs PROTO((char *repository, int which)); +List *ParseEntries PROTO((int aflag)); +char *Make_Date PROTO((char *rawdate)); +char *Name_Repository PROTO((char *dir, char *update_dir)); +#ifdef CVSADM_ROOT +char *Name_Root PROTO((char *dir, char *update_dir)); +void Create_Root PROTO((char *dir, char *rootdir)); +int same_directories PROTO((char *dir1, char *dir2)); +#endif /* CVSADM_ROOT */ +char *Short_Repository PROTO((char *repository)); +char *gca PROTO((char *rev1, char *rev2)); +char *getcaller PROTO((void)); +char *time_stamp PROTO((char *file)); +char *xmalloc PROTO((size_t bytes)); +char *xrealloc PROTO((char *ptr, size_t bytes)); +char *xstrdup PROTO((char *str)); +int No_Difference PROTO((char *file, Vers_TS * vers, List * entries, + char *repository, char *update_dir)); +int Parse_Info PROTO((char *infofile, char *repository, int PROTO((*callproc)) PROTO(()), int all)); +int Reader_Lock PROTO((char *xrepository)); +int SIG_register PROTO((int sig, RETSIGTYPE PROTO((*fn)) PROTO(()))); +int Writer_Lock PROTO((List * list)); +int ign_name PROTO((char *name)); +int isdir PROTO((char *file)); +int isfile PROTO((char *file)); +int islink PROTO((char *file)); +int isreadable PROTO((char *file)); +int iswritable PROTO((char *file)); +int joining PROTO((void)); +int link_file PROTO((char *from, char *to)); +int numdots PROTO((char *s)); +int run_exec PROTO((char *stin, char *stout, char *sterr, int flags)); +int unlink_file PROTO((char *f)); +int update PROTO((int argc, char *argv[])); +int xcmp PROTO((char *file1, char *file2)); +int yesno PROTO((void)); +time_t get_date PROTO((char *date, struct timeb *now)); +void Create_Admin PROTO((char *dir, char *repository, char *tag, char *date)); +void Lock_Cleanup PROTO((void)); +void ParseTag PROTO((char **tagp, char **datep)); +void Scratch_Entry PROTO((List * list, char *fname)); +void WriteTag PROTO((char *dir, char *tag, char *date)); +void cat_module PROTO((int status)); +void check_entries PROTO((char *dir)); +void close_module PROTO((DBM * db)); +void copy_file PROTO((char *from, char *to)); +void error PROTO((int status, int errnum, char *message,...)); +void fperror PROTO((FILE * fp, int status, int errnum, char *message,...)); +void free_names PROTO((int *pargc, char *argv[])); +void freevers_ts PROTO((Vers_TS ** versp)); +void ign_add PROTO((char *ign, int hold)); +void ign_add_file PROTO((char *file, int hold)); +void ign_setup PROTO((void)); +void ign_dir_add PROTO((char *name)); +int ignore_directory PROTO((char *name)); +void line2argv PROTO((int *pargc, char *argv[], char *line)); +void make_directories PROTO((char *name)); +void make_directory PROTO((char *name)); +void rename_file PROTO((char *from, char *to)); +void run_arg PROTO((char *s)); +void run_args PROTO((char *fmt,...)); +void run_print PROTO((FILE * fp)); +void run_setup PROTO((char *fmt,...)); +void strip_path PROTO((char *path)); +void strip_trailing_slashes PROTO((char *path)); +void update_delproc PROTO((Node * p)); +void usage PROTO((char **cpp)); +void xchmod PROTO((char *fname, int writable)); +int Checkin PROTO((int type, char *file, char *repository, char *rcs, char *rev, + char *tag, char *options, char *message, List *entries)); +Ctype Classify_File PROTO((char *file, char *tag, char *date, char *options, int force_tag_match, int aflag, char *repository, - List *entries, List *srcfiles, Vers_TS **versp); -List *Find_Names (char *repository, int which, int aflag, - List ** optentries); -void Register (List * list, char *fname, char *vn, char *ts, - char *options, char *tag, char *date); -void Update_Logfile (char *repository, char *xmessage, char *xrevision, - FILE * xlogfp, List * xchanges); -Vers_TS *Version_TS (char *repository, char *options, char *tag, + List *entries, List *srcfiles, Vers_TS **versp, + char *update_dir, int pipeout)); +List *Find_Names PROTO((char *repository, int which, int aflag, + List ** optentries)); +void Register PROTO((List * list, char *fname, char *vn, char *ts, + char *options, char *tag, char *date, char *ts_conflict)); +void Update_Logfile PROTO((char *repository, char *xmessage, char *xrevision, + FILE * xlogfp, List * xchanges)); +Vers_TS *Version_TS PROTO((char *repository, char *options, char *tag, char *date, char *user, int force_tag_match, - int set_time, List * entries, List * xfiles); -void do_editor (char *dir, char *message, char *repository, - List * changes); -int do_module (DBM * db, char *mname, enum mtype m_type, char *msg, - int (*callback_proc) (), char *where, int shorten, - int local_specified, int run_module_prog, char *extra_arg); -int do_recursion (int (*xfileproc) (), int (*xfilesdoneproc) (), - Dtype (*xdirentproc) (), int (*xdirleaveproc) (), + int set_time, List * entries, List * xfiles)); +void do_editor PROTO((char *dir, char **messagep, + char *repository, List * changes)); +int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg, + int PROTO((*callback_proc)) (), char *where, int shorten, + int local_specified, int run_module_prog, char *extra_arg)); +int do_recursion PROTO((int PROTO((*xfileproc)) (), int PROTO((*xfilesdoneproc)) (), + Dtype PROTO((*xdirentproc)) (), int PROTO((*xdirleaveproc)) (), Dtype xflags, int xwhich, int xaflag, int xreadlock, - int xdosrcs); -int do_update (int argc, char *argv[], char *xoptions, char *xtag, + int xdosrcs)); +int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag, char *xdate, int xforce, int local, int xbuild, int xaflag, int xprune, int xpipeout, int which, - char *xjoin_rev1, char *xjoin_rev2, - char *xK_flag, char *preload_update_dir); -void history_write (int type, char *update_dir, char *revs, char *name, - char *repository); -int start_recursion (int (*fileproc) (), int (*filesdoneproc) (), - Dtype (*direntproc) (), int (*dirleaveproc) (), + char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir)); +void history_write PROTO((int type, char *update_dir, char *revs, char *name, + char *repository)); +int start_recursion PROTO((int PROTO((*fileproc)) (), int PROTO((*filesdoneproc)) (), + Dtype PROTO((*direntproc)) (), int PROTO((*dirleaveproc)) (), int argc, char *argv[], int local, int which, int aflag, int readlock, char *update_preload, - int dosrcs); -void SIG_beginCrSect (); -void SIG_endCrSect (); -#else /* !__STDC__ */ -DBM *open_module (); -FILE *Fopen (); -FILE *open_file (); -List *Find_Dirs (); -List *Find_Names (); -List *ParseEntries (); -Vers_TS *Version_TS (); -char *Make_Date (); -char *Name_Repository (); -char *Short_Repository (); -char *getcaller (); -char *time_stamp (); -char *xmalloc (); -char *xrealloc (); -char *xstrdup (); -int Checkin (); -Ctype Classify_File (); -int No_Difference (); -int Parse_Info (); -int Reader_Lock (); -int SIG_register (); -int Writer_Lock (); -int do_module (); -int do_recursion (); -int do_update (); -int gethostname (); -int ign_name (); -int isdir (); -int isfile (); -int islink (); -int isreadable (); -int iswritable (); -int link_file (); -int numdots (); -int run_exec (); -int start_recursion (); -int unlink_file (); -int update (); -int xcmp (); -int yesno (); -time_t get_date (); -void Create_Admin (); -void Lock_Cleanup (); -void ParseTag (); -void ParseTag (); -void Register (); -void Scratch_Entry (); -void Update_Logfile (); -void WriteTag (); -void cat_module (); -void check_entries (); -void close_module (); -void copy_file (); -void do_editor (); -void error (); -void fperror (); -void free_names (); -void freevers_ts (); -void history_write (); -void ign_add (); -void ign_add_file (); -void ign_setup (); -void line2argv (); -void make_directories (); -void make_directory (); -void rename_file (); -void run_arg (); -void run_args (); -void run_print (); -void run_setup (); -void strip_path (); -void update_delproc (); -void usage (); -void xchmod (); -void SIG_beginCrSect (); -void SIG_endCrSect (); -#endif /* __STDC__ */ + int dosrcs, int wd_is_repos)); +void SIG_beginCrSect PROTO((void)); +void SIG_endCrSect PROTO((void)); +void read_cvsrc PROTO((int *argc, char ***argv)); diff --git a/gnu/usr.bin/cvs/cvs/diff.c b/gnu/usr.bin/cvs/cvs/diff.c index 003c2e3..99d8c18 100644 --- a/gnu/usr.bin/cvs/cvs/diff.c +++ b/gnu/usr.bin/cvs/cvs/diff.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * Difference * @@ -17,26 +17,18 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)diff.c 1.52 92/04/10"; +static char rcsid[] = "$CVSid: @(#)diff.c 1.61 94/10/22 $"; +USE(rcsid) #endif -#if __STDC__ -static Dtype diff_dirproc (char *dir, char *pos_repos, char *update_dir); -static int diff_filesdoneproc (int err, char *repos, char *update_dir); -static int diff_dirleaveproc (char *dir, int err, char *update_dir); -static int diff_file_nodiff (char *file, char *repository, List *entries, - List *srcfiles, Vers_TS *vers); -static int diff_fileproc (char *file, char *update_dir, char *repository, - List * entries, List * srcfiles); -static void diff_mark_errors (int err); -#else -static int diff_fileproc (); -static Dtype diff_dirproc (); -static int diff_filesdoneproc (); -static int diff_dirleaveproc (); -static int diff_file_nodiff (); -static void diff_mark_errors (); -#endif /* __STDC__ */ +static Dtype diff_dirproc PROTO((char *dir, char *pos_repos, char *update_dir)); +static int diff_filesdoneproc PROTO((int err, char *repos, char *update_dir)); +static int diff_dirleaveproc PROTO((char *dir, int err, char *update_dir)); +static int diff_file_nodiff PROTO((char *file, char *repository, List *entries, + List *srcfiles, Vers_TS *vers)); +static int diff_fileproc PROTO((char *file, char *update_dir, char *repository, + List * entries, List * srcfiles)); +static void diff_mark_errors PROTO((int err)); static char *diff_rev1, *diff_rev2; static char *diff_date1, *diff_date2; @@ -44,10 +36,11 @@ static char *use_rev1, *use_rev2; static char *options; static char opts[PATH_MAX]; static int diff_errors; +static int empty_files = 0; static char *diff_usage[] = { - "Usage: %s %s [-l] [rcsdiff-options]\n", + "Usage: %s %s [-lN] [rcsdiff-options]\n", #ifdef CVS_DIFFDATE " [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n", #else @@ -56,6 +49,7 @@ static char *diff_usage[] = "\t-l\tLocal directory only, not recursive\n", "\t-D d1\tDiff revision for date against working file.\n", "\t-D d2\tDiff rev1/date1 against date2.\n", + "\t-N\tinclude diffs for added and removed files.\n", "\t-r rev1\tDiff revision for rev1 against working file.\n", "\t-r rev2\tDiff rev1/date1 against rev2.\n", NULL @@ -69,6 +63,7 @@ diff (argc, argv) char tmp[50]; int c, err = 0; int local = 0; + int which; if (argc == -1) usage (diff_usage); @@ -79,8 +74,8 @@ diff (argc, argv) * non-recursive/recursive diff. */ optind = 1; - while ((c = gnu_getopt (argc, argv, - "abcdefhilnpqtuw0123456789BHQRTC:D:F:I:L:V:k:r:")) != -1) + while ((c = getopt (argc, argv, + "abcdefhilnpqtuw0123456789BHNQRTC:D:F:I:L:V:k:r:")) != -1) { switch (c) { @@ -139,6 +134,9 @@ diff (argc, argv) diff_date1 = Make_Date (optarg); break; #endif + case 'N': + empty_files = 1; + break; case '?': default: usage (diff_usage); @@ -152,10 +150,14 @@ diff (argc, argv) if (!options) options = xstrdup (""); + which = W_LOCAL; + if (diff_rev2 != NULL || diff_date2 != NULL) + which |= W_REPOS | W_ATTIC; + /* start the recursion processor */ err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc, diff_dirleaveproc, argc, argv, local, - W_LOCAL, 0, 1, (char *) NULL, 1); + which, 0, 1, (char *) NULL, 1, 0); /* clean up */ free (options); @@ -176,11 +178,23 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles) { int status, err = 2; /* 2 == trouble, like rcsdiff */ Vers_TS *vers; + enum { + DIFF_ERROR, + DIFF_ADDED, + DIFF_REMOVED, + DIFF_NEITHER + } empty_file = DIFF_NEITHER; + char tmp[L_tmpnam+1]; vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL, file, 1, 0, entries, srcfiles); - if (vers->vn_user == NULL) + if (diff_rev2 != NULL || diff_date2 != NULL) + { + /* Skip all the following checks regarding the user file; we're + not using it. */ + } + else if (vers->vn_user == NULL) { error (0, 0, "I know nothing about %s", file); freevers_ts (&vers); @@ -189,17 +203,27 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles) } else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0') { - error (0, 0, "%s is a new entry, no comparison available", file); - freevers_ts (&vers); - diff_mark_errors (err); - return (err); + if (empty_files) + empty_file = DIFF_ADDED; + else + { + error (0, 0, "%s is a new entry, no comparison available", file); + freevers_ts (&vers); + diff_mark_errors (err); + return (err); + } } else if (vers->vn_user[0] == '-') { - error (0, 0, "%s was removed, no comparison available", file); - freevers_ts (&vers); - diff_mark_errors (err); - return (err); + if (empty_files) + empty_file = DIFF_REMOVED; + else + { + error (0, 0, "%s was removed, no comparison available", file); + freevers_ts (&vers); + diff_mark_errors (err); + return (err); + } } else { @@ -222,7 +246,7 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles) } } - if (diff_file_nodiff (file, repository, entries, srcfiles, vers)) + if (empty_file == DIFF_NEITHER && diff_file_nodiff (file, repository, entries, srcfiles, vers)) { freevers_ts (&vers); return (0); @@ -236,18 +260,51 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles) (void) printf ("Index: %s\n", file); (void) fflush (stdout); - if (use_rev2) + if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED) { - run_setup ("%s%s %s %s -r%s -r%s", Rcsbin, RCS_DIFF, - opts, *options ? options : vers->options, - use_rev1, use_rev2); + (void) printf ("===================================================================\nRCS file: %s\n", + file); + (void) printf ("diff -N %s\n", file); + + if (empty_file == DIFF_ADDED) + { + run_setup ("%s %s %s %s", DIFF, opts, DEVNULL, file); + } + else + { + /* + * FIXME: Should be setting use_rev1 using the logic in + * diff_file_nodiff, and using that revision. This code + * is broken for "cvs diff -N -r foo". + */ + run_setup ("%s%s -p -q %s -r%s", Rcsbin, RCS_CO, + *options ? options : vers->options, vers->vn_rcs); + run_arg (vers->srcfile->path); + if (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY) == -1) + { + (void) unlink (tmp); + error (1, errno, "fork failed during checkout of %s", + vers->srcfile->path); + } + + run_setup ("%s %s %s %s", DIFF, opts, tmp, DEVNULL); + } } else { - run_setup ("%s%s %s %s -r%s", Rcsbin, RCS_DIFF, opts, - *options ? options : vers->options, use_rev1); + if (use_rev2) + { + run_setup ("%s%s %s %s -r%s -r%s", Rcsbin, RCS_DIFF, + opts, *options ? options : vers->options, + use_rev1, use_rev2); + } + else + { + run_setup ("%s%s %s %s -r%s", Rcsbin, RCS_DIFF, opts, + *options ? options : vers->options, use_rev1); + } + run_arg (vers->srcfile->path); } - run_arg (vers->srcfile->path); switch ((status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_REALLY|RUN_COMBINED))) @@ -263,6 +320,9 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles) break; } + if (empty_file == DIFF_REMOVED) + (void) unlink (tmp); + (void) fflush (stdout); freevers_ts (&vers); diff_mark_errors (err); @@ -388,7 +448,12 @@ diff_file_nodiff (file, repository, entries, srcfiles, vers) } /* now, see if we really need to do the diff */ - return (strcmp (use_rev1, use_rev2) == 0); + if (use_rev1 && use_rev2) { + return (strcmp (use_rev1, use_rev2) == 0); + } else { + error(0, 0, "No HEAD revision for file %s", file); + return (1); + } } if (use_rev1 == NULL || strcmp (use_rev1, vers->vn_user) == 0) { diff --git a/gnu/usr.bin/cvs/cvs/ignore.c b/gnu/usr.bin/cvs/cvs/ignore.c index 1b6428f..0005f40 100644 --- a/gnu/usr.bin/cvs/cvs/ignore.c +++ b/gnu/usr.bin/cvs/cvs/ignore.c @@ -1,11 +1,12 @@ /* - * .cvsignore file support contributed by David G. Grubbs <dgg@ksr.com> + * .cvsignore file support contributed by David G. Grubbs <dgg@odi.com> */ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)ignore.c 1.13 92/04/03"; +static char rcsid[] = "$CVSid: @(#)ignore.c 1.16 94/09/24 $"; +USE(rcsid) #endif /* @@ -26,7 +27,7 @@ static int ign_size; /* This many slots available (plus static int ign_hold; /* Index where first "temporary" item * is held */ -char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state .nse_depinfo #* .#* cvslog.* ,* CVS* .del-* *.a *.o *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej *.info *.db"; +char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state .nse_depinfo #* .#* cvslog.* ,* CVS* .del-* *.a *.o *.so *.Z *~ *.old *.elc *.ln *.bak *.BAK *.orig *.rej"; #define IGN_GROW 16 /* grow the list by 16 elements at a * time */ @@ -225,3 +226,47 @@ ign_name (name) return (1); return (0); } + + +static char **dir_ign_list = NULL; +static int dir_ign_max = 0; +static int dir_ign_current = 0; + +/* add a directory to list of dirs to ignore */ +void ign_dir_add (name) + char *name; +{ + /* make sure we've got the space for the entry */ + if (dir_ign_current <= dir_ign_max) + { + dir_ign_max += IGN_GROW; + dir_ign_list = (char **) xrealloc ((char *) dir_ign_list, (dir_ign_max+1) * sizeof(char*)); + } + + dir_ign_list[dir_ign_current] = name; + + dir_ign_current += 1 ; +} + + +/* this function returns 1 (true) if the given directory name is part of + * the list of directories to ignore + */ + +int ignore_directory (name) + char *name; +{ + int i; + + if (!dir_ign_list) + return 0; + + i = dir_ign_current; + while (i--) + { + if (strncmp(name, dir_ign_list[i], strlen(dir_ign_list[i])) == 0) + return 1; + } + + return 0; +} diff --git a/gnu/usr.bin/cvs/cvs/import.c b/gnu/usr.bin/cvs/cvs/import.c index 288b9b2..2d2cdb8 100644 --- a/gnu/usr.bin/cvs/cvs/import.c +++ b/gnu/usr.bin/cvs/cvs/import.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * "import" checks in the vendor release located in the current directory into * the CVS source repository. The CVS vendor branch support is utilized. @@ -19,39 +19,29 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)import.c 1.52 92/03/31"; +static char rcsid[] = "$CVSid: @(#)import.c 1.63 94/09/30 $"; +USE(rcsid) #endif #define FILE_HOLDER ".#cvsxxx" -#if __STDC__ -static char *get_comment (char *user); -static int add_rcs_file (char *message, char *rcs, char *user, char *vtag, - int targc, char *targv[]); -static int expand_at_signs (char *buf, off_t size, FILE *fp); -static int add_rev (char *message, char *rcs, char *vfile, char *vers); -static int add_tags (char *rcs, char *vfile, char *vtag, int targc, - char *targv[]); -static int import_descend (char *message, char *vtag, int targc, char *targv[]); -static int import_descend_dir (char *message, char *dir, char *vtag, - int targc, char *targv[]); -static int process_import_file (char *message, char *vfile, char *vtag, - int targc, char *targv[]); -static int update_rcs_file (char *message, char *vfile, char *vtag, int targc, - char *targv[]); -static void add_log (int ch, char *fname); -#else -static int import_descend (); -static int process_import_file (); -static int update_rcs_file (); -static int add_rev (); -static int add_tags (); -static char *get_comment (); -static int add_rcs_file (); -static int expand_at_signs (); -static void add_log (); -static int import_descend_dir (); -#endif /* __STDC__ */ +static char *get_comment PROTO((char *user)); +static int add_rcs_file PROTO((char *message, char *rcs, char *user, char *vtag, + int targc, char *targv[])); +static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp)); +static int add_rev PROTO((char *message, char *rcs, char *vfile, char *vers)); +static int add_tags PROTO((char *rcs, char *vfile, char *vtag, int targc, + char *targv[])); +static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[])); +static int import_descend_dir PROTO((char *message, char *dir, char *vtag, + int targc, char *targv[])); +static int process_import_file PROTO((char *message, char *vfile, char *vtag, + int targc, char *targv[])); +static int update_rcs_file PROTO((char *message, char *vfile, char *vtag, int targc, + char *targv[], int inattic)); +static void add_log PROTO((int ch, char *fname)); +static int str2expmode PROTO((char const* expstring)); +static int strn2expmode PROTO((char const* expstring, size_t n)); static int repos_len; static char vhead[50]; @@ -59,25 +49,42 @@ static char vbranch[50]; static FILE *logfp; static char repository[PATH_MAX]; static int conflicts; +static int use_file_modtime; +static char *keyword_opt = NULL; static char *import_usage[] = { - "Usage: %s %s [-Qq] [-I ign] [-m msg] [-b branch]\n", + "Usage: %s %s [-Qq] [-d] [-k subst] [-I ign] [-m msg] [-b branch]\n", " repository vendor-tag release-tags...\n", "\t-Q\tReally quiet.\n", "\t-q\tSomewhat quiet.\n", + "\t-d\tUse the file's modification time as the time of import.\n", + "\t-k sub\tSet default RCS keyword substitution mode.\n", "\t-I ign\tMore files to ignore (! to reset).\n", "\t-b bra\tVendor branch id.\n", "\t-m msg\tLog message.\n", NULL }; +static char *keyword_usage[] = +{ + "%s %s: invalid RCS keyword expansion mode\n", + "Valid expansion modes include:\n", + " -kkv\tGenerate keywords using the default form.\n", + " -kkvl\tLike -kkv, except locker's name inserted.\n", + " -kk\tGenerate only keyword names in keyword strings.\n", + " -kv\tGenerate only keyword values in keyword strings.\n", + " -ko\tGenerate the old keyword string (no changes from checked in file).\n", + NULL, +}; + + int import (argc, argv) int argc; char *argv[]; { - char message[MAXMESGLEN]; + char *message = NULL; char tmpfile[L_tmpnam+1]; char *cp; int i, c, msglen, err; @@ -90,9 +97,8 @@ import (argc, argv) ign_setup (); (void) strcpy (vbranch, CVSBRANCH); - message[0] = '\0'; optind = 1; - while ((c = gnu_getopt (argc, argv, "Qqb:m:I:")) != -1) + while ((c = getopt (argc, argv, "Qqdb:m:I:k:")) != -1) { switch (c) { @@ -102,6 +108,9 @@ import (argc, argv) case 'q': quiet = 1; break; + case 'd': + use_file_modtime = 1; + break; case 'b': (void) strcpy (vbranch, optarg); break; @@ -111,18 +120,17 @@ import (argc, argv) #else use_editor = FALSE; #endif - if (strlen (optarg) >= (sizeof (message) - 1)) - { - error (0, 0, "warning: message too long; truncated!"); - (void) strncpy (message, optarg, sizeof (message)); - message[sizeof (message) - 2] = '\0'; - } - else - (void) strcpy (message, optarg); + message = xstrdup(optarg); break; case 'I': ign_add (optarg, 0); break; + case 'k': + if (str2expmode(optarg) != -1) + keyword_opt = optarg; + else + usage (keyword_usage); + break; case '?': default: usage (import_usage); @@ -167,15 +175,25 @@ import (argc, argv) if (numdots (vbranch) != 2) error (1, 0, "Only branches with two dots are supported: %s", vbranch); (void) strcpy (vhead, vbranch); - cp = rindex (vhead, '.'); + cp = strrchr (vhead, '.'); *cp = '\0'; if (use_editor) - do_editor ((char *) NULL, message, repository, (List *) NULL); - msglen = strlen (message); + { + do_editor ((char *) NULL, &message, repository, + (List *) NULL); + } + + msglen = message == NULL ? 0 : strlen (message); if (msglen == 0 || message[msglen - 1] != '\n') { - message[msglen] = '\n'; - message[msglen + 1] = '\0'; + char *nm = xmalloc (msglen + 2); + if (message != NULL) + { + (void) strcpy (nm, message); + free (message); + } + (void) strcat (nm + msglen, "\n"); + message = nm; } /* @@ -235,6 +253,10 @@ import (argc, argv) Update_Logfile (repository, message, vbranch, logfp, ulist); dellist (&ulist); (void) fclose (logfp); + + if (message) + free (message); + return (err); } @@ -249,10 +271,9 @@ import_descend (message, vtag, targc, targv) char *targv[]; { DIR *dirp; - struct direct *dp; + struct dirent *dp; int err = 0; int has_dirs = 0; - FILE *links = (FILE *)0; /* first, load up any per-directory ignore lists */ ign_add_file (CVSDOTIGNORE, 1); @@ -280,38 +301,8 @@ import_descend (message, vtag, targc, targv) { if (islink (dp->d_name)) { -#ifdef DO_LINKS - char lnbuf[PATH_MAX]; - int lln; - - add_log ('L', dp->d_name); - if ((lln = readlink(dp->d_name, lnbuf, PATH_MAX)) == -1) { - error(0, errno, "Can't read contents of symlink %s", - dp->d_name); - return (1); - } - else { - if (!links) { - char lnrep[PATH_MAX]; - - sprintf(lnrep, "%s/SymLinks", repository); - links = fopen(lnrep, "a+"); - if (!links) { - error (0, errno, - "Can't open SymLinks file %s", lnrep); - return (1); - } - } - lnbuf[lln] = '\0'; - fputs(dp->d_name, links); - fputc('\n', links); - fputs(lnbuf, links); - fputc('\n', links); - } -#else add_log ('L', dp->d_name); err++; -#endif } else { @@ -342,8 +333,6 @@ import_descend (message, vtag, targc, targv) (void) closedir (dirp); } } - if (links) - fclose(links); return (err); } @@ -360,6 +349,7 @@ process_import_file (message, vfile, vtag, targc, targv) { char attic_name[PATH_MAX]; char rcs[PATH_MAX]; + int inattic = 0; (void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT); if (!isfile (rcs)) @@ -376,12 +366,13 @@ process_import_file (message, vfile, vtag, targc, targv) add_log ('N', vfile); return (add_rcs_file (message, rcs, vfile, vtag, targc, targv)); } + inattic = 1; } /* * an rcs file exists. have to do things the official, slow, way. */ - return (update_rcs_file (message, vfile, vtag, targc, targv)); + return (update_rcs_file (message, vfile, vtag, targc, targv, inattic)); } /* @@ -389,27 +380,32 @@ process_import_file (message, vfile, vtag, targc, targv) * (possibly already existing) vendor branch. */ static int -update_rcs_file (message, vfile, vtag, targc, targv) +update_rcs_file (message, vfile, vtag, targc, targv, inattic) char *message; char *vfile; char *vtag; int targc; char *targv[]; + int inattic; { Vers_TS *vers; - char letter; + int letter; int ierrno; + char *tmpdir; vers = Version_TS (repository, (char *) NULL, vbranch, (char *) NULL, vfile, 1, 0, (List *) NULL, (List *) NULL); if (vers->vn_rcs != NULL) { - char xtmpfile[50]; + char xtmpfile[PATH_MAX]; int different; int retcode = 0; - /* XXX - should be more unique */ - (void) sprintf (xtmpfile, "/tmp/%s", FILE_HOLDER); + tmpdir = getenv ("TMPDIR"); + if (tmpdir == NULL || tmpdir[0] == '\0') + tmpdir = "/tmp"; + + (void) sprintf (xtmpfile, "%s/cvs-imp%d", tmpdir, getpid()); /* * The rcs file does have a revision on the vendor branch. Compare @@ -459,15 +455,15 @@ update_rcs_file (message, vfile, vtag, targc, targv) } /* We may have failed to parse the RCS file; check just in case */ - if (vers->srcfile == NULL || add_rev (message, vers->srcfile->path, - vfile, vers->vn_rcs) || + if (vers->srcfile == NULL || + add_rev (message, vers->srcfile->path, vfile, vers->vn_rcs) || add_tags (vers->srcfile->path, vfile, vtag, targc, targv)) { freevers_ts (&vers); return (1); } - if (vers->srcfile->branch == NULL || + if (vers->srcfile->branch == NULL || inattic || strcmp (vers->srcfile->branch, vbranch) != 0) { conflicts++; @@ -527,6 +523,8 @@ add_rev (message, rcs, vfile, vers) } run_setup ("%s%s -q -f -r%s", Rcsbin, RCS_CI, vbranch); run_args ("-m%s", message); + if (use_file_modtime) + run_arg ("-d"); run_arg (rcs); status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL); ierrno = errno; @@ -620,8 +618,11 @@ struct compair comtable[] = */ "a", "-- ", /* Ada */ "ada", "-- ", + "adb", "-- ", "asm", ";; ", /* assembler (MS-DOS) */ + "ads", "-- ", /* Ada */ "bat", ":: ", /* batch (MS-DOS) */ + "body", "-- ", /* Ada */ "c", " * ", /* C */ "c++", "// ", /* C++ in all its infinite guises */ "cc", "// ", @@ -633,6 +634,8 @@ struct compair comtable[] = "cs", " * ", /* C* */ "csh", "# ", /* shell */ "e", "# ", /* efl */ + "epsf", "% ", /* encapsulated postscript */ + "epsi", "% ", /* encapsulated postscript */ "el", "; ", /* Emacs Lisp */ "f", "c ", /* Fortran */ "for", "c ", @@ -683,6 +686,7 @@ struct compair comtable[] = #endif "sh", "# ", /* shell */ "sl", "% ", /* psl */ + "spec", "-- ", /* Ada */ "tex", "% ", /* tex */ "y", " * ", /* yacc */ "ye", " * ", /* yacc-efl */ @@ -700,7 +704,7 @@ get_comment (user) char suffix_path[PATH_MAX]; int i; - cp = rindex (user, '.'); + cp = strrchr (user, '.'); if (cp != NULL) { cp++; @@ -739,7 +743,10 @@ add_rcs_file (message, rcs, user, vtag, targc, targv) struct stat sb; struct tm *ftm; time_t now; - char altdate1[50], altdate2[50]; + char altdate1[50]; +#ifndef HAVE_RCS5 + char altdate2[50]; +#endif char *author, *buf; int i, mode, ierrno, err = 0; @@ -767,15 +774,29 @@ add_rcs_file (message, rcs, user, vtag, targc, targv) if (fprintf (fprcs, "%s:%s;\n", vtag, vbranch) == EOF || fprintf (fprcs, "locks ; strict;\n") == EOF || /* XXX - make sure @@ processing works in the RCS file */ - fprintf (fprcs, "comment @%s@;\n\n", get_comment (user)) == EOF) + fprintf (fprcs, "comment @%s@;\n", get_comment (user)) == EOF) { goto write_error; } + if (keyword_opt != NULL) + if (fprintf (fprcs, "expand @%s@;\n", keyword_opt) == EOF) + { + goto write_error; + } + + if (fprintf (fprcs, "\n") == EOF) + goto write_error; + /* * puttree() */ - (void) time (&now); + if (fstat (fileno (fpuser), &sb) < 0) + error (1, errno, "cannot fstat %s", user); + if (use_file_modtime) + now = sb.st_mtime; + else + (void) time (&now); #ifdef HAVE_RCS5 ftm = gmtime (&now); #else @@ -785,16 +806,20 @@ add_rcs_file (message, rcs, user, vtag, targc, targv) ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, ftm->tm_min, ftm->tm_sec); - now++; #ifdef HAVE_RCS5 - ftm = gmtime (&now); +#define altdate2 altdate1 #else + /* + * If you don't have RCS V5 or later, you need to lie about the ci + * time, since RCS V4 and earlier insist that the times differ. + */ + now++; ftm = localtime (&now); -#endif (void) sprintf (altdate2, DATEFORM, ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, ftm->tm_min, ftm->tm_sec); +#endif author = getcaller (); if (fprintf (fprcs, "\n%s\n", vhead) == EOF || @@ -823,8 +848,6 @@ add_rcs_file (message, rcs, user, vtag, targc, targv) goto write_error; } - if (fstat (fileno (fpuser), &sb) < 0) - error (1, errno, "cannot fstat %s", user); if (sb.st_size > 0) { off_t size; @@ -834,7 +857,10 @@ add_rcs_file (message, rcs, user, vtag, targc, targv) if (fread (buf, (int) size, 1, fpuser) != 1) error (1, errno, "cannot read file %s for copying", user); if (expand_at_signs (buf, size, fprcs) == EOF) + { + free (buf); goto write_error; + } free (buf); } if (fprintf (fprcs, "@\n\n") == EOF || @@ -911,7 +937,7 @@ expand_at_signs (buf, size, fp) */ static void add_log (ch, fname) - char ch; + int ch; char *fname; { if (!really_quiet) /* write to terminal */ @@ -1001,7 +1027,7 @@ import_descend_dir (message, dir, vtag, targc, targv) } err = import_descend (message, vtag, targc, targv); out: - if ((cp = rindex (repository, '/')) != NULL) + if ((cp = strrchr (repository, '/')) != NULL) *cp = '\0'; else repository[0] = '\0'; @@ -1009,3 +1035,36 @@ import_descend_dir (message, dir, vtag, targc, targv) error (1, errno, "cannot chdir to %s", cwd); return (err); } + +/* the following code is taken from code in rcs/src/rcssyn.c, and returns a + * positive value if 'expstring' contains a valid RCS expansion token for + * the -k option. If an invalid expansion is named, then return -1. + */ + +char const *const expand_names[] = { + /* These must agree with *_EXPAND in rcs/src/rcsbase.h. */ + "kv","kvl","k","v","o", + 0 +}; + +static int +str2expmode(s) + char const *s; +/* Yield expand mode corresponding to S, or -1 if bad. */ +{ + return strn2expmode(s, strlen(s)); +} + +static int +strn2expmode(s, n) + char const *s; + size_t n; +{ + char const *const *p; + + for (p = expand_names; *p; ++p) + if (memcmp(*p,s,n) == 0 && !(*p)[n]) + return p - expand_names; + return -1; +} + diff --git a/gnu/usr.bin/cvs/cvs/main.c b/gnu/usr.bin/cvs/cvs/main.c index d6ad258..3751b3c 100644 --- a/gnu/usr.bin/cvs/cvs/main.c +++ b/gnu/usr.bin/cvs/cvs/main.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License - * as specified in the README file that comes with the CVS 1.3 kit. + * as specified in the README file that comes with the CVS 1.4 kit. * * This is the main C driver for the CVS system. * @@ -35,7 +35,10 @@ #include "cvs.h" #include "patchlevel.h" -char rcsid[] = "@(#)main.c 1.64 92/03/31\n"; +#ifndef lint +char rcsid[] = "$CVSid: @(#)main.c 1.78 94/10/07 $\n"; +USE(rcsid) +#endif extern char *getenv (); @@ -43,6 +46,7 @@ char *program_name; char *command_name = ""; int use_editor = TRUE; +int use_cvsrc = TRUE; int cvswrite = !CVSREAD_DFLT; int really_quiet = FALSE; int quiet = FALSE; @@ -58,44 +62,28 @@ char *CurDir; char *Rcsbin = RCSBIN_DFLT; char *Editor = EDITOR_DFLT; char *CVSroot = CVSROOT_DFLT; - -#if __STDC__ -int add (int argc, char **argv); -int admin (int argc, char **argv); -int checkout (int argc, char **argv); -int commit (int argc, char **argv); -int diff (int argc, char **argv); -int history (int argc, char **argv); -int import (int argc, char **argv); -int cvslog (int argc, char **argv); -int patch (int argc, char **argv); -int release (int argc, char **argv); -int cvsremove (int argc, char **argv); -int rtag (int argc, char **argv); -int status (int argc, char **argv); -int tag (int argc, char **argv); -int update (int argc, char **argv); -#else -int add (); -int admin (); -int checkout (); -int commit (); -int diff (); -int history (); -int import (); -int cvslog (); -int patch (); -int release (); -int cvsremove (); -int rtag (); -int status (); -int tag (); -int update (); -#endif /* __STDC__ */ - -#ifdef FREEBSD_DEVELOPER -int freebsd = TRUE; /* Use the FreeBSD -K flags!! */ -#endif +#ifdef CVSADM_ROOT +/* + * The path found in CVS/Root must match $CVSROOT and/or 'cvs -d root' + */ +char *CVSADM_Root = CVSROOT_DFLT; +#endif /* CVSADM_ROOT */ + +int add PROTO((int argc, char **argv)); +int admin PROTO((int argc, char **argv)); +int checkout PROTO((int argc, char **argv)); +int commit PROTO((int argc, char **argv)); +int diff PROTO((int argc, char **argv)); +int history PROTO((int argc, char **argv)); +int import PROTO((int argc, char **argv)); +int cvslog PROTO((int argc, char **argv)); +int patch PROTO((int argc, char **argv)); +int release PROTO((int argc, char **argv)); +int cvsremove PROTO((int argc, char **argv)); +int rtag PROTO((int argc, char **argv)); +int status PROTO((int argc, char **argv)); +int tag PROTO((int argc, char **argv)); +int update PROTO((int argc, char **argv)); struct cmd { @@ -141,9 +129,7 @@ static char *usg[] = " -b bindir Find RCS programs in 'bindir'\n", " -e editor Use 'editor' for editing log information\n", " -d CVS_root Overrides $CVSROOT as the root of the CVS tree\n", -#ifdef FREEBSD_DEVELOPER - " -x Do NOT use the FreeBSD -K default flags\n", -#endif + " -f Do not use the ~/.cvsrc file\n", "\n", " and where 'command' is:\n", " add Adds a new file/directory to the repository\n", @@ -165,7 +151,7 @@ static char *usg[] = NULL, }; -static SIGTYPE +static RETSIGTYPE main_cleanup () { exit (1); @@ -180,13 +166,13 @@ main (argc, argv) char *cp; struct cmd *cm; int c, help = FALSE, err = 0; - int rcsbin_update_env, cvs_update_env; + int rcsbin_update_env, cvs_update_env = 0; char tmp[PATH_MAX]; /* * Just save the last component of the path for error messages */ - if ((program_name = rindex (argv[0], '/')) == NULL) + if ((program_name = strrchr (argv[0], '/')) == NULL) program_name = argv[0]; else program_name++; @@ -200,12 +186,15 @@ main (argc, argv) * they can be overridden by command line arguments */ rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */ + cvs_update_env = 0; if ((cp = getenv (RCSBIN_ENV)) != NULL) { Rcsbin = cp; rcsbin_update_env = 0; /* it's already there */ } - if ((cp = getenv (EDITOR_ENV)) != NULL) + if ((cp = getenv (EDITOR1_ENV)) != NULL) + Editor = cp; + else if ((cp = getenv (EDITOR2_ENV)) != NULL) Editor = cp; if ((cp = getenv (CVSROOT_ENV)) != NULL) { @@ -216,11 +205,7 @@ main (argc, argv) cvswrite = FALSE; optind = 1; -#ifdef FREEBSD_DEVELOPER - while ((c = gnu_getopt (argc, argv, "Qqrwtnlvb:e:d:Hx")) != -1) -#else - while ((c = gnu_getopt (argc, argv, "Qqrwtnlvb:e:d:H")) != -1) -#endif /* FREEBSD_DEVELOPER */ + while ((c = getopt (argc, argv, "Qqrwtnlvb:e:d:Hf")) != -1) { switch (c) { @@ -245,11 +230,10 @@ main (argc, argv) logoff = TRUE; break; case 'v': - (void) fputs (rcsid, stdout); (void) fputs (version_string, stdout); (void) sprintf (tmp, "Patch Level: %d\n", PATCHLEVEL); (void) fputs (tmp, stdout); - (void) fputs ("\nCopyright (c) 1992, Brian Berliner and Jeff Polk\nCopyright (c) 1989-1992, Brian Berliner\n\nCVS may be copied only under the terms of the GNU General Public License,\na copy of which can be found with the CVS 1.3 distribution kit.\n", stdout); + (void) fputs ("\nCopyright (c) 1993-1994 Brian Berliner\nCopyright (c) 1993-1994 david d `zoo' zuhn\nCopyright (c) 1992, Brian Berliner and Jeff Polk\nCopyright (c) 1989-1992, Brian Berliner\n\nCVS may be copied only under the terms of the GNU General Public License,\na copy of which can be found with the CVS distribution kit.\n", stdout); exit (0); break; case 'b': @@ -264,13 +248,12 @@ main (argc, argv) cvs_update_env = 1; /* need to update environment */ break; case 'H': + use_cvsrc = FALSE; /* this ensure that cvs -H works */ help = TRUE; break; -#ifdef FREEBSD_DEVELOPER - case 'x': - freebsd = FALSE; + case 'f': + use_cvsrc = FALSE; break; -#endif /* FREEBSD_DEVELOPER */ case '?': default: usage (usg); @@ -281,25 +264,49 @@ main (argc, argv) if (argc < 1) usage (usg); +#ifdef CVSADM_ROOT /* - * XXX - Compatibility. This can be removed in the release after CVS 1.3. - * Try to rename the CVSROOT.adm file to CVSROOT, unless there already is - * a CVSROOT directory. + * See if we are able to find a 'better' value for CVSroot in the + * CVSADM_ROOT directory. */ - if (CVSroot != NULL) + CVSADM_Root = Name_Root((char *) NULL, (char *) NULL); + if (CVSADM_Root != NULL) { - char rootadm[PATH_MAX]; - char orootadm[PATH_MAX]; - - (void) sprintf (rootadm, "%s/%s", CVSroot, CVSROOTADM); - if (!isdir (rootadm)) - { - (void) sprintf (orootadm, "%s/%s", CVSroot, OCVSROOTADM); - if (isdir (orootadm)) - (void) rename (orootadm, rootadm); - } - strip_path (CVSroot); + if (CVSroot == NULL) + { + CVSroot = CVSADM_Root; + cvs_update_env = 1; /* need to update environment */ + } + else + { + /* + * Now for the hard part, compare the two directories. If they + * are not identical, then abort this command. + */ + if ((strcmp (CVSroot, CVSADM_Root) != 0) && + !same_directories(CVSroot, CVSADM_Root)) + { + error (0, 0, "%s value for CVS Root found in %s", + CVSADM_Root, CVSADM_ROOT); + if (cvs_update_env) + { + error (0, 0, "does not match command line -d %s setting", + CVSroot); + error (1, 0, + "you may wish to try the cvs command again without the -d option "); + } + else + { + error (0, 0, + "does not match CVSROOT environment value of %s", + CVSroot); + error (1, 0, + "you may wish to unsetenv CVSROOT and try again"); + } + } + } } +#endif /* CVSADM_ROOT */ /* * Specifying just the '-H' flag to the sub-command causes a Usage @@ -332,7 +339,7 @@ main (argc, argv) } (void) strcat (path, "/"); (void) strcat (path, CVSROOTADM_HISTORY); - if (isfile (path) && access (path, R_OK | (logoff ? 0 : W_OK))) + if (isfile (path) && access (path, R_OK | W_OK)) { save_errno = errno; error (0, 0, @@ -342,7 +349,7 @@ main (argc, argv) } } -#ifndef PUTENV_MISSING +#ifdef HAVE_PUTENV /* Now, see if we should update the environment with the Rcsbin value */ if (cvs_update_env) { @@ -403,7 +410,7 @@ main (argc, argv) (void) SIG_register (SIGPIPE, main_cleanup); (void) SIG_register (SIGTERM, main_cleanup); -#ifndef SETVBUF_MISSING +#ifdef HAVE_SETVBUF /* * Make stdout line buffered, so 'tail -f' can monitor progress. * Patch creates too much output to monitor and it runs slowly. @@ -412,7 +419,11 @@ main (argc, argv) (void) setvbuf (stdout, (char *) NULL, _IOLBF, 0); #endif + if (use_cvsrc) + read_cvsrc(&argc, &argv); + err = (*(cm->func)) (argc, argv); + } /* * If the command's error count is modulo 256, we need to change it diff --git a/gnu/usr.bin/cvs/cvs/patch.c b/gnu/usr.bin/cvs/cvs/patch.c index abc02fd..69e5b09 100644 --- a/gnu/usr.bin/cvs/cvs/patch.c +++ b/gnu/usr.bin/cvs/cvs/patch.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * Patch * @@ -15,24 +15,17 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)patch.c 1.50 92/04/10"; - +static char rcsid[] = "$CVSid: @(#)patch.c 1.57 94/09/30 $"; +USE(rcsid) #endif -#if __STDC__ -static SIGTYPE patch_cleanup (void); -static Dtype patch_dirproc (char *dir, char *repos, char *update_dir); -static int patch_fileproc (char *file, char *update_dir, char *repository, - List * entries, List * srcfiles); -static int patch_proc (int *pargc, char *argv[], char *xwhere, +static RETSIGTYPE patch_cleanup PROTO((void)); +static Dtype patch_dirproc PROTO((char *dir, char *repos, char *update_dir)); +static int patch_fileproc PROTO((char *file, char *update_dir, char *repository, + List * entries, List * srcfiles)); +static int patch_proc PROTO((int *pargc, char *argv[], char *xwhere, char *mwhere, char *mfile, int shorten, - int local_specified, char *mname, char *msg); -#else -static int patch_proc (); -static int patch_fileproc (); -static Dtype patch_dirproc (); -static SIGTYPE patch_cleanup (); -#endif /* __STDC__ */ + int local_specified, char *mname, char *msg)); static int force_tag_match = 1; static int patch_short = 0; @@ -43,8 +36,6 @@ static char *rev1 = NULL; static char *rev2 = NULL; static char *date1 = NULL; static char *date2 = NULL; -static char *K_flag1 = NULL; -static char *K_flag2 = NULL; static char tmpfile1[L_tmpnam+1], tmpfile2[L_tmpnam+1], tmpfile3[L_tmpnam+1]; static int unidiff = 0; @@ -62,7 +53,6 @@ static char *patch_usage[] = "\t-D date\tDate.\n", "\t-r rev\tRevision - symbolic or numeric.\n", "\t-V vers\tUse RCS Version \"vers\" for keyword expansion.\n", - "\t-K key\tUse RCS key -K option on checkout.\n", NULL }; @@ -80,7 +70,7 @@ patch (argc, argv) usage (patch_usage); optind = 1; - while ((c = gnu_getopt (argc, argv, "V:k:cuftsQqlRD:r:K:")) != -1) + while ((c = getopt (argc, argv, "V:k:cuftsQqlRD:r:")) != -1) { switch (c) { @@ -142,14 +132,6 @@ patch (argc, argv) case 'c': /* Context diff */ unidiff = 0; break; - case 'K': - if (K_flag2 != NULL) - error (1, 0, "no more than two -K flags can be specified"); - if (K_flag1 != NULL) - K_flag2 = optarg; - else - K_flag1 = optarg; - break; case '?': default: usage (patch_usage); @@ -160,11 +142,6 @@ patch (argc, argv) argv += optind; /* Sanity checks */ - /* Check for dummy -K flags */ - if (K_flag1 && K_flag1[0] != 'e' && K_flag1[0] != 'i') - error (1, 0, "-K flag does not start e or i"); - if (K_flag2 && K_flag2[0] != 'e' && K_flag2[0] != 'i') - error (1, 0, "-K flag does not start e or i"); if (argc < 1) usage (patch_usage); @@ -234,7 +211,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified, char path[PATH_MAX]; /* if the portion of the module is a path, put the dir part on repos */ - if ((cp = rindex (mfile, '/')) != NULL) + if ((cp = strrchr (mfile, '/')) != NULL) { *cp = '\0'; (void) strcat (repository, "/"); @@ -280,7 +257,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified, /* start the recursion processor */ err = start_recursion (patch_fileproc, (int (*) ()) NULL, patch_dirproc, (int (*) ()) NULL, *pargc - 1, argv + 1, local, - which, 0, 1, where, 1); + which, 0, 1, where, 1, 1); return (err); } @@ -298,6 +275,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) List *entries; List *srcfiles; { + struct utimbuf t; char *vers_tag, *vers_head; char rcsspace[PATH_MAX]; char *rcs = rcsspace; @@ -312,7 +290,6 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) char *cp1, *cp2, *commap; FILE *fp; - /* find the parsed rcs file */ p = findnode (srcfiles, file); if (p == NULL) @@ -380,8 +357,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) } if (vers_tag != NULL) { - run_setup ("%s%s %s -p -q -r%s %s%s", Rcsbin, RCS_CO, options, - vers_tag, K_flag1 ? "-K" : "", K_flag1 ? K_flag1 : ""); + run_setup ("%s%s %s -p -q -r%s", Rcsbin, RCS_CO, options, vers_tag); run_arg (rcsfile->path); if ((retcode = run_exec (RUN_TTY, tmpfile1, RUN_TTY, RUN_NORMAL)) != 0) { @@ -391,6 +367,10 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) ret = 1; goto out; } + memset ((char *) &t, 0, sizeof (t)); + if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_tag, + (char *) 0, 0)) != -1) + (void) utime (tmpfile1, &t); } else if (toptwo_diffs) { @@ -399,8 +379,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) } if (vers_head != NULL) { - run_setup ("%s%s %s -p -q -r%s %s%s", Rcsbin, RCS_CO, options, - vers_head, K_flag2 ? "-K" : "", K_flag2 ? K_flag2 : ""); + run_setup ("%s%s %s -p -q -r%s", Rcsbin, RCS_CO, options, vers_head); run_arg (rcsfile->path); if ((retcode = run_exec (RUN_TTY, tmpfile2, RUN_TTY, RUN_NORMAL)) != 0) { @@ -410,6 +389,9 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) ret = 1; goto out; } + if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head, + (char *) 0, 0)) != -1) + (void) utime (tmpfile2, &t); } run_setup ("%s -%c", DIFF, unidiff ? 'u' : 'c'); run_arg (tmpfile1); @@ -427,6 +409,15 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) * lines of the diff output file, and munge them to include more * reasonable file names that "patch" will understand. */ + + /* Output an "Index:" line for patch to use */ + (void) fflush (stdout); + if (update_dir[0]) + (void) printf ("Index: %s/%s\n", update_dir, file); + else + (void) printf ("Index: %s\n", file); + (void) fflush (stdout); + fp = open_file (tmpfile3, "r"); if (fgets (line1, sizeof (line1), fp) == NULL || fgets (line2, sizeof (line2), fp) == NULL) @@ -441,8 +432,8 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) { if (strncmp (line1, "*** ", 4) != 0 || strncmp (line2, "--- ", 4) != 0 || - (cp1 = index (line1, '\t')) == NULL || - (cp2 = index (line2, '\t')) == NULL) + (cp1 = strchr (line1, '\t')) == NULL || + (cp2 = strchr (line2, '\t')) == NULL) { error (0, 0, "invalid diff header for %s", rcs); ret = 1; @@ -454,8 +445,8 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) { if (strncmp (line1, "--- ", 4) != 0 || strncmp (line2, "+++ ", 4) != 0 || - (cp1 = index (line1, '\t')) == NULL || - (cp2 = index (line2, '\t')) == NULL) + (cp1 = strchr (line1, '\t')) == NULL || + (cp2 = strchr (line2, '\t')) == NULL) { error (0, 0, "invalid unidiff header for %s", rcs); ret = 1; @@ -469,7 +460,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles) (void) strcpy (strippath, REPOS_STRIP); if (strncmp (rcs, strippath, strlen (strippath)) == 0) rcs += strlen (strippath); - commap = rindex (rcs, ','); + commap = strrchr (rcs, ','); *commap = '\0'; if (vers_tag != NULL) { @@ -529,7 +520,7 @@ patch_dirproc (dir, repos, update_dir) /* * Clean up temporary files */ -static SIGTYPE +static RETSIGTYPE patch_cleanup () { if (tmpfile1[0] != '\0') diff --git a/gnu/usr.bin/cvs/cvs/release.c b/gnu/usr.bin/cvs/cvs/release.c index e2a941a..a6200d9 100644 --- a/gnu/usr.bin/cvs/cvs/release.c +++ b/gnu/usr.bin/cvs/cvs/release.c @@ -12,14 +12,11 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)release.c 1.21 92/02/29"; +static char rcsid[] = "$CVSid: @(#)release.c 1.23 94/09/21 $"; +USE(rcsid) #endif -#if __STDC__ -static void release_delete (char *dir); -#else -static void release_delete (); -#endif /* __STDC__ */ +static void release_delete PROTO((char *dir)); static char *release_usage[] = { @@ -49,7 +46,7 @@ release (argc, argv) if (argc == -1) usage (release_usage); optind = 1; - while ((c = gnu_getopt (argc, argv, "Qdq")) != -1) + while ((c = getopt (argc, argv, "Qdq")) != -1) { switch (c) { @@ -116,7 +113,7 @@ release (argc, argv) continue; } val.dptr[val.dsize] = '\0'; - if ((cp = index (val.dptr, '#')) != NULL) /* Strip out a comment */ + if ((cp = strchr (val.dptr, '#')) != NULL) /* Strip out a comment */ { do { @@ -128,7 +125,7 @@ release (argc, argv) margv = modargv; optind = 1; - while (gnu_getopt (margc, margv, CVSMODULE_OPTS) != -1) + while (getopt (margc, margv, CVSMODULE_OPTS) != -1) /* do nothing */ ; margc -= optind; margv += optind; @@ -155,15 +152,11 @@ release (argc, argv) * is "popen()" instead of "Popen()" since we don't want "-n" to * stop it. */ -#ifdef FREEBSD_DEVELOPER - fp = popen ("ncvs -n -q update", "r"); -#else fp = popen ("cvs -n -q update", "r"); -#endif /* FREEBSD_DEVELOPER */ c = 0; while (fgets (line, sizeof (line), fp)) { - if (index ("MARCZ", *line)) + if (strchr ("MARCZ", *line)) c++; (void) printf (line); } @@ -215,7 +208,11 @@ release_delete (dir) "Parent dir on a different disk, delete of %s aborted", dir); return; } - run_setup ("%s -r", RM); + /* + * XXX - shouldn't this just delete the CVS-controlled files and, perhaps, + * the files that would normally be ignored and leave everything else? + */ + run_setup ("%s -fr", RM); run_arg (dir); if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0) error (0, retcode == -1 ? errno : 0, diff --git a/gnu/usr.bin/cvs/cvs/update.c b/gnu/usr.bin/cvs/cvs/update.c index d91ffdd..9fdc0b4 100644 --- a/gnu/usr.bin/cvs/cvs/update.c +++ b/gnu/usr.bin/cvs/cvs/update.c @@ -3,7 +3,7 @@ * Copyright (c) 1989-1992, Brian Berliner * * You may distribute under the terms of the GNU General Public License as - * specified in the README file that comes with the CVS 1.3 kit. + * specified in the README file that comes with the CVS 1.4 kit. * * "update" updates the version in the present directory with respect to the RCS * repository. The present version must have been created by "checkout". The @@ -36,53 +36,39 @@ #include "cvs.h" #ifndef lint -static char rcsid[] = "@(#)update.c 1.83 92/04/10"; +static char rcsid[] = "$CVSid: @(#)update.c 1.95 94/10/22 $"; +USE(rcsid) #endif -#if __STDC__ -static int checkout_file (char *file, char *repository, List *entries, - List *srcfiles, Vers_TS *vers_ts, char *update_dir); -static int isemptydir (char *dir); -static int merge_file (char *file, char *repository, List *entries, - Vers_TS *vers, char *update_dir); -static int scratch_file (char *file, char *repository, List * entries, - char *update_dir); -static Dtype update_dirent_proc (char *dir, char *repository, char *update_dir); -static int update_dirleave_proc (char *dir, int err, char *update_dir); -static int update_file_proc (char *file, char *update_dir, char *repository, - List * entries, List * srcfiles); -static int update_filesdone_proc (int err, char *repository, char *update_dir); -static int write_letter (char *file, int letter, char *update_dir); -static void ignore_files (List * ilist, char *update_dir); -static void join_file (char *file, List *srcfiles, Vers_TS *vers_ts, - char *update_dir); -#else -static int update_file_proc (); -static int update_filesdone_proc (); -static Dtype update_dirent_proc (); -static int update_dirleave_proc (); -static int isemptydir (); -static int scratch_file (); -static int checkout_file (); -static int write_letter (); -static int merge_file (); -static void ignore_files (); -static void join_file (); -#endif /* __STDC__ */ +static int checkout_file PROTO((char *file, char *repository, List *entries, + List *srcfiles, Vers_TS *vers_ts, char *update_dir)); +static int isemptydir PROTO((char *dir)); +static int merge_file PROTO((char *file, char *repository, List *entries, + Vers_TS *vers, char *update_dir)); +static int scratch_file PROTO((char *file, char *repository, List * entries, + char *update_dir)); +static Dtype update_dirent_proc PROTO((char *dir, char *repository, char *update_dir)); +static int update_dirleave_proc PROTO((char *dir, int err, char *update_dir)); +static int update_file_proc PROTO((char *file, char *update_dir, char *repository, + List * entries, List * srcfiles)); +static int update_filesdone_proc PROTO((int err, char *repository, char *update_dir)); +static int write_letter PROTO((char *file, int letter, char *update_dir)); +static void ignore_files PROTO((List * ilist, char *update_dir)); +static void join_file PROTO((char *file, List *srcfiles, Vers_TS *vers_ts, + char *update_dir, List *entries)); static char *options = NULL; static char *tag = NULL; static char *date = NULL; static char *join_rev1, *date_rev1; static char *join_rev2, *date_rev2; -static char *K_flag; static int aflag = 0; static int force_tag_match = 1; static int update_build_dirs = 0; static int update_prune_dirs = 0; static int pipeout = 0; static List *ignlist = (List *) NULL; - +static time_t last_register_time; static char *update_usage[] = { "Usage:\n %s %s [-APQdflRpq] [-k kopt] [-r rev|-D date] [-j rev] [-I ign] [files...]\n", @@ -100,7 +86,6 @@ static char *update_usage[] = "\t-D date\tSet date to update from.\n", "\t-j rev\tMerge in changes made between current revision and rev.\n", "\t-I ign\tMore files to ignore (! to reset).\n", - "\t-K key\tUse RCS key -K option on checkout.\n", NULL }; @@ -123,7 +108,7 @@ update (argc, argv) /* parse the args */ optind = 1; - while ((c = gnu_getopt (argc, argv, "ApPflRQqdk:r:D:j:I:K:")) != -1) + while ((c = getopt (argc, argv, "ApPflRQqdk:r:D:j:I:")) != -1) { switch (c) { @@ -177,9 +162,6 @@ update (argc, argv) else join_rev1 = optarg; break; - case 'K': - K_flag = optarg; - break; case '?': default: usage (update_usage); @@ -189,13 +171,6 @@ update (argc, argv) argc -= optind; argv += optind; -#ifdef FREEBSD_DEVELOPER - if (!K_flag && freebsd) { - /* XXX Note: The leading -K is not needed, it gets added later! */ - K_flag = "eAuthor,eDate,eHeader,eId,eLocker,eLog,eRCSfile,eRevision,eSource,eState,iFreeBSD"; - } -#endif /* FREEBSD_DEVELOPER */ - /* * If we are updating the entire directory (for real) and building dirs * as we go, we make sure there is no static entries file and write the @@ -204,7 +179,10 @@ update (argc, argv) if (argc <= 0 && !pipeout) { if (update_build_dirs) - (void) unlink_file (CVSADM_ENTSTAT); + { + if (unlink_file (CVSADM_ENTSTAT) < 0 && errno != ENOENT) + error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT); + } /* keep the CVS/Tag file current with the specified arguments */ if (aflag || tag || date) @@ -221,8 +199,7 @@ update (argc, argv) /* call the command line interface */ err = do_update (argc, argv, options, tag, date, force_tag_match, local, update_build_dirs, aflag, update_prune_dirs, - pipeout, which, join_rev1, join_rev2, - K_flag, (char *) NULL); + pipeout, which, join_rev1, join_rev2, (char *) NULL); /* free the space Make_Date allocated if necessary */ if (date != NULL) @@ -236,8 +213,7 @@ update (argc, argv) */ int do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, - xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, - xK_flag, preload_update_dir) + xprune, xpipeout, which, xjoin_rev1, xjoin_rev2, preload_update_dir) int argc; char *argv[]; char *xoptions; @@ -252,7 +228,6 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, int which; char *xjoin_rev1; char *xjoin_rev2; - char *xK_flag; char *preload_update_dir; { int err = 0; @@ -268,19 +243,17 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, update_prune_dirs = xprune; pipeout = xpipeout; - K_flag = xK_flag; - /* setup the join support */ join_rev1 = xjoin_rev1; join_rev2 = xjoin_rev2; - if (join_rev1 && (cp = index (join_rev1, ':')) != NULL) + if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL) { *cp++ = '\0'; date_rev1 = Make_Date (cp); } else date_rev1 = (char *) NULL; - if (join_rev2 && (cp = index (join_rev2, ':')) != NULL) + if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL) { *cp++ = '\0'; date_rev2 = Make_Date (cp); @@ -292,7 +265,18 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag, err = start_recursion (update_file_proc, update_filesdone_proc, update_dirent_proc, update_dirleave_proc, argc, argv, local, which, aflag, 1, - preload_update_dir, 1); + preload_update_dir, 1, 0); + + /* see if we need to sleep before returning */ + if (last_register_time) + { + time_t now; + + (void) time (&now); + if (now == last_register_time) + sleep (1); /* to avoid time-stamp races */ + } + return (err); } @@ -320,7 +304,8 @@ update_file_proc (file, update_dir, repository, entries, srcfiles) Vers_TS *vers; status = Classify_File (file, tag, date, options, force_tag_match, - aflag, repository, entries, srcfiles, &vers); + aflag, repository, entries, srcfiles, &vers, + update_dir, pipeout); if (pipeout) { /* @@ -368,13 +353,65 @@ update_file_proc (file, update_dir, repository, entries, srcfiles) break; case T_CONFLICT: /* old punt-type errors */ retval = 1; + (void) write_letter (file, 'C', update_dir); break; - case T_NEEDS_MERGE: /* needs merging */ + case T_NEEDS_MERGE: /* needs merging */ retval = merge_file (file, repository, entries, vers, update_dir); break; case T_MODIFIED: /* locally modified */ - retval = write_letter (file, 'M', update_dir); + retval = 0; + if (vers->ts_conflict) + { + char *filestamp; + int retcode; + + /* + * If the timestamp has changed and no conflict indicators + * are found, it isn't a 'C' any more. + */ + filestamp = time_stamp (file); + retcode = strcmp (vers->ts_conflict, filestamp); + free (filestamp); + + if (retcode) + { + /* + * If the timestamps differ, look for Conflict + * indicators to see if 'C' anyway. + */ + run_setup ("%s -s", GREP); + run_arg (RCS_MERGE_PAT); + run_arg (file); + retcode = run_exec (RUN_TTY, RUN_TTY, + RUN_TTY,RUN_NORMAL); + if (retcode == -1) + { + if (update_dir[0] == '\0') + error (1, errno, + "fork failed while examining conflict in `%s'", + file); + else + error (1, errno, + "fork failed while examining conflict in `%s/%s'", + update_dir, file); + } + } + if (!retcode) + { + (void) write_letter (file, 'C', update_dir); + retval = 1; + } + else + { + /* Reregister to clear conflict flag. */ + Register (entries, file, vers->vn_rcs, vers->ts_rcs, + vers->options, vers->tag, + vers->date, (char *)0); + } + } + if (!retval) + retval = write_letter (file, 'M', update_dir); break; case T_CHECKOUT: /* needs checkout */ retval = checkout_file (file, repository, entries, srcfiles, @@ -399,7 +436,7 @@ update_file_proc (file, update_dir, repository, entries, srcfiles) /* only try to join if things have gone well thus far */ if (retval == 0 && join_rev1) - join_file (file, srcfiles, vers, update_dir); + join_file (file, srcfiles, vers, update_dir, entries); /* if this directory has an ignore list, add this file to it */ if (ignlist) @@ -409,7 +446,8 @@ update_file_proc (file, update_dir, repository, entries, srcfiles) p = getnode (); p->type = FILES; p->key = xstrdup (file); - (void) addnode (ignlist, p); + if (addnode (ignlist, p) != 0) + freenode (p); } freevers_ts (&vers); @@ -440,37 +478,14 @@ update_filesdone_proc (err, repository, update_dir) run_arg (CVSADM); (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL); } - -#ifdef DO_LINKS +#ifdef CVSADM_ROOT + else { - char lnfile[PATH_MAX]; - FILE *links; - - sprintf(lnfile, "%s/SymLinks", repository); - links = fopen(lnfile, "r"); - if (links) { - char from[PATH_MAX], to[PATH_MAX]; - - /* Read all the link pairs from the symlinks file */ - while (fgets(to, PATH_MAX, links)) { - fgets(from, PATH_MAX, links); - - /* Strip off the newlines */ - to[strlen(to) - 1] = '\0'; - from[strlen(from) - 1] = '\0'; - - /* Do it */ - if (symlink(from, to) == -1) { - error (0, errno, "Unable to create symlink `%s'", to); - return 1; - } - else if (!quiet) - error (0, 0, "Creating symlink %s", to); - } - fclose(links); - } + /* If there is no CVS/Root file, add one */ + if (!isfile (CVSADM_ROOT)) + Create_Root( (char *) NULL, CVSroot ); } -#endif +#endif /* CVSADM_ROOT */ return (err); } @@ -489,6 +504,14 @@ update_dirent_proc (dir, repository, update_dir) char *repository; char *update_dir; { + if (ignore_directory (update_dir)) + { + /* print the warm fuzzy message */ + if (!quiet) + error (0, 0, "Ignoring %s", update_dir); + return R_SKIP_ALL; + } + if (!isdir (dir)) { /* if we aren't building dirs, blow it off */ @@ -520,7 +543,8 @@ update_dirent_proc (dir, repository, update_dir) char tmp[PATH_MAX]; (void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT); - (void) unlink_file (tmp); + if (unlink_file (tmp) < 0 && errno != ENOENT) + error (1, errno, "cannot remove file %s", tmp); } /* keep the CVS/Tag file current with the specified arguments */ @@ -563,7 +587,7 @@ update_dirleave_proc (dir, err, update_dir) repository = Name_Repository ((char *) NULL, update_dir); if (fgets (line, sizeof (line), fp) != NULL) { - if ((cp = rindex (line, '\n')) != NULL) + if ((cp = strrchr (line, '\n')) != NULL) *cp = '\0'; run_setup ("%s %s", line, repository); (void) printf ("%s %s: Executing '", program_name, command_name); @@ -582,6 +606,35 @@ update_dirleave_proc (dir, err, update_dir) run_arg (CVSADM); (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL); } +#ifdef CVSADM_ROOT + else + { + /* If there is no CVS/Root file, add one */ + if (!isreadable (CVSADM_ROOT)) + { + if (isfile (CVSADM_ROOT)) + { + error (0, 0, "bad permissions %s/%s deleteing it", update_dir, + CVSADM_ROOT); + if (unlink_file (CVSADM_ROOT) == -1) + { + error (0, errno, "delete failed for %s/%s", + update_dir, CVSADM_ROOT); + } + } + Create_Root( (char *) NULL, CVSroot ); + } + else + { + char *root = Name_Root( (char *) NULL, update_dir); + + if (root == NULL) + Create_Root( (char *) NULL, CVSroot ); + else + free (root); /* all is well, release the storage */ + } + } +#endif /* CVSADM_ROOT */ /* Prune empty dirs on the way out - if necessary */ (void) chdir (".."); @@ -604,7 +657,7 @@ isemptydir (dir) char *dir; { DIR *dirp; - struct direct *dp; + struct dirent *dp; if ((dirp = opendir (dir)) == NULL) { @@ -667,8 +720,8 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir) (void) unlink_file (backup); } - run_setup ("%s%s -q -r%s %s %s%s", Rcsbin, RCS_CO, vers_ts->vn_rcs, - vers_ts->options, K_flag ? "-K" : "", K_flag ? K_flag : ""); + run_setup ("%s%s -q -r%s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs, + vers_ts->options); /* * if we are checking out to stdout, print a nice message to stderr, and @@ -719,8 +772,12 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir) force_tag_match, set_time, entries, srcfiles); if (strcmp (xvers_ts->options, "-V4") == 0) xvers_ts->options[0] = '\0'; + + (void) time (&last_register_time); + Register (entries, file, xvers_ts->vn_rcs, xvers_ts->ts_user, - xvers_ts->options, xvers_ts->tag, xvers_ts->date); + xvers_ts->options, xvers_ts->tag, xvers_ts->date, + (char *)0); /* Clear conflict flag on fresh checkout */ /* fix up the vers structure, in case it is used by join */ if (join_rev1) @@ -775,7 +832,7 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir) static int write_letter (file, letter, update_dir) char *file; - char letter; + int letter; char *update_dir; { if (!really_quiet) @@ -839,11 +896,20 @@ merge_file (file, repository, entries, vers, update_dir) rename_file (backup, file); return (1); } - /* XXX - Might want to make sure that rcsmerge changed the file */ + if (strcmp (vers->options, "-V4") == 0) vers->options[0] = '\0'; - Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options, - vers->tag, vers->date); + (void) time (&last_register_time); + { + char *cp = 0; + + if (status) + cp = time_stamp (file); + Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options, + vers->tag, vers->date, cp); + if (cp) + free (cp); + } /* fix up the vers structure, in case it is used by join */ if (join_rev1) @@ -853,6 +919,14 @@ merge_file (file, repository, entries, vers, update_dir) vers->vn_user = xstrdup (vers->vn_rcs); } + if (!xcmp (backup, file)) + { + printf ("%s already contains the differences between %s and %s\n", + user, vers->vn_user, vers->vn_rcs); + history_write ('G', update_dir, vers->vn_rcs, file, repository); + return (0); + } + /* possibly run GREP to see if there appear to be conflicts in the file */ run_setup ("%s -s", GREP); run_arg (RCS_MERGE_PAT); @@ -887,98 +961,216 @@ merge_file (file, repository, entries, vers, update_dir) * (-j option) */ static void -join_file (file, srcfiles, vers, update_dir) +join_file (file, srcfiles, vers, update_dir, entries) char *file; List *srcfiles; Vers_TS *vers; char *update_dir; + List *entries; { char user[PATH_MAX]; char backup[PATH_MAX]; - char *rev, *baserev; char *options; int status; + char *rev1; + char *rev2; + char *jrev1; + char *jrev2; + char *jdate1; + char *jdate2; + + jrev1 = join_rev1; + jrev2 = join_rev2; + jdate1 = date_rev1; + jdate2 = date_rev2; + /* determine if we need to do anything at all */ - if (vers->vn_user == NULL || vers->srcfile == NULL || + if (vers->srcfile == NULL || vers->srcfile->path == NULL) { return; } - /* special handling when two revisions are specified */ - if (join_rev1 && join_rev2) + /* in all cases, use two revs. */ + + /* if only one rev is specified, it becomes the second rev */ + if (jrev2 == NULL) { - rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1); - if (rev == NULL) + jrev2 = jrev1; + jrev1 = NULL; + jdate2 = jdate1; + jdate1 = NULL; + } + + /* convert the second rev spec, walking branches and dates. */ + + rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1); + if (rev2 == NULL) + { + if (!quiet) { - if (!quiet && date_rev2 == NULL) + if (jdate2 != NULL) error (0, 0, - "cannot find revision %s in file %s", join_rev2, file); + "cannot find revision %s as of %s in file %s", + jrev2, jdate2, file); + else + error (0, 0, + "cannot find revision %s in file %s", + jrev2, file); return; } + } + + /* skip joining identical revs */ + if (strcmp (rev2, vers->vn_user) == 0) /* no merge necessary */ + { + free (rev2); + return; + } - baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1); - if (baserev == NULL) + if (jrev1 == NULL) + { + char *tst; + /* if the first rev is missing, then it is implied to be the + greatest common ancestor of both the join rev, and the + checked out rev. */ + + tst = vers->vn_user; + if (*tst == '!') { - if (!quiet && date_rev1 == NULL) - error (0, 0, - "cannot find revision %s in file %s", join_rev1, file); - free (rev); - return; + /* file was dead. merge anyway and pretend it's been + added. */ + ++tst; + Register (entries, file, "0", vers->ts_user, vers->options, + vers->tag, (char *) 0, (char *) 0); + } + rev1 = gca (tst, rev2); + if (rev1 == NULL) + { + /* this should not be possible */ + error (0, 0, "bad gca"); + abort(); } - /* - * nothing to do if: - * second revision matches our BASE revision (vn_user) && - * both revisions are on the same branch - */ - if (strcmp (vers->vn_user, rev) == 0 && - numdots (baserev) == numdots (rev)) + tst = RCS_gettag (vers->srcfile, rev2, 1); + if (tst == NULL) { - /* might be the same branch. take a real look */ - char *dot = rindex (baserev, '.'); - int len = (dot - baserev) + 1; + /* this should not be possible. */ + error (0, 0, "cannot find gca"); + abort(); + } - if (strncmp (baserev, rev, len) == 0) - return; + free (tst); + + /* these two cases are noops */ + if (strcmp (rev1, rev2) == 0) + { + free (rev1); + free (rev2); + return; } } else { - rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1); - if (rev == NULL) - return; - if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */ + /* otherwise, convert the first rev spec, walking branches and + dates. */ + + rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1); + if (rev1 == NULL + && !quiet) { - free (rev); + if (jdate1 != NULL) + error (0, 0, + "cannot find revision %s as of %s in file %s", + jrev1, jdate1, file); + else + error (0, 0, + "cannot find revision %s in file %s", + jrev1, file); return; } + } - baserev = RCS_whatbranch (file, join_rev1, srcfiles); - if (baserev) - { - char *cp; + /* do the join */ - /* we get a branch -- turn it into a revision, or NULL if trunk */ - if ((cp = rindex (baserev, '.')) == NULL) +#if 0 + dome { + /* special handling when two revisions are specified */ + if (join_rev1 && join_rev2) + { + rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1); + if (rev == NULL) { - free (baserev); - baserev = (char *) NULL; + if (!quiet && date_rev2 == NULL) + error (0, 0, + "cannot find revision %s in file %s", join_rev2, file); + return; + } + + baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1); + if (baserev == NULL) + { + if (!quiet && date_rev1 == NULL) + error (0, 0, + "cannot find revision %s in file %s", join_rev1, file); + free (rev); + return; + } + + /* + * nothing to do if: + * second revision matches our BASE revision (vn_user) && + * both revisions are on the same branch + */ + if (strcmp (vers->vn_user, rev) == 0 && + numdots (baserev) == numdots (rev)) + { + /* might be the same branch. take a real look */ + char *dot = strrchr (baserev, '.'); + int len = (dot - baserev) + 1; + + if (strncmp (baserev, rev, len) == 0) + return; } - else - *cp = '\0'; + } + else + { + rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1); + if (rev == NULL) + return; + if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */ + { + free (rev); + return; + } + + baserev = RCS_whatbranch (file, join_rev1, srcfiles); + if (baserev) + { + char *cp; + + /* we get a branch -- turn it into a revision, or NULL if trunk */ + if ((cp = strrchr (baserev, '.')) == NULL) + { + free (baserev); + baserev = (char *) NULL; + } + else + *cp = '\0'; + } + } + if (baserev && strcmp (baserev, rev) == 0) + { + /* they match -> nothing to do */ + free (rev); + free (baserev); + return; } } - if (baserev && strcmp (baserev, rev) == 0) - { - /* they match -> nothing to do */ - free (rev); - free (baserev); - return; - } +#endif - /* OK, so we have a revision and possibly a base revision; continue on */ + /* OK, so we have two revisions; continue on */ /* * The users currently modified file is moved to a backup file name @@ -999,13 +1191,15 @@ join_file (file, srcfiles, vers, update_dir) options = vers->options; #ifdef HAVE_RCS5 +#if 0 if (*options == '\0') options = "-kk"; /* to ignore keyword expansions */ #endif +#endif /* XXX - Do merge by hand instead of using rcsmerge, due to -k handling */ - run_setup ("%s%s %s %s%s -r%s", Rcsbin, RCS_RCSMERGE, options, - baserev ? "-r" : "", baserev ? baserev : "", rev); + run_setup ("%s%s %s -r%s -r%s", Rcsbin, RCS_RCSMERGE, options, + rev1, rev2); run_arg (vers->srcfile->path); status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL); if (status != 0 @@ -1015,14 +1209,28 @@ join_file (file, srcfiles, vers, update_dir) ) { error (0, status == -1 ? errno : 0, - "could not merge revision %s of %s", rev, user); + "could not merge revision %s of %s", rev2, user); error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s", user, backup); rename_file (backup, file); } - free (rev); - if (baserev) - free (baserev); + free (rev1); + free (rev2); + +#ifdef HAVE_RCS5 + if (status == 1) + { + char *cp = 0; + + if (status) + cp = time_stamp (file); + Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options, + vers->tag, vers->date, cp); + if (cp) + free(cp); + } +#endif + return; } @@ -1036,7 +1244,7 @@ ignore_files (ilist, update_dir) char *update_dir; { DIR *dirp; - struct direct *dp; + struct dirent *dp; struct stat sb; char *file; char *xdir; @@ -1059,18 +1267,47 @@ ignore_files (ilist, update_dir) continue; if (findnode (ilist, file) != NULL) continue; - if (lstat (file, &sb) != -1) + + if ( +#ifdef DT_DIR + dp->d_type != DT_UNKNOWN || +#endif + lstat(file, &sb) != -1) { - if (S_ISDIR (sb.st_mode)) - continue; -#ifdef S_IFLNK - if (S_ISLNK (sb.st_mode)) + + if ( +#ifdef DT_DIR + dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN && +#endif + S_ISDIR(sb.st_mode)) + { + char temp[PATH_MAX]; + + (void) sprintf (temp, "%s/%s", file, CVSADM); + if (isdir (temp)) + continue; + } +#ifdef S_ISLNK + else if ( +#ifdef DT_DIR + dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN && +#endif + S_ISLNK(sb.st_mode)) + { continue; + } #endif - } + } + if (ign_name (file)) continue; (void) write_letter (file, '?', xdir); } (void) closedir (dirp); } + +int +joining () +{ + return (join_rev1 != NULL); +} diff --git a/gnu/usr.bin/cvs/cvsinit/cvsinit.sh b/gnu/usr.bin/cvs/cvsinit/cvsinit.sh index 58e4332..3885221 100644 --- a/gnu/usr.bin/cvs/cvsinit/cvsinit.sh +++ b/gnu/usr.bin/cvs/cvsinit/cvsinit.sh @@ -1,14 +1,18 @@ +#! /bin/sh -x : # # Copyright (c) 1992, Brian Berliner # # You may distribute under the terms of the GNU General Public License as -# specified in the README file that comes with the CVS 1.3 kit. +# specified in the README file that comes with the CVS 1.4 kit. # -# @(#)cvsinit 1.1 92/03/31 +# $CVSid: @(#)cvsinit.sh 1.1 94/10/22 $ # # This script should be run once to help you setup your site for CVS. +# this line is edited by Makefile when creating cvsinit.inst +CVSLIB="/usr/src/gnu/usr.bin/cvs" + # Make sure that the CVSROOT variable is set if [ "x$CVSROOT" = x ]; then echo "The CVSROOT environment variable is not set." @@ -153,15 +157,15 @@ else echo "Making a simple one for you..." # try to find perl; use fancy log script if we can for perlpath in `echo $PATH | sed -e 's/:/ /g'` x; do - if [ -f $perlpath/perl ]; then + if [ -f $perlpath/perl -a -r $CVSLIB/contrib/log.pl ]; then echo "#!$perlpath/perl" > $CVSROOT/CVSROOT/log.pl - cat contrib/log.pl >> $CVSROOT/CVSROOT/log.pl + cat $CVSLIB/contrib/log.pl >> $CVSROOT/CVSROOT/log.pl chmod 755 $CVSROOT/CVSROOT/log.pl - cp examples/loginfo $CVSROOT/CVSROOT/loginfo + cp $CVSLIB/examples/loginfo $CVSROOT/CVSROOT/loginfo break fi done - if [ $perlpath = x ]; then + if [ $perlpath = x -o ! -r $CVSLIB/contrib/log.pl ]; then # we did not find perl anywhere, so make a simple loginfo file cat > $CVSROOT/CVSROOT/loginfo <<"HERE" # @@ -204,16 +208,20 @@ for info in commitinfo rcsinfo editinfo; do echo "You have a $CVSROOT/CVSROOT/$info file," echo "But no $CVSROOT/CVSROOT/${info},v file." echo "I'll create one for you, but otherwise leave it alone..." + (cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info) else echo "The $CVSROOT/CVSROOT/$info file does not exist." - echo "Making a simple one for you..." - sed -e 's/^\([^#]\)/#\1/' examples/$info > $CVSROOT/CVSROOT/$info + if [ -r $CVSLIB/examples/$info ]; then + echo "Making a simple one for you..." + sed -e 's/^\([^#]\)/#\1/' $CVSLIB/examples/$info > $CVSROOT/CVSROOT/$info + fi fi - (cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info) echo "" fi done +# XXX - also add a stub for the cvsignore file + # Turn on history logging by default if [ ! -f $CVSROOT/CVSROOT/history ]; then echo "Enabling CVS history logging..." diff --git a/gnu/usr.bin/cvs/doc/Makefile b/gnu/usr.bin/cvs/doc/Makefile new file mode 100644 index 0000000..a0cdc97 --- /dev/null +++ b/gnu/usr.bin/cvs/doc/Makefile @@ -0,0 +1,3 @@ +INFO = cvs + +.include <bsd.info.mk> diff --git a/gnu/usr.bin/cvs/lib/Makefile b/gnu/usr.bin/cvs/lib/Makefile index ab44594b..af510b6 100644 --- a/gnu/usr.bin/cvs/lib/Makefile +++ b/gnu/usr.bin/cvs/lib/Makefile @@ -1,14 +1,13 @@ -LIB = cvs - -CFLAGS += -I${.CURDIR} -I${.CURDIR}/../cvs -DFTIME_MISSING -DHAVE_TIMEZONE +# $Id: Makefile,v 1.25 1995/03/22 19:39:45 nate Exp $ -SRCS = argmatch.c error.c getopt.c sighandle.c strippath.c stripslash.c yesno.c \ - getdate.y fnmatch.c subr.c myndbm.c hash.c +LIB = cvs +NOPROFILE= yes +CFLAGS += -I${.CURDIR} -I${.CURDIR}/../cvs -DHAVE_CONFIG_H -DHAVE_TIMEZONE +SRCS = argmatch.c error.c getdate.y getopt.c getopt1.c fnmatch.c myndbm.c \ + hash.c sighandle.c strippath.c stripslash.c subr.c version.c yesno.c CLEANFILES+= getdate.c y.tab.h -NOPROFILE= yes - install: @echo -n diff --git a/gnu/usr.bin/cvs/lib/getopt.c b/gnu/usr.bin/cvs/lib/getopt.c index b61fc89..446a8e4 100644 --- a/gnu/usr.bin/cvs/lib/getopt.c +++ b/gnu/usr.bin/cvs/lib/getopt.c @@ -1,10 +1,15 @@ /* Getopt for GNU. - Copyright (C) 1987-1992 Free Software Foundation, Inc. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! - 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. + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 + 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 @@ -13,73 +18,73 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !__STDC__ +/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. + Ditto for AIX 3.2 and <stdlib.h>. */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +#if defined (emacs) || defined (CONFIG_BROKETS) +/* We use <config.h> instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because it found this file in $srcdir). */ +#include <config.h> +#else +#include "config.h" +#endif +#endif + +#ifndef __STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const #define const #endif +#endif + +#include <stdio.h> + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include <stdlib.h> +#endif /* GNU C library. */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. - As `getopt' works, it permutes the elements of `argv' so that, + As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. - Setting the environment variable _POSIX_OPTION_ORDER disables permutation. + Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #ifndef lint -static char rcsid[] = "@(#)getopt.c 1.7 92/03/31"; -#endif - -#include <stdio.h> - -#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__) -#include <stdlib.h> -#else /* STDC_HEADERS or __GNU_LIBRARY__ */ -char *getenv (); -char *malloc (); -#endif /* STDC_HEADERS or __GNU_LIBRARY__ */ - -/* AIX requires this to be the first thing in the file. */ -#ifdef __GNUC__ -#if !defined(bsdi) && !defined(__FreeBSD__) -#define alloca __builtin_alloca +static char rcsid[] = "$CVSid: @(#)getopt.c 1.10 94/09/21 $"; #endif -#else /* not __GNUC__ */ -#ifdef sparc -#include <alloca.h> -#else -#ifdef _AIX - #pragma alloca -#else -char *alloca (); -#endif -#endif /* sparc */ -#endif /* not __GNUC__ */ -#if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__) -#include <string.h> -#ifndef bcopy -#define bcopy(s, d, n) memcpy ((d), (s), (n)) -#endif -#ifndef index -#define index strchr -#endif -#else /* USG or STDC_HEADERS or __GNU_LIBRARY__ */ -#ifdef VMS -#include <string.h> -#else /* VMS */ -#include <strings.h> -#endif /* VMS */ -/* Declaring bcopy causes errors on systems whose declarations are different. - If the declaration is omitted, everything works fine. */ -#endif /* USG or STDC_HEADERS or __GNU_LIBRARY__ */ +#include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, @@ -87,7 +92,7 @@ char *alloca (); Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ -char *optarg = 0; +char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller @@ -101,6 +106,7 @@ char *optarg = 0; Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ +/* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element @@ -117,17 +123,23 @@ static char *nextchar; int opterr = 1; +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable - _POSIX_OPTION_ORDER is defined, PERMUTE otherwise. + POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment - variable POSIX_ME_HARDER, or using `+' as the first character + variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, @@ -151,28 +163,50 @@ static enum REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; -/* Describe the long-named options requested by the application. - _GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an - element containing a name which is zero. - The field `has_arg' is 1 if the option takes an argument, - 2 if it takes an optional argument. */ - -struct option -{ - char *name; - int has_arg; - int *flag; - int val; -}; +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include <string.h> +#define my_index strchr +#else -const struct option *_getopt_long_options; +/* Avoid depending on library functions or files + whose names are inconsistent. */ -int _getopt_long_only = 0; +char *getenv (); -/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found. - Only valid when a long-named option was found. */ +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} -int option_index; +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +#ifndef __STDC__ +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +#endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ @@ -185,32 +219,104 @@ static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. + which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. + the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ + the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { - int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); - char **temp = (char **) alloca (nonopts_size); + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; - /* Interchange the two blocks of data in ARGV. */ + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; - bcopy (&argv[first_nonopt], temp, nonopts_size); - bcopy (&argv[last_nonopt], &argv[first_nonopt], - (optind - last_nonopt) * sizeof (char *)); - bcopy (temp, &argv[first_nonopt + optind - last_nonopt], nonopts_size); + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } + +/* Initialize the internal data when the first call is made. */ + +static const char * +_getopt_initialize (optstring) + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + + return optstring; +} /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. @@ -245,78 +351,67 @@ exchange (argv) handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - Long-named options begin with `+' instead of `-'. + Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field - otherwise. */ + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ int -gnu_getopt (argc, argv, optstring) +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; - char **argv; + char *const *argv; const char *optstring; + const struct option *longopts; + int *longind; + int long_only; { - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ + optarg = NULL; if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; + optstring = _getopt_initialize (optstring); - nextchar = 0; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIX_ME_HARDER") != 0) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - } - - if (nextchar == 0 || *nextchar == 0) + if (nextchar == NULL || *nextchar == '\0') { + /* Advance to the next ARGV-element. */ + if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange (argv); + exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; - /* Now skip any additional non-options + /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc - && (argv[optind][0] != '-' - || argv[optind][1] == 0) - && (_getopt_long_options == 0 - || argv[optind][0] != '+' - || argv[optind][1] == 0)) + && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } - /* Special ARGV-element `--' means premature end of options. + /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ @@ -326,7 +421,7 @@ gnu_getopt (argc, argv, optstring) optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange (argv); + exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; @@ -349,9 +444,7 @@ gnu_getopt (argc, argv, optstring) /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ - if ((argv[optind][0] != '-' || argv[optind][1] == 0) - && (_getopt_long_options == 0 - || argv[optind][0] != '+' || argv[optind][1] == 0)) + if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; @@ -360,32 +453,48 @@ gnu_getopt (argc, argv, optstring) } /* We have found another option-ARGV-element. - Start decoding its characters. */ + Skip the initial punctuation. */ - nextchar = argv[optind] + 1; + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); } - if (_getopt_long_options != 0 - && (argv[optind][0] == '+' - || (_getopt_long_only && argv[optind][0] == '-')) - ) + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { + char *nameend; const struct option *p; - char *s = nextchar; + const struct option *pfound = NULL; int exact = 0; int ambig = 0; - const struct option *pfound = 0; - int indfound = 0; + int indfound; + int option_index; - while (*s && *s != '=') - s++; + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; - /* Test all options for either exact match or abbreviated matches. */ - for (p = _getopt_long_options, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) { - if (s - nextchar == strlen (p->name)) + if (nameend - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; @@ -393,39 +502,52 @@ gnu_getopt (argc, argv, optstring) exact = 1; break; } - else if (pfound == 0) + else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else - /* Second nonexact match found. */ + /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } - if (pfound != 0) + if (pfound != NULL) { option_index = indfound; optind++; - if (*s) + if (*nameend) { - if (pfound->has_arg > 0) - optarg = s + 1; + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; else { - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } nextchar += strlen (nextchar); return '?'; } @@ -436,13 +558,16 @@ gnu_getopt (argc, argv, optstring) optarg = argv[optind++]; else { - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); nextchar += strlen (nextchar); - return '?'; + return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; @@ -450,43 +575,52 @@ gnu_getopt (argc, argv, optstring) } return pfound->val; } - /* Can't find it as a long option. If this is getopt_long_only, - and the option starts with '-' and is a valid short - option, then interpret it as a short option. Otherwise it's - an error. */ - if (_getopt_long_only == 0 || argv[optind][0] == '+' || - index (optstring, *nextchar) == 0) + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) { - if (opterr != 0) - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - nextchar += strlen (nextchar); + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; optind++; return '?'; } } - /* Look at and handle the next option-character. */ + /* Look at and handle the next short option-character. */ { char c = *nextchar++; - char *temp = index (optstring, c); + char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ - if (*nextchar == 0) - optind++; + if (*nextchar == '\0') + ++optind; - if (temp == 0 || c == ':') + if (temp == NULL || c == ':') { - if (opterr != 0) + if (opterr) { - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - argv[0], c); + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); else - fprintf (stderr, "%s: unrecognized option `-%c'\n", - argv[0], c); + fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c); } + optopt = c; return '?'; } if (temp[1] == ':') @@ -494,19 +628,19 @@ gnu_getopt (argc, argv, optstring) if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ - if (*nextchar != 0) + if (*nextchar != '\0') { optarg = nextchar; optind++; } else - optarg = 0; - nextchar = 0; + optarg = NULL; + nextchar = NULL; } else { /* This is an option that requires an argument. */ - if (*nextchar != 0) + if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, @@ -515,21 +649,42 @@ gnu_getopt (argc, argv, optstring) } else if (optind == argc) { - if (opterr != 0) - fprintf (stderr, "%s: option `-%c' requires an argument\n", - argv[0], c); - c = '?'; + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; - nextchar = 0; + nextchar = NULL; } } return c; } } + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST @@ -548,7 +703,7 @@ main (argc, argv) { int this_option_optind = optind ? optind : 1; - c = gnu_getopt (argc, argv, "abc:d:0123456789"); + c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; diff --git a/gnu/usr.bin/cvs/mkmodules/Makefile b/gnu/usr.bin/cvs/mkmodules/Makefile index 4a6ec7c..f37930b 100644 --- a/gnu/usr.bin/cvs/mkmodules/Makefile +++ b/gnu/usr.bin/cvs/mkmodules/Makefile @@ -1,9 +1,10 @@ +# $Id: Makefile,v 1.25 1995/03/22 19:39:45 nate Exp $ + PROG = mkmodules SRCS = mkmodules.c -CFLAGS += -I${.CURDIR}/../cvs -I${.CURDIR}/../lib +CFLAGS+= -I${.CURDIR}/../cvs -I${.CURDIR}/../lib -DHAVE_CONFIG_H -DHAVE_TIMEZONE DPADD+= ${LIBCVS} LDADD+= -lcvs .include "../../Makefile.inc" -.include "../Makefile.inc" .include <bsd.prog.mk> |