sccs.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,630 行 · 第 1/3 页
C
1,630 行
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) { printf("%s\n", basefile); break; } printf("%12s: being edited: ", basefile); putpfent(pf, stdout); } fclose(pfp); } /* the s. file exists and no p. file exists -- unlink the g-file */ if (mode == CLEANC && !gotpfent) { char unlinkbuf[FBUFSIZ]; gstrcpy(unlinkbuf, &dir->d_name[2], sizeof(unlinkbuf)); unlink(unlinkbuf); } } /* cleanup & report results */ closedir(dirfd); if (!gotedit && mode == INFOC) { 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);}/*** ISBRANCH -- is the SID a branch?**** Parameters:** sid -- the sid to check.**** Returns:** TRUE if the sid represents a branch.** FALSE otherwise.**** Side Effects:** none.*/isbranch(sid) char *sid;{ register char *p; int dots; dots = 0; for (p = sid; *p != '\0'; p++) { if (*p == '.') dots++; if (dots > 1) return (TRUE); } return (FALSE);}/*** UNEDIT -- unedit a file**** Checks to see that the current user is actually editting** the file and arranges that s/he is not editting it.**** Parameters:** fn -- the name of the file to be unedited.**** Returns:** TRUE -- if the file was successfully unedited.** FALSE -- if the file was not unedited for some** reason.**** Side Effects:** fn is removed** entries are removed from pfile.*/boolunedit(fn) char *fn;{ register FILE *pfp; char *pfn; static char tfn[] = "/tmp/sccsXXXXX"; FILE *tfp; register char *q; bool delete = FALSE; bool others = FALSE; char *myname; extern char *username(); struct pfile *pent; extern struct pfile *getpfent(); char buf[PFILELG]; extern char *makefile(); extern int errno; int err; /* make "s." filename & find the trailing component */ pfn = makefile(fn); if (pfn == NULL) return (FALSE); q = rindex(pfn, '/'); if (q == NULL) q = &pfn[-1]; if (q[1] != 's' || q[2] != '.') { usrerr("bad file name \"%s\" (sc13)", fn); return (FALSE); } /* turn "s." into "p." & try to open it */ *++q = 'p'; pfp = fopen(pfn, "r"); if (pfp == NULL) { printf("SCCS: %12s not being edited (sc14)\n", fn); return (FALSE); } /* create temp file for editing p-file */ mktemp(tfn); tfp = fopen(tfn, "w"); if (tfp == NULL) { usrerr("cannot create \"%s\" (sc15)", tfn); exit(EX_OSERR); } /* figure out who I am */ myname = username(); /* ** Copy p-file to temp file, doing deletions as needed. */ while ((pent = getpfent(pfp)) != NULL) { if (strcmp(pent->p_user, myname) == 0) { /* a match */ delete++; } else { /* output it again */ putpfent(pent, tfp); others++; } } /* do final cleanup */ if (others) { /* copy it back (perhaps it should be linked?) */ if (freopen(tfn, "r", tfp) == NULL) { syserr("cannot reopen \"%s\" (sc16)", tfn); exit(EX_OSERR); } if (freopen(pfn, "w", pfp) == NULL) { usrerr("cannot create \"%s\" (sc15)", pfn); return (FALSE); } while (fgets(buf, sizeof buf, tfp) != NULL) fputs(buf, pfp); } else { /* it's empty -- remove it */ unlink(pfn); } fclose(tfp); fclose(pfp); unlink(tfn); /* * if g-file present, * actually remove the g-file, by first setting the UID to the real * user (the file's owner), unlinking the file, and finally resetting * the UID to the effective user (sccs). */ if (delete) { return (TRUE); } else { printf("SCCS: %12s not being edited by you (sc19)\n", fn); return (FALSE); }}/*** RMGFILE -- This routine will unlink a g-file. It assumes that the UID** has been set to the real user.**** Parameters:** fn -- pointer to the g-file name**** Returns:** 0 -- g-file unlinked** 1 -- g-file could not be unlinked**** Side Effects:** none*/rmgfile(fn) char *fn;{ if (unlink(tail(fn)) < 0) return (FALSE); return(TRUE);}/*** DODIFF -- diff an s-file against a g-file**** Parameters:** getv -- argv for the 'get' command.** gfile -- name of the g-file to diff against.**** Returns:** Result of get.**** Side Effects:** none.*/dodiff(getv, gfile) char **getv; char *gfile;{ int pipev[2]; int rval; register int i; register int pid; auto int st; extern int errno; void (*osig)(); printf("\n------- %s -------\n", gfile); fflush(stdout); /* create context for diff to run in */ if (pipe(pipev) < 0) { syserr("dodiff: pipe failed (sc20)"); exit(EX_OSERR); } if ((pid = fork()) < 0) { syserr("dodiff: fork failed (sc8)"); exit(EX_OSERR); } else if (pid > 0) { /* in parent; run get */ OutFile = pipev[1]; close(pipev[0]); 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; signal(SIGINT, osig); /* ignore result of diff */ } else { /* in child, run diff */ if (close(pipev[1]) < 0 || close(0) < 0 || dup(pipev[0]) != 0 || close(pipev[0]) < 0) { syserr("dodiff: magic failed (sc21)"); exit(EX_OSERR); } command(&getv[1], FALSE, "-diff:elsfhbC"); } return (rval);}/*** TAIL -- return tail of filename.**** Parameters:** fn -- the filename.**** Returns:** a pointer to the tail of the filename; e.g., given** "cmd/ls.c", "ls.c" is returned.**** Side Effects:** none.*/char *tail(fn) register char *fn;{ register char *p; for (p = fn; *p != 0; p++) if (*p == '/' && p[1] != '\0' && p[1] != '/') fn = &p[1]; return (fn);}/*** GETPFENT -- get an entry from the p-file**** Parameters:** pfp -- p-file file pointer**** Returns:** pointer to p-file struct for next entry** NULL on EOF or error**** Side Effects:** Each call wipes out results of previous call.*/struct pfile *getpfent(pfp) FILE *pfp;{ static struct pfile ent; static char buf[PFILELG]; register char *p; extern char *nextfield(); if (fgets(buf, sizeof buf, pfp) == NULL) return (NULL); ent.p_osid = p = buf; ent.p_nsid = p = nextfield(p); ent.p_user = p = nextfield(p); ent.p_date = p = nextfield(p); ent.p_time = p = nextfield(p); ent.p_aux = p = nextfield(p); return (&ent);}char *nextfield(p) register char *p;{ if (p == NULL || *p == '\0') return (NULL); while (*p != ' ' && *p != '\n' && *p != '\0') p++; if (*p == '\n' || *p == '\0') { *p = '\0'; return (NULL); } *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**** Parameters:** f -- format string.** p1-p3 -- parameters to a printf.**** Returns:** -1**** Side Effects:** none.*//*VARARGS1*/usrerr(f, p1, p2, p3) char *f;{ fprintf(stderr, "\n%s: ", MyName); fprintf(stderr, f, p1, p2, p3); fprintf(stderr, "\n"); return (-1);}/*** SYSERR -- print system-generated error.**** Parameters:** f -- format string to a printf.** p1, p2, p3 -- parameters to f.**** Returns:** never.**** Side Effects:** none.*//*VARARGS1*/syserr(f, p1, p2, p3) char *f;{ extern int errno; fprintf(stderr, "\n%s SYSERR: ", MyName); fprintf(stderr, f, p1, p2, p3); fprintf(stderr, "\n"); if (errno == 0) exit(EX_SOFTWARE); else { perror(NULL); 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}/*** Guarded string manipulation routines; the last argument** is the length of the buffer into which the strcpy or strcat** is to be done.*/char *gstrcat(to, from, length) char *to, *from; int length;{ if (strlen(from) + strlen(to) >= length) { gstrbotch(to, from); } return(strcat(to, from));}char *gstrncat(to, from, n, length) char *to, *from; int n; int length;{ if (n + strlen(to) >= length) { gstrbotch(to, from); } return(strncat(to, from, n));}char *gstrcpy(to, from, length) char *to, *from; int length;{ if (strlen(from) >= length) { gstrbotch(from, (char *)0); } return(strcpy(to, from));}gstrbotch(str1, str2) char *str1, *str2;{ usrerr("Filename(s) too long: %s %s (sc22)", str1, str2);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?