⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rcsfnms.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	do {	    if ((xl = suffixlen(x))) {		if (xl <= nl  &&  memcmp(p = nz-xl, x, xl) == 0)		    return p;	    } else {		dl = dirlen(name);		if (		    rcsdirlen < dl  &&		    !memcmp(p = name+(dl-=rcsdirlen+1), rcsdir, rcsdirlen) &&		    (!dl  ||  isSLASH(*--p))		)		    return nz;	    }	    x += xl;	} while (*x++);	return 0;}	/*ARGSUSED*/ RILE *rcsreadopen(RCSname, status, mustread)	struct buf *RCSname;	struct stat *status;	int mustread;/* Open RCSNAME for reading and yield its FILE* descriptor. * If successful, set *STATUS to its status. * Pass this routine to pairfilenames() for read-only access to the file.  */{	return Iopen(RCSname->string, FOPEN_R, status);}	static intfinopen(rcsopen, mustread)	/* jlf RILE *(*rcsopen)P((struct buf*,struct stat*,int)); */	RILE *(*rcsopen)();	int mustread;/* * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. * Set finptr to the result and yield true if successful. * RCSb holds the file's name. * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. * Yield true if successful or if an unusual failure. */{	int interesting, preferold;	/*	 * We prefer an old name to that of a nonexisting new RCS file,	 * unless we tried locking the old name and failed.	 */	preferold  =  RCSbuf.string[0] && (mustread||frewrite);	finptr = (*rcsopen)(&RCSb, &RCSstat, mustread);	interesting = finptr || errno!=ENOENT;	if (interesting || !preferold) {		/* Use the new name.  */		RCSerrno = errno;		bufscpy(&RCSbuf, RCSb.string);	}	return interesting;}	static intfin2open(d, dlen, base, baselen, x, xlen, rcsopen, mustread)	char const *d, *base, *x;	size_t dlen, baselen, xlen;	/* jlf RILE *(*rcsopen)P((struct buf*,struct stat*,int)); */	RILE *(*rcsopen)();	int mustread;/* * D is a directory name with length DLEN (including trailing slash). * BASE is a filename with length BASELEN. * X is an RCS filename suffix with length XLEN. * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. * Yield true if successful. * Try dRCS/basex first; if that fails and x is nonempty, try dbasex. * Put these potential names in RCSb. * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. * Yield true if successful or if an unusual failure. */{	register char *p;	bufalloc(&RCSb, dlen + rcsdirlen + 1 + baselen + xlen + 1);	/* Try dRCS/basex.  */	VOID memcpy(p = RCSb.string, d, dlen);	VOID memcpy(p += dlen, rcsdir, rcsdirlen);	p += rcsdirlen;	*p++ = SLASH;	VOID memcpy(p, base, baselen);	VOID memcpy(p += baselen, x, xlen);	p[xlen] = 0;	if (xlen) {	    if (finopen(rcsopen, mustread))		return true;	    /* Try dbasex.  */	    /* Start from scratch, because finopen() may have changed RCSb.  */	    VOID memcpy(p = RCSb.string, d, dlen);	    VOID memcpy(p += dlen, base, baselen);	    VOID memcpy(p += baselen, x, xlen);	    p[xlen] = 0;	}	return finopen(rcsopen, mustread);}	intpairfilenames(argc, argv, rcsopen, mustread, quiet)	int argc;	char **argv;	/* jlf RILE *(*rcsopen)P((struct buf*,struct stat*,int)); */	RILE *(*rcsopen)();	int mustread, quiet;/* Function: Pairs the filenames pointed to by argv; argc indicates * how many there are. * Places a pointer to the RCS filename into RCSfilename, * and a pointer to the name of the working file into workfilename. * If both the workfilename and the RCS filename are given, and workstdout * is set, a warning is printed. * * If the RCS file exists, places its status into RCSstat. * * If the RCS file exists, it is RCSOPENed for reading, the file pointer * is placed into finptr, and the admin-node is read in; returns 1. * If the RCS file does not exist and MUSTREAD, * print an error unless QUIET and return 0. * Otherwise, initialize the admin node and return -1. * * 0 is returned on all errors, e.g. files that are not regular files. */{	static struct buf tempbuf;	register char *p, *arg, *RCS1;	char const *purefname, *pureRCSname, *x;	int paired;	size_t arglen, dlen, baselen, xlen;	if (!(arg = *argv)) return 0; /* already paired filename */	if (*arg == '-') {		error("%s option is ignored after file names", arg);		return 0;	}	purefname = basename(arg);	/* Allocate buffer temporary to hold the default paired file name. */	p = arg;	for (;;) {		switch (*p++) {		    /* Beware characters that cause havoc with ci -k. */		    case KDELIM:			error("RCS file name `%s' contains %c", arg, KDELIM);			return 0;		    case ' ': case '\n': case '\t':			error("RCS file name `%s' contains white space", arg);			return 0;		    default:			continue;		    case 0:			break;		}		break;	}	paired = false;        /* first check suffix to see whether it is an RCS file or not */	if ((x = rcssuffix(arg)))	{                /* RCS file name given*/		RCS1 = arg;		pureRCSname = purefname;		baselen = x - purefname;		if (		    1 < argc  &&		    !rcssuffix(workfilename = p = argv[1])  &&		    baselen <= (arglen = strlen(p))  &&		    ((p+=arglen-baselen) == workfilename  ||  isSLASH(p[-1])) &&		    memcmp(purefname, p, baselen) == 0		) {			argv[1] = 0;			paired = true;		} else {			bufscpy(&tempbuf, purefname);			workfilename = p = tempbuf.string;			p[baselen] = 0;		}        } else {                /* working file given; now try to find RCS file */		workfilename = arg;		baselen = p - purefname - 1;                /* derive RCS file name*/		if (		    1 < argc  &&		    (x = rcssuffix(RCS1 = argv[1]))  &&		    baselen  <=  x - RCS1  &&		    ((pureRCSname=x-baselen)==RCS1 || isSLASH(pureRCSname[-1])) &&		    memcmp(purefname, pureRCSname, baselen) == 0		) {			argv[1] = 0;			paired = true;		} else			pureRCSname = RCS1 = 0;        }        /* now we have a (tentative) RCS filename in RCS1 and workfilename  */        /* Second, try to find the right RCS file */        if (pureRCSname!=RCS1) {                /* a path for RCSfile is given; single RCS file to look for */		bufscpy(&RCSbuf, RCS1);		finptr = (*rcsopen)(&RCSbuf, &RCSstat, mustread);		RCSerrno = errno;        } else {		bufscpy(&RCSbuf, "");		if (RCS1)			/* RCS file name was given without path.  */			VOID fin2open(arg, (size_t)0, pureRCSname, baselen,				x, strlen(x), rcsopen, mustread			);		else {			/* No RCS file name was given.  */			/* Try each suffix in turn.  */			dlen = purefname-arg;			x = suffixes;			while (! fin2open(arg, dlen, purefname, baselen,					x, xlen=suffixlen(x), rcsopen, mustread			)) {				x += xlen;				if (!*x++)					break;			}		}        }	RCSfilename = p = RCSbuf.string;	if (finptr) {		if (!S_ISREG(RCSstat.st_mode)) {			error("%s isn't a regular file -- ignored", p);                        return 0;                }                Lexinit(); getadmin();	} else {		if (RCSerrno!=ENOENT || mustread || !frewrite) {			if (RCSerrno == EEXIST)				error("RCS file %s is in use", p);			else if (!quiet || RCSerrno!=ENOENT)				enerror(RCSerrno, p);			return 0;		}                InitAdmin();        };#	if LONG_NAMES_MAY_BE_SILENTLY_TRUNCATED	    if (filenametoolong(p)) {		error("RCS file name %s is too long", p);		return 0;	    }#	    ifndef NAME_MAX		/*		 * Check workfilename too, even though it cannot be longer,		 * because it may reside on a different filesystem.		 */		if (filenametoolong(workfilename)) {		    error("working file name %s is too long", workfilename);		    return 0;		}#	    endif#	endif	if (paired && workstdout)                warn("Option -p is set; ignoring output file %s",workfilename);	prevkeys = false;	return finptr ? 1 : -1;}	char const *getfullRCSname()/* Function: returns a pointer to the full path name of the RCS file. * Gets the working directory's name at most once. * Removes leading "../" and "./". */{	static char const *wdptr;	static struct buf rcsbuf, wdbuf;	static size_t pathlength;	register char const *realname;	register size_t parentdirlength;	register unsigned dotdotcounter;	register char *d;	register char const *wd;	if (ROOTPATH(RCSfilename)) {                return(RCSfilename);        } else {		if (!(wd = wdptr)) {		    /* Get working directory for the first time.  */		    if (!(d = cgetenv("PWD"))) {			bufalloc(&wdbuf, SIZEABLE_PATH + 1);#			if !has_getcwd && has_getwd			    d = getwd(wdbuf.string);#			else			    while (				    !(d = getcwd(wdbuf.string, wdbuf.size))				&&  errno==ERANGE			    )				bufalloc(&wdbuf, wdbuf.size<<1);#			endif			if (!d)			    efaterror("working directory");		    }		    parentdirlength = strlen(d);		    while (parentdirlength && isSLASH(d[parentdirlength-1])) {			d[--parentdirlength] = 0;                        /* Check needed because some getwd implementations */                        /* generate "/" for the root.                      */                    }		    wdptr = wd = d;		    pathlength = parentdirlength;                }                /*the following must be redone since RCSfilename may change*/		/* Find how many `../'s to remove from RCSfilename.  */                dotdotcounter =0;                realname = RCSfilename;		while (realname[0]=='.') {			if (isSLASH(realname[1])) {                            /* drop leading ./ */                            realname += 2;			} else if (realname[1]=='.' && isSLASH(realname[2])) {                            /* drop leading ../ and remember */                            dotdotcounter++;                            realname += 3;			} else			    break;                }		/* Now remove dotdotcounter trailing directories from wd. */		parentdirlength = pathlength;		while (dotdotcounter && parentdirlength) {                    /* move pointer backwards over trailing directory */		    if (isSLASH(wd[--parentdirlength])) {                        dotdotcounter--;                    }                }		/* build full path name */		bufalloc(&rcsbuf, parentdirlength+strlen(realname)+2);		d = rcsbuf.string;		VOID memcpy(d, wd, parentdirlength);		d += parentdirlength;		*d++ = SLASH;		VOID strcpy(d, realname);		return rcsbuf.string;        }}#ifndef isSLASH	intisSLASH(c)	int c;{	switch (c) {	    case SLASHes:		return true;	    default:		return false;	}}#endif#if !has_getcwd && !has_getwd	char *getcwd(path, size)	char *path;	size_t size;{	static char const usrbinpwd[] = "/usr/bin/pwd";#	define binpwd (usrbinpwd+4)	register FILE *fp;	register int c;	register char *p, *lim;	int closeerrno, closeerror, e, fd[2], readerror, toolong, wstatus;	pid_t child;#	if !has_waitpid		pid_t w;#	endif	if (!size) {		errno = EINVAL;		return 0;	}	if (pipe(fd) != 0)		return 0;	if (!(child = vfork())) {		if (			close(fd[0]) == 0 &&			(fd[1] == STDOUT_FILENO ||#				ifdef F_DUPFD					(VOID close(STDOUT_FILENO),					fcntl(fd[1], F_DUPFD, STDOUT_FILENO))#				else					dup2(fd[1], STDOUT_FILENO)#				endif				== STDOUT_FILENO &&				close(fd[1]) == 0			)		) {			VOID close(STDERR_FILENO);			VOID execl(binpwd, binpwd, (char *)0);			VOID execl(usrbinpwd, usrbinpwd, (char *)0);		}		_exit(EXIT_FAILURE);	}	e = errno;	closeerror = close(fd[1]);	closeerrno = errno;	fp = 0;	readerror = toolong = wstatus = 0;	p = path;	if (0 <= child) {		fp = fdopen(fd[0], "r");		e = errno;		if (fp) {			lim = p + size;			for (p = path;  ;  *p++ = c) {				if ((c=getc(fp)) < 0) {					if (feof(fp))						break;					if (ferror(fp)) {						readerror = 1;						e = errno;						break;					}				}				if (p == lim) {					toolong = 1;					break;				}			}		}#		if has_waitpid			if (waitpid(child, &wstatus, 0) < 0)				wstatus = 1;#		else			do {				if ((w = wait(&wstatus)) < 0) {					wstatus = 1;					break;				}			} while (w != child);#		endif	}	if (!fp) {		VOID close(fd[0]);		errno = e;		return 0;	}	if (fclose(fp) != 0)		return 0;	if (readerror) {		errno = e;		return 0;	}	if (closeerror) {		errno = closeerrno;		return 0;	}	if (toolong) {		errno = ERANGE;		return 0;	}	if (wstatus  ||  p == path  ||  *--p != '\n') {		errno = EACCES;		return 0;	}	*p = '\0';	return path;}#endif#ifdef PAIRTEST/* test program for pairfilenames() and getfullRCSname() */char const cmdid[] = "pair";main(argc, argv)int argc; char *argv[];{        int result;	int initflag;	quietflag = initflag = false;        while(--argc, ++argv, argc>=1 && ((*argv)[0] == '-')) {                switch ((*argv)[1]) {		case 'p':       workstdout = stdout;                                break;                case 'i':       initflag=true;                                break;                case 'q':       quietflag=true;                                break;                default:        error("unknown option: %s", *argv);                                break;                }        }        do {                RCSfilename=workfilename=nil;		result = pairfilenames(argc,argv,rcsreadopen,!initflag,quietflag);                if (result!=0) {		    diagnose("RCS file: %s; working file: %s\nFull RCS file name: %s\n",			     RCSfilename,workfilename,getfullRCSname()		    );                }                switch (result) {                        case 0: continue; /* already paired file */                        case 1: if (initflag) {                                    error("RCS file %s exists already",RCSfilename);                                } else {				    diagnose("RCS file %s exists\n",RCSfilename);                                }				Ifclose(finptr);                                break;			case -1:diagnose("RCS file doesn't exist\n");                                break;                }        } while (++argv, --argc>=1);}	exiting voidexiterr(){	dirtempunlink();	tempunlink();	_exit(EXIT_FAILURE);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -