X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/c03d198b2336ff0cb6f7293afa3569391cc451c0..9be60522cd2e7ab0aeb1940a0f648c2113250f7a:/usr/src/usr.bin/sccs/sccs.c diff --git a/usr/src/usr.bin/sccs/sccs.c b/usr/src/usr.bin/sccs/sccs.c index 2466dca83c..8ceba1a6d2 100644 --- a/usr/src/usr.bin/sccs/sccs.c +++ b/usr/src/usr.bin/sccs/sccs.c @@ -6,6 +6,7 @@ # include # include # include +# include /* ** SCCS.C -- human-oriented front end to the SCCS system. @@ -92,7 +93,7 @@ ** Copyright 1980 Regents of the University of California */ -static char SccsId[] = "@(#)sccs.c 1.48 %G%"; +static char SccsId[] = "@(#)sccs.c 1.63 %G%"; /******************* Configuration Information ********************/ @@ -108,6 +109,10 @@ static char SccsId[] = "@(#)sccs.c 1.48 %G%"; # define PROGPATH(name) "/usr/local/name" # endif INGVAX +# ifdef CORY +# define PROGPATH(name) "/usr/eecs/bin/name" +# endif CORY + /* end of berkeley systems defines */ # ifndef SCCSPATH @@ -130,10 +135,6 @@ typedef char bool; # define bitset(bit, word) ((bool) ((bit) & (word))) -# ifdef UIDUSER -# include -# endif UIDUSER - struct sccsprog { char *sccsname; /* name of SCCS routine */ @@ -150,6 +151,8 @@ struct sccsprog # define UNEDIT 4 /* unedit a file */ # define SHELL 5 /* call a shell file (like PROG) */ # define DIFFS 6 /* diff between sccs & file out */ +# define DODIFF 7 /* internal call to diff program */ +# define CREATE 8 /* create new files */ /* bits for sccsflags */ # define NO_SDOT 0001 /* no s. on front of args */ @@ -172,27 +175,34 @@ struct sccsprog struct sccsprog SccsProg[] = { - "admin", PROG, REALUSER, PROGPATH(admin), - "chghist", PROG, 0, PROGPATH(rmdel), - "comb", PROG, 0, PROGPATH(comb), - "delta", PROG, 0, PROGPATH(delta), - "get", PROG, 0, PROGPATH(get), - "help", PROG, NO_SDOT, PROGPATH(help), - "prt", PROG, 0, PROGPATH(prt), - "rmdel", PROG, REALUSER, PROGPATH(rmdel), - "what", PROG, NO_SDOT, PROGPATH(what), - "sccsdiff", SHELL, REALUSER, PROGPATH(sccsdiff), - "edit", CMACRO, NO_SDOT, "get -e", - "delget", CMACRO, NO_SDOT, "delta:mysrp/get:ixbeskcl -t", - "deledit", CMACRO, NO_SDOT, "delta:mysrp/get:ixbskcl -e -t", - "fix", FIX, NO_SDOT, NULL, - "clean", CLEAN, REALUSER, (char *) CLEANC, - "info", CLEAN, REALUSER, (char *) INFOC, - "check", CLEAN, REALUSER, (char *) CHECKC, - "tell", CLEAN, REALUSER, (char *) TELLC, - "unedit", UNEDIT, NO_SDOT, NULL, - "diffs", DIFFS, NO_SDOT|REALUSER, NULL, - NULL, -1, 0, NULL + "admin", PROG, REALUSER, PROGPATH(admin), + "chghist", PROG, 0, PROGPATH(rmdel), + "comb", PROG, 0, PROGPATH(comb), + "delta", PROG, 0, PROGPATH(delta), + "get", PROG, 0, PROGPATH(get), + "help", PROG, NO_SDOT, PROGPATH(help), + "prs", PROG, 0, PROGPATH(prs), + "prt", PROG, 0, PROGPATH(prt), + "rmdel", PROG, REALUSER, PROGPATH(rmdel), + "val", PROG, 0, PROGPATH(val), + "what", PROG, NO_SDOT, PROGPATH(what), + "sccsdiff", SHELL, REALUSER, PROGPATH(sccsdiff), + "edit", CMACRO, NO_SDOT, "get -e", + "delget", CMACRO, NO_SDOT, "delta:mysrp/get:ixbeskcl -t", + "deledit", CMACRO, NO_SDOT, "delta:mysrp -n/get:ixbskcl -e -t -g", + "fix", FIX, NO_SDOT, NULL, + "clean", CLEAN, REALUSER|NO_SDOT, (char *) CLEANC, + "info", CLEAN, REALUSER|NO_SDOT, (char *) INFOC, + "check", CLEAN, REALUSER|NO_SDOT, (char *) CHECKC, + "tell", CLEAN, REALUSER|NO_SDOT, (char *) TELLC, + "unedit", UNEDIT, NO_SDOT, NULL, + "diffs", DIFFS, NO_SDOT|REALUSER, NULL, + "-diff", DODIFF, NO_SDOT|REALUSER, PROGPATH(bdiff), + "print", CMACRO, 0, "prt -e/get -p -m -s", + "branch", CMACRO, NO_SDOT, + "get:ixrc -e -b/delta: -s -n -ybranch-place-holder/get:pl -e -t -g", + "create", CREATE, NO_SDOT, NULL, + NULL, -1, 0, NULL }; /* one line from a p-file */ @@ -203,6 +213,7 @@ struct pfile char *p_user; /* user who did edit */ char *p_date; /* date of get */ char *p_time; /* time of get */ + char *p_aux; /* extra info at end */ }; char *SccsPath = SCCSPATH; /* pathname of SCCS files */ @@ -217,6 +228,9 @@ bool RealUser; /* if set, running as real user */ # ifdef DEBUG bool Debug; /* turn on tracing */ # endif +# ifndef V6 +extern char *getenv(); +# endif V6 main(argc, argv) int argc; @@ -225,6 +239,43 @@ main(argc, argv) register char *p; extern struct sccsprog *lookup(); register int i; +# ifndef V6 +# ifndef SCCSDIR + register struct passwd *pw; + extern struct passwd *getpwnam(); + char buf[100]; + + /* pull "SccsDir" out of the environment (possibly) */ + p = getenv("PROJECT"); + if (p != NULL && p[0] != '\0') + { + if (p[0] == '/') + SccsDir = p; + else + { + pw = getpwnam(p); + if (pw == NULL) + { + usrerr("user %s does not exist", p); + exit(EX_USAGE); + } + strcpy(buf, pw->pw_dir); + strcat(buf, "/src"); + if (access(buf, 0) < 0) + { + strcpy(buf, pw->pw_dir); + strcat(buf, "/source"); + if (access(buf, 0) < 0) + { + usrerr("project %s has no source!", p); + exit(EX_USAGE); + } + } + SccsDir = buf; + } + } +# endif SCCSDIR +# endif V6 /* ** Detect and decode flags intended for this program. @@ -253,10 +304,14 @@ main(argc, argv) # ifndef SCCSDIR case 'p': /* path of sccs files */ SccsPath = ++p; + if (SccsPath[0] == '\0' && argv[1] != NULL) + SccsPath = *++argv; break; case 'd': /* directory to search from */ SccsDir = ++p; + if (SccsDir[0] == '\0' && argv[1] != NULL) + SccsDir = *++argv; break; # endif @@ -309,7 +364,7 @@ command(argv, forkflag, arg0) { register struct sccsprog *cmd; register char *p; - char buf[40]; + char buf[100]; extern struct sccsprog *lookup(); char *nav[1000]; char **np; @@ -480,6 +535,53 @@ command(argv, forkflag, arg0) } break; + case DODIFF: /* internal diff call */ + setuid(getuid()); + for (np = ap; *np != NULL; np++) + { + if ((*np)[0] == '-' && (*np)[1] == 'C') + (*np)[1] = 'c'; + } + + /* insert "-" argument */ + np[1] = NULL; + np[0] = np[-1]; + np[-1] = "-"; + + /* execute the diff program of choice */ +# ifndef V6 + execvp("diff", ap); +# endif + execv(cmd->sccspath, argv); + syserr("cannot exec %s", cmd->sccspath); + exit(EX_OSERR); + + case CREATE: /* create new sccs files */ + /* skip over flag arguments */ + for (np = &ap[1]; *np != NULL && **np == '-'; np++) + continue; + argv = np; + + /* do an admin for each file */ + p = argv[1]; + while (*np != NULL) + { + sprintf(buf, "-i%s", *np); + ap[0] = buf; + argv[0] = tail(*np); + argv[1] = NULL; + rval = command(ap, TRUE, "admin"); + argv[1] = p; + if (rval == 0) + { + sprintf(buf, ",%s", tail(*np)); + if (link(*np, buf) >= 0) + unlink(*np); + } + np++; + } + break; + default: syserr("oper %d", cmd->sccsoper); exit(EX_SOFTWARE); @@ -789,6 +891,7 @@ clean(mode, argv) { struct direct dir; char buf[100]; + char *bufend; register FILE *dirfd; register char *basefile; bool gotedit; @@ -798,15 +901,44 @@ clean(mode, argv) extern struct pfile *getpfent(); register struct pfile *pf; register char **ap; + extern char *username(); + char *usernm = NULL; + char *subdir = NULL; + char *cmdname; /* ** Process the argv */ - for (ap = argv; *ap != NULL; ap++) + cmdname = *argv; + for (ap = argv; *++ap != NULL; ) { - if (strcmp(*ap, "-b") == 0) - nobranch = TRUE; + if (**ap == '-') + { + /* we have a flag */ + switch ((*ap)[1]) + { + case 'b': + nobranch = TRUE; + break; + + case 'u': + if ((*ap)[2] != '\0') + usernm = &(*ap)[2]; + else if (ap[1] != NULL && ap[1][0] != '-') + usernm = *++ap; + else + usernm = username(); + break; + } + } + else + { + if (subdir != NULL) + usrerr("too many args"); + else + subdir = *ap; + } } /* @@ -816,7 +948,13 @@ clean(mode, argv) strcpy(buf, SccsDir); if (buf[0] != '\0') strcat(buf, "/"); + if (subdir != NULL) + { + strcat(buf, subdir); + strcat(buf, "/"); + } strcat(buf, SccsPath); + bufend = &buf[strlen(buf)]; dirfd = fopen(buf, "r"); if (dirfd == NULL) @@ -838,12 +976,8 @@ clean(mode, argv) continue; /* got an s. file -- see if the p. file exists */ - strcpy(buf, SccsDir); - if (buf[0] != '\0') - strcat(buf, "/"); - strcat(buf, SccsPath); - strcat(buf, "/p."); - basefile = &buf[strlen(buf)]; + strcpy(bufend, "/p."); + basefile = bufend + 3; strncpy(basefile, &dir.d_name[2], sizeof dir.d_name - 2); basefile[sizeof dir.d_name - 2] = '\0'; @@ -862,6 +996,8 @@ clean(mode, argv) { if (nobranch && isbranch(pf->p_nsid)) continue; + if (usernm != NULL && strcmp(usernm, pf->p_user) != 0 && mode != CLEANC) + continue; gotedit = TRUE; gotpfent = TRUE; if (mode == TELLC) @@ -869,17 +1005,14 @@ clean(mode, argv) printf("%s\n", basefile); break; } - printf("%12s: being edited: %s %s %s %s %s\n", - basefile, pf->p_osid, pf->p_nsid, - pf->p_user, pf->p_date, pf->p_time); + printf("%12s: being edited: ", basefile); + putpfent(pf, stdout); } fclose(pfp); } - if (!gotpfent) - continue; /* the s. file exists and no p. file exists -- unlink the g-file */ - if (mode == CLEANC) + if (mode == CLEANC && !gotpfent) { strncpy(buf, &dir.d_name[2], sizeof dir.d_name - 2); buf[sizeof dir.d_name - 2] = '\0'; @@ -890,7 +1023,15 @@ clean(mode, argv) /* cleanup & report results */ fclose(dirfd); if (!gotedit && mode == INFOC) - printf("Nothing being edited\n"); + { + printf("Nothing being edited"); + if (nobranch) + printf(" (on trunk)"); + if (usernm == NULL) + printf("\n"); + else + printf(" by %s\n", usernm); + } if (mode == CHECKC) exit(gotedit); return (EX_OK); @@ -958,15 +1099,11 @@ unedit(fn) bool delete = FALSE; bool others = FALSE; char *myname; - extern char *getlogin(); + extern char *username(); struct pfile *pent; extern struct pfile *getpfent(); char buf[120]; extern char *makefile(); -# ifdef UIDUSER - struct passwd *pw; - extern struct passwd *getpwuid(); -# endif UIDUSER /* make "s." filename & find the trailing component */ pfn = makefile(fn); @@ -1001,17 +1138,7 @@ unedit(fn) } /* figure out who I am */ -# ifdef UIDUSER - pw = getpwuid(getuid()); - if (pw == NULL) - { - syserr("who are you? (uid=%d)", getuid()); - exit(EX_OSERR); - } - myname = pw->pw_name; -# else - myname = getlogin(); -# endif UIDUSER + myname = username(); /* ** Copy p-file to temp file, doing deletions as needed. @@ -1027,9 +1154,7 @@ unedit(fn) else { /* output it again */ - fprintf(tfp, "%s %s %s %s %s\n", pent->p_osid, - pent->p_nsid, pent->p_user, pent->p_date, - pent->p_time); + putpfent(pent, tfp); others++; } } @@ -1099,8 +1224,33 @@ dodiff(getv, gfile) auto int st; extern int errno; int (*osig)(); + register char *p; + register char **ap; + bool makescript = FALSE; - printf("\n------- %s -------\n", gfile); + for (ap = getv; *ap != NULL; ap++) + { + p = *ap; + if (p[0] == '-') + { + switch (p[1]) + { + case 'E': + p[1] = 'e'; + makescript = TRUE; + break; + } + } + } + + if (makescript) + { + printf("sccs edit %s\n", gfile); + printf("ed - %s << 'xxEOFxx'\n", gfile); + } + else + printf("\n------- %s -------\n", gfile); + fflush(stdout); /* create context for diff to run in */ if (pipe(pipev) < 0) @@ -1118,7 +1268,7 @@ dodiff(getv, gfile) /* in parent; run get */ OutFile = pipev[1]; close(pipev[0]); - rval = command(&getv[1], TRUE, "get -s -k -p"); + rval = command(&getv[1], TRUE, "get:rcixt -s -k -p"); osig = signal(SIGINT, SIG_IGN); while (((i = wait(&st)) >= 0 && i != pid) || errno == EINTR) errno = 0; @@ -1134,14 +1284,17 @@ dodiff(getv, gfile) syserr("dodiff: magic failed"); exit(EX_OSERR); } - execl(PROGPATH(bdiff), "bdiff", "-", gfile, NULL); -# ifndef V6 - execlp("bdiff", "bdiff", "-", gfile, NULL); - execlp("diff", "diff", "-", gfile, NULL); -# endif NOT V6 - syserr("bdiff: cannot execute"); - exit(EX_OSERR); + command(&getv[1], FALSE, "-diff:elsfhbC"); + } + + if (makescript) + { + printf("w\n"); + printf("q\n"); + printf("'xxEOFxx'\n"); + printf("sccs delta %s\n", gfile); } + return (rval); } @@ -1202,8 +1355,7 @@ getpfent(pfp) ent.p_user = p = nextfield(p); ent.p_date = p = nextfield(p); ent.p_time = p = nextfield(p); - if (p == NULL || nextfield(p) != NULL) - return (NULL); + ent.p_aux = p = nextfield(p); return (&ent); } @@ -1225,6 +1377,31 @@ nextfield(p) *p++ = '\0'; return (p); } + /* +** PUTPFENT -- output a p-file entry to a file +** +** Parameters: +** pf -- the p-file entry +** f -- the file to put it on. +** +** Returns: +** none. +** +** Side Effects: +** pf is written onto file f. +*/ + +putpfent(pf, f) + register struct pfile *pf; + register FILE *f; +{ + fprintf(f, "%s %s %s %s %s", pf->p_osid, pf->p_nsid, + pf->p_user, pf->p_date, pf->p_time); + if (pf->p_aux != NULL) + fprintf(f, " %s", pf->p_aux); + else + fprintf(f, "\n"); +} /* ** USRERR -- issue user-level error @@ -1282,3 +1459,41 @@ syserr(f, p1, p2, p3) exit(EX_OSERR); } } + /* +** USERNAME -- return name of the current user +** +** Parameters: +** none +** +** Returns: +** name of current user +** +** Side Effects: +** none +*/ + +char * +username() +{ +# ifdef UIDUSER + extern struct passwd *getpwuid(); + register struct passwd *pw; + + pw = getpwuid(getuid()); + if (pw == NULL) + { + syserr("who are you? (uid=%d)", getuid()); + exit(EX_OSERR); + } + return (pw->pw_name); +# else + extern char *getlogin(); + extern char *getenv(); + register char *p; + + p = getenv("USER"); + if (p == NULL || p[0] == '\0') + p = getlogin(); + return (p); +# endif UIDUSER +}