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

📄 recover.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	SCR *sp;	EXF *ep;{	if (ep->db->sync(ep->db, R_RECNOSYNC)) {		F_CLR(ep, F_RCV_ON);		msgq(sp, M_ERR, "Automatic file backup failed: %s: %s",		    ep->rcv_path, strerror(errno));		return (1);	}	return (0);}/* * rcv_hup -- *	Recovery SIGHUP interrupt handler.  (Modem line dropped, or *	xterm window closed.) */voidrcv_hup(){	SCR *sp;	/*	 * Walk the lists of screens, sync'ing the files; only sync	 * each file once.  Send email to the user for each file saved.	 */	for (sp = __global_list->dq.cqh_first;	    sp != (void *)&__global_list->dq; sp = sp->q.cqe_next)		rcv_syncit(sp, 1);	for (sp = __global_list->hq.cqh_first;	    sp != (void *)&__global_list->hq; sp = sp->q.cqe_next)		rcv_syncit(sp, 1);	/*	 * Die with the proper exit status.  Don't bother using	 * sigaction(2) 'cause we want the default behavior.	 */	(void)signal(SIGHUP, SIG_DFL);	(void)kill(0, SIGHUP);	/* NOTREACHED */	exit (1);}/* * rcv_term -- *	Recovery SIGTERM interrupt handler.  (Reboot or halt is running.) */voidrcv_term(){	SCR *sp;	/*	 * Walk the lists of screens, sync'ing the files; only sync	 * each file once.	 */	for (sp = __global_list->dq.cqh_first;	    sp != (void *)&__global_list->dq; sp = sp->q.cqe_next)		rcv_syncit(sp, 0);	for (sp = __global_list->hq.cqh_first;	    sp != (void *)&__global_list->hq; sp = sp->q.cqe_next)		rcv_syncit(sp, 0);	/*	 * Die with the proper exit status.  Don't bother using	 * sigaction(2) 'cause we want the default behavior.	 */	(void)signal(SIGTERM, SIG_DFL);	(void)kill(0, SIGTERM);	/* NOTREACHED */	exit (1);}/* * rcv_syncit -- *	Sync the file, optionally send mail. */static voidrcv_syncit(sp, email)	SCR *sp;	int email;{	EXF *ep;	char comm[1024];	if ((ep = sp->ep) == NULL ||	    !F_ISSET(ep, F_MODIFIED) || !F_ISSET(ep, F_RCV_ON))		return;	(void)ep->db->sync(ep->db, R_RECNOSYNC);	F_SET(ep, F_RCV_NORM);	/*	 * !!!	 * If you need to port this to a system that doesn't have sendmail,	 * the -t flag being used causes sendmail to read the message for	 * the recipients instead of us specifying them some other way.	 */	if (email) {		(void)snprintf(comm, sizeof(comm),		    "%s -t < %s", _PATH_SENDMAIL, ep->rcv_mpath);		(void)system(comm);	}	(void)file_end(sp, ep, 1);}/* *	people making love *	never exactly the same *	just like a snowflake * * rcv_list -- *	List the files that can be recovered by this user. */intrcv_list(sp)	SCR *sp;{	struct dirent *dp;	struct stat sb;	DIR *dirp;	FILE *fp;	int found;	char *p, file[1024];	if (chdir(O_STR(sp, O_RECDIR)) || (dirp = opendir(".")) == NULL) {		(void)fprintf(stderr,		    "vi: %s: %s\n", O_STR(sp, O_RECDIR), strerror(errno));		return (1);	}	for (found = 0; (dp = readdir(dirp)) != NULL;) {		if (strncmp(dp->d_name, "recover.", 8))			continue;		/* If it's readable, it's recoverable. */		if ((fp = fopen(dp->d_name, "r")) == NULL)			continue;		/* If it's locked, it's live. */		if (flock(fileno(fp), LOCK_EX | LOCK_NB)) {			(void)fclose(fp);			continue;		}		/* Check the header, get the file name. */		if (fgets(file, sizeof(file), fp) == NULL ||		    strncmp(file, VI_FHEADER, sizeof(VI_FHEADER) - 1) ||		    (p = strchr(file, '\n')) == NULL) {			(void)fprintf(stderr,			    "vi: %s: malformed recovery file.\n", dp->d_name);			goto next;		}		*p = '\0';		/* Get the last modification time. */		if (fstat(fileno(fp), &sb)) {			(void)fprintf(stderr,			    "vi: %s: %s\n", dp->d_name, strerror(errno));			goto next;		}		/* Display. */		(void)printf("%s: %s",		    file + sizeof(VI_FHEADER) - 1, ctime(&sb.st_mtime));		found = 1;next:		(void)fclose(fp);	}	if (found == 0)		(void)printf("vi: no files to recover.\n");	(void)closedir(dirp);	return (0);}/* * rcv_read -- *	Start a recovered file as the file to edit. */intrcv_read(sp, name)	SCR *sp;	char *name;{	struct dirent *dp;	struct stat sb;	DIR *dirp;	FREF *frp;	FILE *fp, *sv_fp;	time_t rec_mtime;	int found, requested;	char *p, *t, *recp, *pathp;	char recpath[MAXPATHLEN], file[MAXPATHLEN], path[MAXPATHLEN];	if ((dirp = opendir(O_STR(sp, O_RECDIR))) == NULL) {		msgq(sp, M_ERR,		    "%s: %s", O_STR(sp, O_RECDIR), strerror(errno));		return (1);	}	sv_fp = NULL;	rec_mtime = 0;	recp = pathp = NULL;	for (found = requested = 0; (dp = readdir(dirp)) != NULL;) {		if (strncmp(dp->d_name, "recover.", 8))			continue;		/* If it's readable, it's recoverable. */		(void)snprintf(recpath, sizeof(recpath),		    "%s/%s", O_STR(sp, O_RECDIR), dp->d_name);		if ((fp = fopen(recpath, "r")) == NULL)			continue;		/* If it's locked, it's live. */		if (flock(fileno(fp), LOCK_EX | LOCK_NB)) {			(void)fclose(fp);			continue;		}		/* Check the headers. */		if (fgets(file, sizeof(file), fp) == NULL ||		    strncmp(file, VI_FHEADER, sizeof(VI_FHEADER) - 1) ||		    (p = strchr(file, '\n')) == NULL ||		    fgets(path, sizeof(path), fp) == NULL ||		    strncmp(path, VI_PHEADER, sizeof(VI_PHEADER) - 1) ||		    (t = strchr(path, '\n')) == NULL) {			msgq(sp, M_ERR,			    "%s: malformed recovery file.", recpath);			goto next;		}		++found;		*t = *p = '\0';		/* Get the last modification time. */		if (fstat(fileno(fp), &sb)) {			msgq(sp, M_ERR,			    "vi: %s: %s", dp->d_name, strerror(errno));			goto next;		}		/* Check the file name. */		if (strcmp(file + sizeof(VI_FHEADER) - 1, name))			goto next;		++requested;		/* If we've found more than one, take the most recent. */		if (recp == NULL || rec_mtime < sb.st_mtime) {			p = recp;			t = pathp;			if ((recp = strdup(recpath)) == NULL) {				msgq(sp, M_ERR,				    "vi: Error: %s.\n", strerror(errno));				recp = p;				goto next;			}			if ((pathp = strdup(path)) == NULL) {				msgq(sp, M_ERR,				    "vi: Error: %s.\n", strerror(errno));				FREE(recp, strlen(recp) + 1);				recp = p;				pathp = t;				goto next;			}			if (p != NULL) {				FREE(p, strlen(p) + 1);				FREE(t, strlen(t) + 1);			}			rec_mtime = sb.st_mtime;			if (sv_fp != NULL)				(void)fclose(sv_fp);			sv_fp = fp;		} elsenext:			(void)fclose(fp);	}	(void)closedir(dirp);	if (recp == NULL) {		msgq(sp, M_INFO,		    "No files named %s, owned by you, to edit.", name);		return (1);	}	if (found) {		if (requested > 1)			msgq(sp, M_INFO,		   "There are older versions of this file for you to recover.");		if (found > requested)			msgq(sp, M_INFO,			    "There are other files for you to recover.");	}	/* Create the FREF structure, start the btree file. */	if ((frp = file_add(sp, NULL, name, 0)) == NULL ||	    file_init(sp, frp, pathp + sizeof(VI_PHEADER) - 1, 0)) {		FREE(recp, strlen(recp) + 1);		FREE(pathp, strlen(pathp) + 1);		(void)fclose(sv_fp);		return (1);	}	/*	 * We keep an open lock on the file so that the recover option can	 * distinguish between files that are live and those that need to	 * be recovered.  The lock is already acquired, so just get a copy.	 */	if ((sp->ep->rcv_fd = dup(fileno(sv_fp))) != -1)		(void)fclose(sv_fp);	sp->ep->rcv_mpath = recp;	/* We believe the file is recoverable. */	F_SET(sp->ep, F_RCV_ON);	return (0);}

⌨️ 快捷键说明

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