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

📄 interactive.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1985, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)interactive.c	8.1 (Berkeley) 6/5/93";#endif /* not lint */#include <sys/param.h>#include <sys/time.h>#include <sys/stat.h>#include <ufs/ffs/fs.h>#include <ufs/ufs/dinode.h>#include <ufs/ufs/dir.h>#include <protocols/dumprestore.h>#include <setjmp.h>#include <glob.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "restore.h"#include "extern.h"#define round(a, b) (((a) + (b) - 1) / (b) * (b))/* * Things to handle interruptions. */static int runshell;static jmp_buf reset;static char *nextarg = NULL;/* * Structure and routines associated with listing directories. */struct afile {	ino_t	fnum;		/* inode number of file */	char	*fname;		/* file name */	short	len;		/* name length */	char	prefix;		/* prefix character */	char	postfix;	/* postfix character */};struct arglist {	int	freeglob;	/* glob structure needs to be freed */	int	argcnt;		/* next globbed argument to return */	glob_t	glob;		/* globbing information */	char	*cmd;		/* the current command */};static char	*copynext __P((char *, char *));static int	 fcmp __P((const void *, const void *));static void	 formatf __P((struct afile *, int));static void	 getcmd __P((char *, char *, char *, struct arglist *));struct dirent	*glob_readdir __P((RST_DIR *dirp));static int	 glob_stat __P((const char *, struct stat *));static void	 mkentry __P((struct direct *, struct afile *));static void	 printlist __P((char *, char *));/* * Read and execute commands from the terminal. */voidruncmdshell(){	register struct entry *np;	ino_t ino;	struct arglist arglist;	char curdir[MAXPATHLEN];	char name[MAXPATHLEN];	char cmd[BUFSIZ];	arglist.freeglob = 0;	arglist.argcnt = 0;	arglist.glob.gl_flags = GLOB_ALTDIRFUNC;	arglist.glob.gl_opendir = (void *)rst_opendir;	arglist.glob.gl_readdir = (void *)glob_readdir;	arglist.glob.gl_closedir = (void *)rst_closedir;	arglist.glob.gl_lstat = glob_stat;	arglist.glob.gl_stat = glob_stat;	canon("/", curdir);loop:	if (setjmp(reset) != 0) {		if (arglist.freeglob != 0) {			arglist.freeglob = 0;			arglist.argcnt = 0;			globfree(&arglist.glob);		}		nextarg = NULL;		volno = 0;	}	runshell = 1;	getcmd(curdir, cmd, name, &arglist);	switch (cmd[0]) {	/*	 * Add elements to the extraction list.	 */	case 'a':		if (strncmp(cmd, "add", strlen(cmd)) != 0)			goto bad;		ino = dirlookup(name);		if (ino == 0)			break;		if (mflag)			pathcheck(name);		treescan(name, ino, addfile);		break;	/*	 * Change working directory.	 */	case 'c':		if (strncmp(cmd, "cd", strlen(cmd)) != 0)			goto bad;		ino = dirlookup(name);		if (ino == 0)			break;		if (inodetype(ino) == LEAF) {			fprintf(stderr, "%s: not a directory\n", name);			break;		}		(void) strcpy(curdir, name);		break;	/*	 * Delete elements from the extraction list.	 */	case 'd':		if (strncmp(cmd, "delete", strlen(cmd)) != 0)			goto bad;		np = lookupname(name);		if (np == NULL || (np->e_flags & NEW) == 0) {			fprintf(stderr, "%s: not on extraction list\n", name);			break;		}		treescan(name, np->e_ino, deletefile);		break;	/*	 * Extract the requested list.	 */	case 'e':		if (strncmp(cmd, "extract", strlen(cmd)) != 0)			goto bad;		createfiles();		createlinks();		setdirmodes(0);		if (dflag)			checkrestore();		volno = 0;		break;	/*	 * List available commands.	 */	case 'h':		if (strncmp(cmd, "help", strlen(cmd)) != 0)			goto bad;	case '?':		fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",			"Available commands are:\n",			"\tls [arg] - list directory\n",			"\tcd arg - change directory\n",			"\tpwd - print current directory\n",			"\tadd [arg] - add `arg' to list of",			" files to be extracted\n",			"\tdelete [arg] - delete `arg' from",			" list of files to be extracted\n",			"\textract - extract requested files\n",			"\tsetmodes - set modes of requested directories\n",			"\tquit - immediately exit program\n",			"\twhat - list dump header information\n",			"\tverbose - toggle verbose flag",			" (useful with ``ls'')\n",			"\thelp or `?' - print this list\n",			"If no `arg' is supplied, the current",			" directory is used\n");		break;	/*	 * List a directory.	 */	case 'l':		if (strncmp(cmd, "ls", strlen(cmd)) != 0)			goto bad;		printlist(name, curdir);		break;	/*	 * Print current directory.	 */	case 'p':		if (strncmp(cmd, "pwd", strlen(cmd)) != 0)			goto bad;		if (curdir[1] == '\0')			fprintf(stderr, "/\n");		else			fprintf(stderr, "%s\n", &curdir[1]);		break;	/*	 * Quit.	 */	case 'q':		if (strncmp(cmd, "quit", strlen(cmd)) != 0)			goto bad;		return;	case 'x':		if (strncmp(cmd, "xit", strlen(cmd)) != 0)			goto bad;		return;	/*	 * Toggle verbose mode.	 */	case 'v':		if (strncmp(cmd, "verbose", strlen(cmd)) != 0)			goto bad;		if (vflag) {			fprintf(stderr, "verbose mode off\n");			vflag = 0;			break;		}		fprintf(stderr, "verbose mode on\n");		vflag++;		break;	/*	 * Just restore requested directory modes.	 */	case 's':		if (strncmp(cmd, "setmodes", strlen(cmd)) != 0)			goto bad;		setdirmodes(FORCE);		break;	/*	 * Print out dump header information.	 */	case 'w':		if (strncmp(cmd, "what", strlen(cmd)) != 0)			goto bad;		printdumpinfo();		break;	/*	 * Turn on debugging.	 */	case 'D':		if (strncmp(cmd, "Debug", strlen(cmd)) != 0)			goto bad;		if (dflag) {			fprintf(stderr, "debugging mode off\n");			dflag = 0;			break;		}		fprintf(stderr, "debugging mode on\n");		dflag++;		break;	/*	 * Unknown command.	 */	default:	bad:		fprintf(stderr, "%s: unknown command; type ? for help\n", cmd);		break;	}	goto loop;}/* * Read and parse an interactive command. * The first word on the line is assigned to "cmd". If * there are no arguments on the command line, then "curdir" * is returned as the argument. If there are arguments * on the line they are returned one at a time on each * successive call to getcmd. Each argument is first assigned * to "name". If it does not start with "/" the pathname in * "curdir" is prepended to it. Finally "canon" is called to * eliminate any embedded ".." components. */static voidgetcmd(curdir, cmd, name, ap)	char *curdir, *cmd, *name;	struct arglist *ap;{	register char *cp;	static char input[BUFSIZ];	char output[BUFSIZ];#	define rawname input	/* save space by reusing input buffer */	/*	 * Check to see if still processing arguments.	 */	if (ap->argcnt > 0)		goto retnext;	if (nextarg != NULL)		goto getnext;	/*	 * Read a command line and trim off trailing white space.	 */	do	{		fprintf(stderr, "restore > ");		(void) fflush(stderr);		(void) fgets(input, BUFSIZ, terminal);	} while (!feof(terminal) && input[0] == '\n');	if (feof(terminal)) {		(void) strcpy(cmd, "quit");		return;	}	for (cp = &input[strlen(input) - 2]; *cp == ' ' || *cp == '\t'; cp--)		/* trim off trailing white space and newline */;	*++cp = '\0';	/*	 * Copy the command into "cmd".	 */	cp = copynext(input, cmd);	ap->cmd = cmd;	/*	 * If no argument, use curdir as the default.	 */	if (*cp == '\0') {		(void) strcpy(name, curdir);		return;	}	nextarg = cp;	/*	 * Find the next argument.	 */getnext:	cp = copynext(nextarg, rawname);	if (*cp == '\0')		nextarg = NULL;	else		nextarg = cp;	/*	 * If it is an absolute pathname, canonicalize it and return it.	 */	if (rawname[0] == '/') {		canon(rawname, name);	} else {		/*		 * For relative pathnames, prepend the current directory to		 * it then canonicalize and return it.		 */		(void) strcpy(output, curdir);		(void) strcat(output, "/");		(void) strcat(output, rawname);		canon(output, name);	}	if (glob(name, GLOB_ALTDIRFUNC, NULL, &ap->glob) < 0)		fprintf(stderr, "%s: out of memory\n", ap->cmd);	if (ap->glob.gl_pathc == 0)		return;	ap->freeglob = 1;	ap->argcnt = ap->glob.gl_pathc;retnext:

⌨️ 快捷键说明

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