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

📄 tar.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 2 页
字号:
-M, +multi-volume	create/list/extract multi-volume archive\n\-N, +after-date date	only store files newer than DATE\n\-o, +old-archive	write a V7 format archive, rather than ANSI format\n\-O, +to-stdout		extract files to standard output\n\-p, +same-permissions	extract all protection information\n\-P, +absolute-paths	don't strip leading `/'s from file names\n\+preserve		like -p -s\n\-R, +record-number	show record number within archive with each message\n\-s, +same-order		list of names to extract is sorted to match archive\n\-S, +sparse		handle sparse files efficiently\n\", stderr); /* KLUDGE */ fputs("\-T, +files-from F	get names to extract or create from file F\n\-v, +verbose		verbosely list files processed\n\-V, +volume VNAM	create archive with volume name VNAM\n\+version		print tar program version number\n\-w, +interactive	ask for confirmation for every action\n\-W, +verify		attempt to verify the archive after writing it\n\-X, +exclude FILE	exclude files listed in FILE\n\-z, -Z, +compress      	filter the archive through compress\n\-[0-7][lmh]		specify drive and density\n\", stderr);}name_add(name)char *name;{	if(n_indalloc==n_indused) {		n_indalloc+=10;		n_ind=(char **)(n_indused ? ck_realloc(n_ind,n_indalloc*sizeof(int)) : ck_malloc(n_indalloc*sizeof(int)));	}	n_ind[n_indused++]=name;}		/* * Set up to gather file names for tar. * * They can either come from stdin or from argv. */name_init(argc, argv)	int	argc;	char	**argv;{	if (f_namefile) {		if (optind < argc) {			msg("too many args with -T option");			exit(EX_ARGSBAD);		}		if (!strcmp(name_file, "-")) {			namef = stdin;		} else {			namef = fopen(name_file, "r");			if (namef == NULL) {				msg_perror("can't open file %s",name_file);				exit(EX_BADFILE);			}		}	} else {		/* Get file names from argv, after options. */		n_argc = argc;		n_argv = argv;	}}/* * Get the next name from argv or the name file. * * Result is in static storage and can't be relied upon across two calls. *//* C is non-zero if we should deal with -C */char *name_next(c){	static char	buffer[NAMSIZ+2];	/* Holding pattern */	register char	*p;	register char	*q = 0;	extern char *un_quote_string(); tryagain:	if (namef == NULL) {		if(n_indscan<n_indused)			p=n_ind[n_indscan++];		else if (optind < n_argc)					/* Names come from argv, after options */			p=n_argv[optind++];		else {			if(q)				msg("Missing filename after -C");			return NULL;		}		/* JF trivial support for -C option.  I don't know if		   chdir'ing at this point is dangerous or not.		   It seems to work, which is all I ask. */		if(c && !q && p[0]=='-' && p[1]=='C' && p[2]=='\0') {			q=p;			goto tryagain;		}		if(q) {			if(chdir(p)<0)				msg_perror("Can't chdir to %s",p);			q=0;			goto tryagain;		}		/* End of JF quick -C hack */		if(f_exclude && check_exclude(p))			goto tryagain;		return un_quote_string(p);	}	while(p = fgets(buffer, NAMSIZ+1 /*nl*/, namef)) {		q = p+strlen(p)-1;		/* Find the newline */		if (q <= p)			/* Ignore empty lines */			continue;		*q-- = '\0';			/* Zap the newline */		while (q > p && *q == '/')	/* Zap trailing /s */			*q-- = '\0';		if(f_exclude && check_exclude(p))			goto tryagain;		return un_quote_string(p);	}	return NULL;}/* * Close the name file, if any. */name_close(){	if (namef != NULL && namef != stdin) fclose(namef);}/* * Gather names in a list for scanning. * Could hash them later if we really care. * * If the names are already sorted to match the archive, we just * read them one by one.  name_gather reads the first one, and it * is called by name_match as appropriate to read the next ones. * At EOF, the last name read is just left in the buffer. * This option lets users of small machines extract an arbitrary * number of files by doing "tar t" and editing down the list of files. */name_gather(){	register char *p;	static struct name namebuf[1];	/* One-name buffer */	static char *chdir_name;	if (f_sorted_names) {		p = name_next(0);		if (p) {			if(*p=='-' && p[1]=='C' && p[2]=='\0') {				chdir_name=name_next(0);				p=name_next(0);				if(!p) {					msg("Missing file name after -C");					exit(EX_ARGSBAD);				}				namebuf[0].change_dir=chdir_name;			}			namebuf[0].length = strlen(p);			if (namebuf[0].length >= sizeof namebuf[0].name) {				msg("Argument name '%s' too long.",p);				namebuf[0].length = (sizeof namebuf[0].name) - 1;			}			strncpy(namebuf[0].name, p, namebuf[0].length);			namebuf[0].name[ namebuf[0].length ] = 0;			namebuf[0].next = (struct name *)NULL;			namebuf[0].found = 0;			namelist = namebuf;			namelast = namelist;		}		return;	}	/* Non sorted names -- read them all in */	while (p = name_next(0))		addname(p);}/* * Add a name to the namelist. */addname(name)	char	*name;			/* pointer to name */{	register int	i;		/* Length of string */	register struct name	*p;	/* Current struct pointer */	static char *chdir_name;	char *new_name();#define MAXPATHLEN 1024	if(name[0]=='-' && name[1]=='C' && name[2]=='\0') {		chdir_name=name_next(0);		name=name_next(0);		if(!name) {			msg("Missing file name after -C");			exit(EX_ARGSBAD);		}		if(chdir_name[0]!='/') {			char path[MAXPATHLEN];#if defined(MSDOS) || defined(USG)			int getcwd();			if(!getcwd(path,MAXPATHLEN))				msg("Couldn't get current directory.");				exit(EX_SYSTEM);#else			char *getwd();			if(!getwd(path)) {				msg("Couldn't get current directory: %s",path);				exit(EX_SYSTEM);			}#endif			chdir_name=new_name(path,chdir_name);		}	}	i = strlen(name);	/*NOSTRICT*/	p = (struct name *)		malloc((unsigned)(i + sizeof(struct name) - NAMSIZ));	if (!p) {		msg("cannot allocate mem for name '%s'.",name);		exit(EX_SYSTEM);	}	p->next = (struct name *)NULL;	p->length = i;	strncpy(p->name, name, i);	p->name[i] = '\0';	/* Null term */	p->found = 0;	p->regexp = 0;		/* Assume not a regular expression */	p->firstch = 1;		/* Assume first char is literal */	p->change_dir=chdir_name;	p->dir_contents = 0;	/* JF */	if (index(name, '*') || index(name, '[') || index(name, '?')) {		p->regexp = 1;	/* No, it's a regexp */		if (name[0] == '*' || name[0] == '[' || name[0] == '?')			p->firstch = 0;		/* Not even 1st char literal */	}	if (namelast) namelast->next = p;	namelast = p;	if (!namelist) namelist = p;}/* * Match a name from an archive, p, with a name from the namelist. */name_match(p)	register char *p;{	register struct name	*nlp;	register int		len;again:	if (0 == (nlp = namelist))	/* Empty namelist is easy */		return 1;	len = strlen(p);	for (; nlp != 0; nlp = nlp->next) {		/* If first chars don't match, quick skip */		if (nlp->firstch && nlp->name[0] != p[0])			continue;		/* Regular expressions */		if (nlp->regexp) {			if (wildmat(p, nlp->name)) {				nlp->found = 1;	/* Remember it matched */				if(f_startfile) {					free((void *)namelist);					namelist=0;				}				if(nlp->change_dir && chdir(nlp->change_dir))					msg_perror("Can't change to directory %s",nlp->change_dir);				return 1;	/* We got a match */			}			continue;		}		/* Plain Old Strings */		if (nlp->length <= len		/* Archive len >= specified */		 && (p[nlp->length] == '\0' || p[nlp->length] == '/')						/* Full match on file/dirname */		 && strncmp(p, nlp->name, nlp->length) == 0) /* Name compare */		{			nlp->found = 1;		/* Remember it matched */			if(f_startfile) {				free((void *)namelist);				namelist = 0;			}			if(nlp->change_dir && chdir(nlp->change_dir))				msg_perror("Can't change to directory %s",nlp->change_dir);			return 1;		/* We got a match */		}	}	/*	 * Filename from archive not found in namelist.	 * If we have the whole namelist here, just return 0.	 * Otherwise, read the next name in and compare it.	 * If this was the last name, namelist->found will remain on.	 * If not, we loop to compare the newly read name.	 */	if (f_sorted_names && namelist->found) {		name_gather();		/* Read one more */		if (!namelist->found) goto again;	}	return 0;}/* * Print the names of things in the namelist that were not matched. */names_notfound(){	register struct name	*nlp;	register char		*p;	for (nlp = namelist; nlp != 0; nlp = nlp->next) {		if (!nlp->found)			msg("%s not found in archive",nlp->name);		/*		 * We could free() the list, but the process is about		 * to die anyway, so save some CPU time.  Amigas and		 * other similarly broken software will need to waste		 * the time, though.		 */#ifndef unix		if (!f_sorted_names)			free(nlp);#endif	}	namelist = (struct name *)NULL;	namelast = (struct name *)NULL;	if (f_sorted_names) {		while (0 != (p = name_next(1)))			msg("%s not found in archive", p);	}}/* These next routines were created by JF */name_expand(){;}/* This is like name_match(), except that it returns a pointer to the name   it matched, and doesn't set ->found  The caller will have to do that   if it wants to.  Oh, and if the namelist is empty, it returns 0, unlike   name_match(), which returns TRUE */struct name *name_scan(p)register char *p;{	register struct name	*nlp;	register int		len;again:	if (0 == (nlp = namelist))	/* Empty namelist is easy */		return 0;	len = strlen(p);	for (; nlp != 0; nlp = nlp->next) {		/* If first chars don't match, quick skip */		if (nlp->firstch && nlp->name[0] != p[0])			continue;		/* Regular expressions */		if (nlp->regexp) {			if (wildmat(p, nlp->name))				return nlp;	/* We got a match */			continue;		}		/* Plain Old Strings */		if (nlp->length <= len		/* Archive len >= specified */		 && (p[nlp->length] == '\0' || p[nlp->length] == '/')						/* Full match on file/dirname */		 && strncmp(p, nlp->name, nlp->length) == 0) /* Name compare */			return nlp;		/* We got a match */	}	/*	 * Filename from archive not found in namelist.	 * If we have the whole namelist here, just return 0.	 * Otherwise, read the next name in and compare it.	 * If this was the last name, namelist->found will remain on.	 * If not, we loop to compare the newly read name.	 */	if (f_sorted_names && namelist->found) {		name_gather();		/* Read one more */		if (!namelist->found) goto again;	}	return (struct name *) 0;}/* This returns a name from the namelist which doesn't have ->found set.   It sets ->found before returning, so successive calls will find and return   all the non-found names in the namelist */struct name *gnu_list_name;char *name_from_list(){	if(!gnu_list_name)		gnu_list_name = namelist;	while(gnu_list_name && gnu_list_name->found)		gnu_list_name=gnu_list_name->next;	if(gnu_list_name) {		gnu_list_name->found++;		if(gnu_list_name->change_dir)			if(chdir(gnu_list_name->change_dir)<0)				msg_perror("can't chdir to %s",gnu_list_name->change_dir);		return gnu_list_name->name;	}	return (char *)0;}blank_name_list(){	struct name *n;	gnu_list_name = 0;	for(n=namelist;n;n=n->next)		n->found = 0;}char *new_name(path,name)char *path,*name;{	char *path_buf;	path_buf=(char *)malloc(strlen(path)+strlen(name)+2);	if(path_buf==0) {		msg("Can't allocate memory for name '%s/%s",path,name);		exit(EX_SYSTEM);	}	(void) sprintf(path_buf,"%s/%s",path,name);	return path_buf;}/* returns non-zero if the luser typed 'y' or 'Y', zero otherwise. */intconfirm(action,file)char *action, *file;{	int	c,nl;	static FILE *confirm_file = 0;	extern FILE *msg_file;	extern char TTY_NAME[];	fprintf(msg_file,"%s %s?", action, file);	fflush(msg_file);	if(!confirm_file) {		confirm_file = (archive == 0) ? fopen(TTY_NAME, "r") : stdin;		if(!confirm_file) {			msg("Can't read confirmation from user");			exit(EX_SYSTEM);		}	}	c=getc(confirm_file);	for(nl = c; nl != '\n' && nl != EOF; nl = getc(confirm_file))		;	return (c=='y' || c=='Y');}char *x_buffer = 0;int size_x_buffer;int free_x_buffer;char **exclude = 0;int size_exclude = 0;int free_exclude = 0;char **re_exclude = 0;int size_re_exclude = 0;int free_re_exclude = 0;add_exclude(file)char *file;{	FILE *fp;	char buf[1024];	extern char *rindex();	if(strcmp(file, "-"))		fp=fopen(file,"r");	else		/* Let's hope the person knows what they're doing. */		/* Using -X - -T - -f - will get you *REALLY* strange		   results. . . */		fp=stdin;	if(!fp) {		msg_perror("can't open %s",file);		exit(2);	}	while(fgets(buf,1024,fp)) {		int size_buf;		char *end_str;		end_str=rindex(buf,'\n');		if(end_str)			*end_str='\0';		un_quote_string(buf);		size_buf = strlen(buf);		if(x_buffer==0) {			x_buffer = (char *)ck_malloc(size_buf+1024);			free_x_buffer=1024;		} else if(free_x_buffer<=size_buf) {			char *old_x_buffer;			char **tmp_ptr;			old_x_buffer = x_buffer;			x_buffer = (char *)ck_realloc(x_buffer,size_x_buffer+1024);			free_x_buffer = 1024;			for(tmp_ptr=exclude;tmp_ptr<exclude+size_exclude;tmp_ptr++)				*tmp_ptr= x_buffer + ((*tmp_ptr) - old_x_buffer);			for(tmp_ptr=re_exclude;tmp_ptr<re_exclude+size_re_exclude;tmp_ptr++)				*tmp_ptr= x_buffer + ((*tmp_ptr) - old_x_buffer);		}		if(is_regex(buf)) {			if(free_re_exclude==0) {				re_exclude= (char **)(re_exclude ? ck_realloc(re_exclude,(size_re_exclude+32)*sizeof(char *)) : ck_malloc(sizeof(char *)*32));				free_re_exclude+=32;			}			re_exclude[size_re_exclude]=x_buffer+size_x_buffer;			size_re_exclude++;			free_re_exclude--;		} else {			if(free_exclude==0) {				exclude=(char **)(exclude ? ck_realloc(exclude,(size_exclude+32)*sizeof(char *)) : ck_malloc(sizeof(char *)*32));				free_exclude+=32;			}			exclude[size_exclude]=x_buffer+size_x_buffer;			size_exclude++;			free_exclude--;		}		strcpy(x_buffer+size_x_buffer,buf);		size_x_buffer+=size_buf+1;		free_x_buffer-=size_buf+1;	}	fclose(fp);}intis_regex(str)char *str;{	return index(str,'*') || index(str,'[') || index(str,'?');}/* Returns non-zero if the file 'name' should not be added/extracted */intcheck_exclude(name)char *name;{	int n;	for(n=0;n<size_re_exclude;n++) {		if(wildmat(name,re_exclude[n]))			return 1;	}	for(n=0;n<size_exclude;n++) {		if(strstr(name,exclude[n]))			return 1;	}	return 0;}

⌨️ 快捷键说明

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