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

📄 util.c

📁 早期freebsd实现
💻 C
字号:
#include "EXTERN.h"#include "common.h"#include "INTERN.h"#include "util.h"#include "backupfile.h"void my_exit();static char *private_strerror (errnum)     int errnum;{  extern char *sys_errlist[];  extern int sys_nerr;  if (errnum > 0 && errnum <= sys_nerr)    return sys_errlist[errnum];  return "Unknown system error";}#define strerror private_strerror/* Rename a file, copying it if necessary. */intmove_file(from,to)char *from, *to;{    char bakname[512];    Reg1 char *s;    Reg2 int i;    Reg3 int fromfd;    /* to stdout? */    if (strEQ(to, "-")) {#ifdef DEBUGGING	if (debug & 4)	    say2("Moving %s to stdout.\n", from);#endif	fromfd = open(from, 0);	if (fromfd < 0)	    pfatal2("internal error, can't reopen %s", from);	while ((i=read(fromfd, buf, sizeof buf)) > 0)	    if (write(1, buf, i) != 1)		pfatal1("write failed");	Close(fromfd);	return 0;    }    if (origprae) {	Strcpy(bakname, origprae);	Strcat(bakname, to);    } else {#ifndef NODIR	char *backupname = find_backup_file_name(to);	if (backupname == (char *) 0)	    fatal1("out of memory\n");	Strcpy(bakname, backupname);	free(backupname);#else /* NODIR */	Strcpy(bakname, to);    	Strcat(bakname, simple_backup_suffix);#endif /* NODIR */    }    if (stat(to, &filestat) == 0) {	/* output file exists */	dev_t to_device = filestat.st_dev;	ino_t to_inode  = filestat.st_ino;	char *simplename = bakname;		for (s=bakname; *s; s++) {	    if (*s == '/')		simplename = s+1;	}	/* Find a backup name that is not the same file.	   Change the first lowercase char into uppercase;	   if that isn't sufficient, chop off the first char and try again.  */	while (stat(bakname, &filestat) == 0 &&		to_device == filestat.st_dev && to_inode == filestat.st_ino) {	    /* Skip initial non-lowercase chars.  */	    for (s=simplename; *s && !islower(*s); s++) ;	    if (*s)		*s = toupper(*s);	    else		Strcpy(simplename, simplename+1);	}	while (unlink(bakname) >= 0) ;	/* while() is for benefit of Eunice */#ifdef DEBUGGING	if (debug & 4)	    say3("Moving %s to %s.\n", to, bakname);#endif	if (link(to, bakname) < 0) {	    /* Maybe `to' is a symlink into a different file system.	       Copying replaces the symlink with a file; using rename	       would be better.  */	    Reg4 int tofd;	    Reg5 int bakfd;	    bakfd = creat(bakname, 0666);	    if (bakfd < 0) {		say4("Can't backup %s, output is in %s: %s\n", to, from,		     strerror(errno));		return -1;	    }	    tofd = open(to, 0);	    if (tofd < 0)		pfatal2("internal error, can't open %s", to);	    while ((i=read(tofd, buf, sizeof buf)) > 0)		if (write(bakfd, buf, i) != i)		    pfatal1("write failed");	    Close(tofd);	    Close(bakfd);	}	while (unlink(to) >= 0) ;    }#ifdef DEBUGGING    if (debug & 4)	say3("Moving %s to %s.\n", from, to);#endif    if (link(from, to) < 0) {		/* different file system? */	Reg4 int tofd;		tofd = creat(to, 0666);	if (tofd < 0) {	    say4("Can't create %s, output is in %s: %s\n",	      to, from, strerror(errno));	    return -1;	}	fromfd = open(from, 0);	if (fromfd < 0)	    pfatal2("internal error, can't reopen %s", from);	while ((i=read(fromfd, buf, sizeof buf)) > 0)	    if (write(tofd, buf, i) != i)		pfatal1("write failed");	Close(fromfd);	Close(tofd);    }    Unlink(from);    return 0;}/* Copy a file. */voidcopy_file(from,to)char *from, *to;{    Reg3 int tofd;    Reg2 int fromfd;    Reg1 int i;        tofd = creat(to, 0666);    if (tofd < 0)	pfatal2("can't create %s", to);    fromfd = open(from, 0);    if (fromfd < 0)	pfatal2("internal error, can't reopen %s", from);    while ((i=read(fromfd, buf, sizeof buf)) > 0)	if (write(tofd, buf, i) != i)	    pfatal2("write to %s failed", to);    Close(fromfd);    Close(tofd);}/* Allocate a unique area for a string. */char *savestr(s)Reg1 char *s;{    Reg3 char *rv;    Reg2 char *t;    if (!s)	s = "Oops";    t = s;    while (*t++);    rv = malloc((MEM) (t - s));    if (rv == Nullch) {	if (using_plan_a)	    out_of_mem = TRUE;	else	    fatal1("out of memory\n");    }    else {	t = rv;	while (*t++ = *s++);    }    return rv;}#if defined(lint) && defined(CANVARARG)/*VARARGS ARGSUSED*/say(pat) char *pat; { ; }/*VARARGS ARGSUSED*/fatal(pat) char *pat; { ; }/*VARARGS ARGSUSED*/pfatal(pat) char *pat; { ; }/*VARARGS ARGSUSED*/ask(pat) char *pat; { ; }#else/* Vanilla terminal output (buffered). */voidsay(pat,arg1,arg2,arg3)char *pat;long arg1,arg2,arg3;{    fprintf(stderr, pat, arg1, arg2, arg3);    Fflush(stderr);}/* Terminal output, pun intended. */void				/* very void */fatal(pat,arg1,arg2,arg3)char *pat;long arg1,arg2,arg3;{    fprintf(stderr, "patch: **** ");    fprintf(stderr, pat, arg1, arg2, arg3);    my_exit(1);}/* Say something from patch, something from the system, then silence . . . */void				/* very void */pfatal(pat,arg1,arg2,arg3)char *pat;long arg1,arg2,arg3;{    int errnum = errno;    fprintf(stderr, "patch: **** ");    fprintf(stderr, pat, arg1, arg2, arg3);    fprintf(stderr, ": %s\n", strerror(errnum));    my_exit(1);}/* Get a response from the user, somehow or other. */voidask(pat,arg1,arg2,arg3)char *pat;long arg1,arg2,arg3;{    int ttyfd;    int r;    bool tty2 = isatty(2);    Sprintf(buf, pat, arg1, arg2, arg3);    Fflush(stderr);    write(2, buf, strlen(buf));    if (tty2) {				/* might be redirected to a file */	r = read(2, buf, sizeof buf);    }    else if (isatty(1)) {		/* this may be new file output */	Fflush(stdout);	write(1, buf, strlen(buf));	r = read(1, buf, sizeof buf);    }    else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {					/* might be deleted or unwriteable */	write(ttyfd, buf, strlen(buf));	r = read(ttyfd, buf, sizeof buf);	Close(ttyfd);    }    else if (isatty(0)) {		/* this is probably patch input */	Fflush(stdin);	write(0, buf, strlen(buf));	r = read(0, buf, sizeof buf);    }    else {				/* no terminal at all--default it */	buf[0] = '\n';	r = 1;    }    if (r <= 0)	buf[0] = 0;    else	buf[r] = '\0';    if (!tty2)	say1(buf);}#endif /* lint *//* How to handle certain events when not in a critical region. */voidset_signals(reset)int reset;{#ifndef lint#ifdef VOIDSIG    static void (*hupval)(),(*intval)();#else    static int (*hupval)(),(*intval)();#endif    if (!reset) {	hupval = signal(SIGHUP, SIG_IGN);	if (hupval != SIG_IGN)#ifdef VOIDSIG	    hupval = my_exit;#else	    hupval = (int(*)())my_exit;#endif	intval = signal(SIGINT, SIG_IGN);	if (intval != SIG_IGN)#ifdef VOIDSIG	    intval = my_exit;#else	    intval = (int(*)())my_exit;#endif    }    Signal(SIGHUP, hupval);    Signal(SIGINT, intval);#endif}/* How to handle certain events when in a critical region. */voidignore_signals(){#ifndef lint    Signal(SIGHUP, SIG_IGN);    Signal(SIGINT, SIG_IGN);#endif}/* Make sure we'll have the directories to create a file.   If `striplast' is TRUE, ignore the last element of `filename'.  */voidmakedirs(filename,striplast)Reg1 char *filename;bool striplast;{    char tmpbuf[256];    Reg2 char *s = tmpbuf;    char *dirv[20];		/* Point to the NULs between elements.  */    Reg3 int i;    Reg4 int dirvp = 0;		/* Number of finished entries in dirv. */    /* Copy `filename' into `tmpbuf' with a NUL instead of a slash       between the directories.  */    while (*filename) {	if (*filename == '/') {	    filename++;	    dirv[dirvp++] = s;	    *s++ = '\0';	}	else {	    *s++ = *filename++;	}    }    *s = '\0';    dirv[dirvp] = s;    if (striplast)	dirvp--;    if (dirvp < 0)	return;    strcpy(buf, "mkdir");    s = buf;    for (i=0; i<=dirvp; i++) {	struct stat sbuf;	if (stat(tmpbuf, &sbuf) && errno == ENOENT) {	    while (*s) s++;	    *s++ = ' ';	    strcpy(s, tmpbuf);	}	*dirv[i] = '/';    }    if (s != buf)	system(buf);}/* Make filenames more reasonable. */char *fetchname(at,strip_leading,assume_exists)char *at;int strip_leading;int assume_exists;{    char *fullname;    char *name;    Reg1 char *t;    char tmpbuf[200];    int sleading = strip_leading;    if (!at)	return Nullch;    while (isspace(*at))	at++;#ifdef DEBUGGING    if (debug & 128)	say4("fetchname %s %d %d\n",at,strip_leading,assume_exists);#endif    if (strnEQ(at, "/dev/null", 9))	/* so files can be created by diffing */	return Nullch;			/*   against /dev/null. */    name = fullname = t = savestr(at);    /* Strip off up to `sleading' leading slashes and null terminate.  */    for (; *t && !isspace(*t); t++)	if (*t == '/')	    if (--sleading >= 0)		name = t+1;    *t = '\0';    /* If no -p option was given (957 is the default value!),       we were given a relative pathname,       and the leading directories that we just stripped off all exist,       put them back on.  */    if (strip_leading == 957 && name != fullname && *fullname != '/') {	name[-1] = '\0';	if (stat(fullname, &filestat) == 0 && S_ISDIR (filestat.st_mode)) {	    name[-1] = '/';	    name=fullname;	}    }    name = savestr(name);    free(fullname);    if (stat(name, &filestat) && !assume_exists) {	char *filebase = basename(name);	int pathlen = filebase - name;	/* Put any leading path into `tmpbuf'.  */	strncpy(tmpbuf, name, pathlen);#define try(f, a1, a2) (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)	if (   try("RCS/%s%s", filebase, RCSSUFFIX)	    || try("RCS/%s"  , filebase,         0)	    || try(    "%s%s", filebase, RCSSUFFIX)	    || try("SCCS/%s%s", SCCSPREFIX, filebase)	    || try(     "%s%s", SCCSPREFIX, filebase))	  return name;	free(name);	name = Nullch;    }    return name;}

⌨️ 快捷键说明

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