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 + -
显示快捷键?