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

📄 rcsutil.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#else	static void  setup_catchsig()  {	register i;	for (i=SIGS; 0<=--i; )		if (		    signal(sig[i], SIG_IGN) != SIG_IGN  &&		    signal(sig[i], catchsig) != SIG_IGN		)			faterror("signal catcher failure");  }#endif#endif	voidcatchints(){	static int catching_ints;	if (!catching_ints) {		catching_ints = true;		setup_catchsig();	}}#endif /* has_signal */	voidfastcopy(inf,outf)	register RILE *inf;	FILE *outf;/* Function: copies the remainder of file inf to outf. */{#if large_memory#	if has_mmap	    awrite((char const*)inf->ptr, (size_t)(inf->lim - inf->ptr), outf);	    inf->ptr = inf->lim;#	else	    for (;;) {		awrite((char const*)inf->ptr, (size_t)(inf->readlim - inf->ptr), outf);		inf->ptr = inf->readlim;		if (inf->ptr == inf->lim)		    break;		VOID Igetmore(inf);	    }#	endif#else	char buf[BUFSIZ*8];	register fread_type rcount;        /*now read the rest of the file in blocks*/	while (!feof(inf)) {		if (!(rcount = Fread(buf,sizeof(*buf),sizeof(buf),inf))) {			testIerror(inf);			return;		}		awrite(buf, (size_t)rcount, outf);        }#endif}#ifndef SSIZE_MAX /* This does not work in #ifs, but it's good enough for us.  */ /* Underestimating SSIZE_MAX may slow us down, but it won't break us.  */#	define SSIZE_MAX ((unsigned)-1 >> 1)#endif	voidawrite(buf, chars, f)	char const *buf;	size_t chars;	FILE *f;{	/* Posix 1003.1-1990 ssize_t hack */	while (SSIZE_MAX < chars) {		if (Fwrite(buf, sizeof(*buf), SSIZE_MAX, f)  !=  SSIZE_MAX)			Oerror();		buf += SSIZE_MAX;		chars -= SSIZE_MAX;	}	if (Fwrite(buf, sizeof(*buf), chars, f)  !=  chars)		Oerror();}	static intmovefd(old, new)	int old, new;{	if (old < 0  ||  old == new)		return old;#	ifdef F_DUPFD		new = fcntl(old, F_DUPFD, new);#	else		new = dup2(old, new);#	endif	return close(old)==0 ? new : -1;}	static intfdreopen(fd, file, flags)	int fd;	char const *file;	int flags;{	int newfd;	VOID close(fd);	newfd =#if !open_can_creat		flags&O_CREAT ? creat(file, S_IRUSR|S_IWUSR) :#endif		open(file, flags, S_IRUSR|S_IWUSR);	return movefd(newfd, fd);}#if !has_spawn	static voidtryopen(fd,file,flags)	int fd, flags;	char const *file;{	if (file  &&  fdreopen(fd,file,flags) != fd)		efaterror(file);}#else	static inttryopen(fd,file,flags)	int fd, flags;	char const *file;{	int newfd = -1;	if (file  &&  ((newfd=dup(fd)) < 0  ||  fdreopen(fd,file,flags) != fd))		efaterror(file);	return newfd;}	static voidredirect(old, new)	int old, new;{	if (0 <= old   &&   (close(new) != 0  ||  movefd(old,new) < 0))		efaterror("spawn I/O redirection");}#endif#if !has_fork && !has_spawn	static voidbufargcat(b, c, s)	register struct buf *b;	int c;	register char const *s;/* Append to B a copy of C, plus a quoted copy of S.  */{	register char *p;	register char const *t;	size_t bl, sl;	for (t=s, sl=0;  *t;  )		sl  +=  3*(*t++=='\'') + 1;	bl = strlen(b->string);	bufrealloc(b, bl + sl + 4);	p = b->string + bl;	*p++ = c;	*p++ = '\'';	while (*s) {		if (*s == '\'') {			*p++ = '\'';			*p++ = '\\';			*p++ = '\'';		}		*p++ = *s++;	}	*p++ = '\'';	*p = 0;}#endif/** Run a command specified by the strings in 'inoutargs'.* inoutargs[0], if nonnil, is the name of the input file.* inoutargs[1], if nonnil, is the name of the output file.* inoutargs[2..] form the command to be run.*/	intrunv(inoutargs)	char const **inoutargs;{	register char const **p;	int wstatus;	oflush();	eflush();    {#if has_spawn	int in, out;	p = inoutargs;	in = tryopen(STDIN_FILENO, *p++, O_BINARY|O_RDONLY);	out = tryopen(STDOUT_FILENO, *p++, O_BINARY|O_CREAT|O_TRUNC|O_WRONLY);	wstatus = spawn_RCS(0, *p, (char*const*)p);	if (wstatus == -1  &&  errno == ENOEXEC) {		*--p = RCS_SHELL;		wstatus = spawnv(0, *p, (char*const*)p);	}	redirect(in, STDIN_FILENO);	redirect(out, STDOUT_FILENO);#else#if has_fork	pid_t pid;#	if !has_waitpid		pid_t w;#	endif	if (!(pid = vfork())) {		p = inoutargs;		tryopen(STDIN_FILENO, *p++, O_BINARY|O_RDONLY);		tryopen(STDOUT_FILENO, *p++, O_BINARY|O_CREAT|O_TRUNC|O_WRONLY);		VOID exec_RCS(*p, (char*const*)p);		if (errno == ENOEXEC) {			*--p = RCS_SHELL;			VOID execv(*p, (char*const*)p);		}		VOID write(STDERR_FILENO, *p, strlen(*p));		VOID write(STDERR_FILENO, ": not found\n", 12);		_exit(EXIT_TROUBLE);	}	if (pid < 0)		efaterror("fork");#	if has_waitpid		if (waitpid(pid, &wstatus, 0) < 0)			efaterror("waitpid");#	else		do {			if ((w = wait(&wstatus)) < 0)				efaterror("wait");		} while (w != pid);#	endif#else	static struct buf b;	/* Use system().  On many hosts system() discards signals.  Yuck!  */	p = inoutargs+2;	bufscpy(&b, *p);	while (*++p)		bufargcat(&b, ' ', *p);	if (inoutargs[0])		bufargcat(&b, '<', inoutargs[0]);	if (inoutargs[1])		bufargcat(&b, '>', inoutargs[1]);	wstatus = system(b.string);#endif#endif    }	if (!WIFEXITED(wstatus))		faterror("%s failed", inoutargs[2]);	return WEXITSTATUS(wstatus);}#define CARGSMAX 20/** Run a command.* The first two arguments are the input and output files (if nonnil);* the rest specify the command and its arguments.*/	int#if has_prototypesrun(char const *infile, char const *outfile, ...)#else	/*VARARGS2*/run(infile, outfile, va_alist)	char const *infile;	char const *outfile;	va_dcl#endif{	va_list ap;	char const *rgargs[CARGSMAX];	register i = 0;	rgargs[0] = infile;	rgargs[1] = outfile;	vararg_start(ap, outfile);	for (i = 2;  (rgargs[i++] = va_arg(ap, char const*));  )		if (CARGSMAX <= i)			faterror("too many command arguments");	va_end(ap);	return runv(rgargs);}	char const *date2str(date, datebuf)	char const date[datesize];	char datebuf[datesize];/** Format a user-readable form of the RCS format DATE into the buffer DATEBUF.* Yield DATEBUF.*/{	register char const *p = date;	while (*p++ != '.')		;	VOID sprintf(datebuf,		"19%.*s/%.2s/%.2s %.2s:%.2s:%s" +			(date[2]=='.' && VERSION(5)<=RCSversion  ?  0  :  2),		(int)(p-date-1), date,		p, p+3, p+6, p+9, p+12	);	return datebuf;}int RCSversion;	voidsetRCSversion(str)	char const *str;{	static int oldversion;	register char const *s = str + 2;	int v = VERSION_DEFAULT;	if (oldversion)		redefined('V');	oldversion = true;	if (*s) {		v = 0;		while (isdigit(*s))			v  =  10*v + *s++ - '0';		if (*s)			faterror("%s isn't a number", str);		if (v < VERSION_min  ||  VERSION_max < v)			faterror("%s out of range %d..%d", str, VERSION_min, VERSION_max);	}	RCSversion = VERSION(v);}	intgetRCSINIT(argc, argv, newargv)	int argc;	char **argv, ***newargv;{	register char *p, *q, **pp;	unsigned n;	if (!(q = cgetenv("RCSINIT")))		*newargv = argv;	else {		n = argc + 2;		/*		 * Count spaces in RCSINIT to allocate a new arg vector.		 * This is an upper bound, but it's OK even if too large.		 */		for (p = q;  ;  ) {			switch (*p++) {			    default:				continue;			    case ' ':			    case '\b': case '\f': case '\n':			    case '\r': case '\t': case '\v':				n++;				continue;			    case '\0':				break;			}			break;		}		*newargv = pp = tnalloc(char*, n);		*pp++ = *argv++; /* copy program name */		for (p = q;  ;  ) {			for (;;) {				switch (*q) {				    case '\0':					goto copyrest;				    case ' ':				    case '\b': case '\f': case '\n':				    case '\r': case '\t': case '\v':					q++;					continue;				}				break;			}			*pp++ = p;			++argc;			for (;;) {				switch ((*p++ = *q++)) {				    case '\0':					goto copyrest;				    case '\\':					if (!*q)						goto copyrest;					p[-1] = *q++;					continue;				    default:					continue;				    case ' ':				    case '\b': case '\f': case '\n':				    case '\r': case '\t': case '\v':					break;				}				break;			}			p[-1] = '\0';		}	    copyrest:		while ((*pp++ = *argv++))			;	}	return argc;}#define cacheid(E) static uid_t i; static int s; if (!s){ s=1; i=(E); } return i#if has_getuid	uid_t ruid() { cacheid(getuid()); }#endif#if has_setuid	uid_t euid() { cacheid(geteuid()); }#endif#if has_setuid/* * Setuid execution really works only with Posix 1003.1a Draft 5 seteuid(), * because it lets us switch back and forth between arbitrary users. * If seteuid() doesn't work, we fall back on setuid(), * which works if saved setuid is supported, * unless the real or effective user is root. * This area is such a mess that we always check switches at runtime. */	static voidset_uid_to(u)	uid_t u;/* Become user u.  */{	static int looping;	if (euid() == ruid())		return;#if (has_fork||has_spawn) && DIFF_ABSOLUTE	if (seteuid(u) != 0)		efaterror("setuid");#endif	if (geteuid() != u) {		if (looping)			return;		looping = true;		faterror("root setuid not supported" + (u?5:0));	}}static int stick_with_euid;	void/* Ignore all calls to seteid() and setrid().  */nosetid(){	stick_with_euid = true;}	voidseteid()/* Become effective user.  */{	if (!stick_with_euid)		set_uid_to(euid());}	voidsetrid()/* Become real user.  */{	if (!stick_with_euid)		set_uid_to(ruid());}#endif

⌨️ 快捷键说明

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