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

📄 recover.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}private char **scanvec(args, str)register char	**args,		*str;{	while (*args) {		if (strcmp(*args, str) == 0)			return args;		args += 1;	}	return NULL;}private voidread_rec(recptr)struct rec_entry	*recptr;{	if (fread((UnivPtr) recptr, sizeof *recptr, (size_t)1, ptrs_fp) != 1)		fprintf(stderr, "recover: cannot read record.\n");}private voidseekto(which)int	which;{	long	offset;	int	i;	offset = sizeof (Header) + (Header.Nbuffers * sizeof (struct rec_entry));	for (i = 1; i < which; i++)		offset += buflist[i]->r_nlines * sizeof (daddr);	fseek(ptrs_fp, offset, L_SET);}private voidmakblist(){	int	i;	fseek(ptrs_fp, (long) sizeof (Header), L_SET);	for (i = 1; i <= Header.Nbuffers; i++) {		if (buflist[i] == NULL)			buflist[i] = (struct rec_entry *) malloc (sizeof (struct rec_entry));		read_rec(buflist[i]);	}	while (buflist[i]) {		free((UnivPtr) buflist[i]);		buflist[i] = NULL;		i += 1;	}}private daddrgetaddr(fp)register FILE	*fp;{	register int	nchars = sizeof (daddr);	daddr	addr;	register char	*cp = (char *) &addr;	while (--nchars >= 0)		*cp++ = getc(fp);	return addr;}private voiddump_file(which, out)int	which;FILE	*out;{	register int	nlines;	register daddr	addr;	char	buf[JBUFSIZ];	seekto(which);	nlines = buflist[which]->r_nlines;	Nchars = Nlines = 0L;	while (--nlines >= 0) {		addr = getaddr(ptrs_fp);		getline(addr, buf);		Nlines += 1;		Nchars += 1 + strlen(buf);		fputs(buf, out);		if (nlines > 0)			fputc('\n', out);	}}/* List all the buffers. */private voidlist(){	int	i;	for (i = 1; i <= Header.Nbuffers; i++)		printf("%d) buffer %s  \"%s\" (%d lines)\n", i,			buflist[i]->r_bname,			buflist[i]->r_fname,			buflist[i]->r_nlines);}private void	ask_del proto((char *prompt, struct file_pair *fp));private intdoit(fp)struct file_pair	*fp;{	char	answer[30];	char	*datafile = fp->file_data,		*pntrfile = fp->file_rec;	ptrs_fp = fopen(pntrfile, "r");	if (ptrs_fp == NULL) {		if (Verbose)			fprintf(stderr, "recover: cannot read rec file (%s).\n", pntrfile);		return 0;	}	fread((UnivPtr) &Header, sizeof Header, (size_t)1, ptrs_fp);	if (Header.Uid != UserID)		return 0;	/* Don't ask about JOVE's that are still running ... */#ifdef	KILL0	if (kill(Header.Pid, 0) == 0)		return 0;#endif	/* KILL0 */	if (Header.Nbuffers == 0) {		printf("There are no modified buffers in %s; should I delete the tmp file?", pntrfile);		ask_del(" ", fp);		return 1;	}	if (Header.Nbuffers < 0) {		fprintf(stderr, "recover: %s doesn't look like a jove file.\n", pntrfile);		ask_del("Should I delete it? ", fp);		return 1;	/* We'll, we sort of found something. */	}	printf("Found %d buffer%s last updated: %s",		Header.Nbuffers,		Header.Nbuffers != 1 ? "s" : "",		ctime(&Header.UpdTime));	data_fd = open(datafile, 0);	if (data_fd == -1) {		fprintf(stderr, "recover: but I can't read the data file (%s).\n", datafile);		ask_del("Should I delete the tmp files? ", fp);		return 1;	}	makblist();	list();	for (;;) {		tellme("(Type '?' for options): ", answer);		switch (answer[0]) {		case '\0':			continue;		case '?':			options();			break;		case 'l':			list();			break;		case 'p':			get(getsrc(), tty);			break;		case 'q':			ask_del("Shall I delete the tmp files? ", fp);			return 1;		case 'g':		    {	/* So it asks for src first. */			char	*dest;			struct rec_entry	**src;			if ((src = getsrc()) == NULL)				break;			dest = getdest();			get(src, dest);			break;		    }		case 'r':			restore();			break;		default:			printf("I don't know how to \"%s\"!\n", answer);			break;		}	}}private void	del_files proto((struct file_pair *fp));private voidask_del(prompt, fp)char	*prompt;struct file_pair	*fp;{	char	yorn[20];	tellme(prompt, yorn);	if (yorn[0] == 'y')		del_files(fp);}private voiddel_files(fp)struct file_pair	*fp;{	(void) unlink(fp->file_data);	(void) unlink(fp->file_rec);}private voidMailUser(rec)struct rec_head *rec;{#ifdef	SYSV	struct utsname mach;#else	char mach[BUFSIZ];#endif	char mail_cmd[BUFSIZ];	char *last_update;	char *buf_string;	FILE *mail_pipe;	struct passwd *pw;	if ((pw = getpwuid(rec->Uid))== NULL)		return;#ifdef	SYSV	if (uname(&mach) < 0)		strcpy(mach.sysname, "unknown");#else	{#ifndef BSD386		extern int	gethostname proto((const char *, size_t));#endif		gethostname(mach, sizeof(mach));	}#endif	last_update = ctime(&(rec->UpdTime));	/* Start up mail */	sprintf(mail_cmd, "/bin/mail %s", pw->pw_name);	setuid(getuid());	if ((mail_pipe = popen(mail_cmd, "w")) == NULL)		return;	setbuf(mail_pipe, mail_cmd);	/* Let's be grammatically correct! */	if (rec->Nbuffers == 1)		buf_string = "buffer";	else		buf_string = "buffers";	fprintf(mail_pipe, "Subject: System crash\n");	fprintf(mail_pipe, " \n");	fprintf(mail_pipe, "Jove saved %d %s when the system \"%s\"\n",	 rec->Nbuffers, buf_string,#ifdef	SYSV	 mach.sysname#else	 mach#endif	 );	fprintf(mail_pipe, "crashed on %s\n\n", last_update);	fprintf(mail_pipe, "You can retrieve the %s using Jove's -r\n",	 buf_string);	fprintf(mail_pipe, "(recover option) i.e. give the command.\n");	fprintf(mail_pipe, "\tjove -r\n");	fprintf(mail_pipe, "See the Jove manual for more details\n");	pclose(mail_pipe);}private voidsavetmps(){	struct file_pair	*fp;	union wait	status;	int	pid,		fd;	struct rec_head		header;	char	buf[BUFSIZ];	char	*fname;	struct stat		stbuf;	if (strcmp(TMP_DIR, REC_DIR) == 0)		return;		/* Files are moved to the same place. */	get_files(TMP_DIR);	for (fp = First; fp != NULL; fp = fp->file_next) {		stat(fp->file_data, &stbuf);		switch (pid = fork()) {		case -1:			fprintf(stderr, "recover: can't fork\n!");			exit(-1);			/*NOTREACHED*/		case 0:			fprintf(stderr, "Recovering: %s, %s\n", fp->file_data,			 fp->file_rec);			if ((fd = open(fp->file_rec, 0)) != -1) {				if ((read(fd, (UnivPtr) &header, sizeof header) != sizeof header)) {					close(fd);					return;				} else					close(fd);			}			MailUser(&header);			execl("/bin/mv", "mv", fp->file_data, fp->file_rec,				  REC_DIR, (char *)NULL);			fprintf(stderr, "recover: cannot execl /bin/mv.\n");			exit(-1);			/*NOTREACHED*/		default:			do ; while (wait(&status) != pid);			if (status.w_status != 0)				fprintf(stderr, "recover: non-zero status (%d) returned from copy.\n", status.w_status);			fname = fp->file_data + strlen(TMP_DIR);			strcpy(buf, REC_DIR);			strcat(buf, fname);			if (chown(buf, (int) stbuf.st_uid, (int) stbuf.st_gid) != 0)				perror("recover: chown failed.");			fname = fp->file_rec + strlen(TMP_DIR);			strcpy(buf, REC_DIR);			strcat(buf, fname);			if (chown(buf, (int) stbuf.st_uid, (int) stbuf.st_gid) != 0)				perror("recover: chown failed.");		}	}}private intlookup(dir)char	*dir;{	struct file_pair	*fp;	int	nfound = 0;	printf("Checking %s ...\n", dir);	Directory = dir;	get_files(dir);	for (fp = First; fp != NULL; fp = fp->file_next) {		nfound += doit(fp);		if (ptrs_fp)			(void) fclose(ptrs_fp);		if (data_fd > 0)			(void) close(data_fd);	}	return nfound;}intmain(argc, argv)int	argc;char	*argv[];{	int	nfound;	char	**argvp;	char	*tmp_dir;	UserID = getuid();	if (scanvec(argv, "-help")) {		printf("recover: usage: recover [-d directory] [-syscrash]\n");		printf("Use \"jove -r\" after JOVE has died for some\n");		printf("unknown reason.\n\n");		printf("Use \"%s -syscrash\"\n", Recover);		printf("when the system is in the process of rebooting.");		printf("This is done automatically at reboot time\n");		printf("and so most of you don't have to worry about that.\n\n");		printf("Use \"recover -d directory\" when the tmp files are store\n");		printf("in DIRECTORY instead of the default one (/tmp).\n");		exit(0);	}	if (scanvec(argv, "-v"))		Verbose = YES;	if (scanvec(argv, "-syscrash")) {		printf("Recovering jove files ... ");		savetmps();		printf("Done.\n");		exit(0);	}	if ((argvp = scanvec(argv, "-uid")) != NULL)		UserID = atoi(argvp[1]);	if ((argvp = scanvec(argv, "-d")) != NULL)		tmp_dir = argvp[1];	else		tmp_dir = TmpFilePath;	/* Check default directory */	nfound = lookup(tmp_dir);	/* Check whether anything was saved when system died? */	if (strcmp(tmp_dir, REC_DIR) != 0)		nfound += lookup(REC_DIR);	if (nfound == 0)		printf("There's nothing to recover.\n");	return 0;}

⌨️ 快捷键说明

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