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

📄 tar.c

📁 unix 下tar 执行程序的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

		case 'G':			/* We are making a GNU dump; save
						   directories at the beginning of
						   the archive, and include in each
						   directory its contents */
			if(f_oldarch)
				goto badopt;
			f_gnudump++;
			gnu_dumpfile=0;
			break;

		case 'h':
			f_follow_links++;	/* follow symbolic links */
			break;

		case 'i':
			f_ignorez++;		/* Ignore zero records (eofs) */
			/*
			 * This can't be the default, because Unix tar
			 * writes two records of zeros, then pads out the
			 * block with garbage.
			 */
			break;

		case 'k':			/* Don't overwrite files */
#ifdef NO_OPEN3
			msg("can't do -k option on this system");
			exit(EX_ARGSBAD);
#else
			f_keep++;
#endif
			break;

		case 'K':
			f_startfile++;
			addname(optarg);
			break;

		case 'l':			/* When dumping directories, don't
						   dump files/subdirectories that are
						   on other filesystems. */
			f_local_filesys++;
			break;

		case 'L':
			tape_length = intconv (optarg);
			f_multivol++;
			break;
		case 'm':
			f_modified++;
			break;

		case 'M':			/* Make Multivolume archive:
						   When we can't write any more
						   into the archive, re-open it,
						   and continue writing */
			f_multivol++;
			break;

		case 'N':			/* Only write files newer than X */
		get_newer:
			f_new_files++;
			new_time=get_date(optarg,(struct timeb *)0);
			break;

		case 'o':			/* Generate old archive */
			if(f_gnudump /* || f_dironly */)
				goto badopt;
			f_oldarch++;
			break;

		case 'O':
			f_exstdout++;
			break;

		case 'p':
			f_use_protection++;
			break;

		case 'P':
			f_absolute_paths++;
			break;

		case 'r':			/* Append files to the archive */
			if(cmd_mode!=CMD_NONE)
				goto badopt;
			cmd_mode=CMD_APPEND;
			break;

		case 'R':
			f_sayblock++;		/* Print block #s for debug */
			break;			/* of bad tar archives */

		case 's':
			f_sorted_names++;	/* Names to extr are sorted */
			break;

		case 'S':			/* deal with sparse files */
			f_sparse_files++;
			break;
		case 't':
			if(cmd_mode!=CMD_NONE)
				goto badopt;
			cmd_mode=CMD_LIST;
			f_verbose++;		/* "t" output == "cv" or "xv" */
			break;

		case 'T':
			name_file = optarg;
			f_namefile++;
			break;

		case 'u':			/* Append files to the archive that
						   aren't there, or are newer than the
						   copy in the archive */
			if(cmd_mode!=CMD_NONE)
				goto badopt;
			cmd_mode=CMD_UPDATE;
			break;

		case 'v':
			f_verbose++;
			break;

		case 'V':
			f_volhdr=optarg;
			break;

		case 'w':
			f_confirm++;
			break;

		case 'W':
			f_verify++;
			break;

		case 'x':			/* Extract files from the archive */
			if(cmd_mode!=CMD_NONE)
				goto badopt;
			cmd_mode=CMD_EXTRACT;
			break;

		case 'X':
			f_exclude++;
			add_exclude_file(optarg);
			break;

		case 'z':		/* Easy to type */
		case 'Z':		/* Like the filename extension .Z */
			f_compress++;
			break;

		case '?':
		badopt:
			msg("Unknown option.  Use '%s +help' for a complete list of options.", tar);
			exit(EX_ARGSBAD);

		}
	}

	blocksize = blocking * RECORDSIZE;
}


/*
 * Print as much help as the user's gonna get.
 *
 * We have to sprinkle in the KLUDGE lines because too many compilers
 * cannot handle character strings longer than about 512 bytes.  Yuk!
 * In particular, MSDOS and Xenix MSC and PDP-11 V7 Unix have this
 * problem.
 */
void
describe()
{
	msg("choose one of the following:");
	fputs("\
-A, +catenate,\n\
    +concatenate	append tar files to an archive\n\
-c, +create		create a new archive\n\
-d, +diff,\n\
    +compare		find differences between archive and file system\n\
+delete			delete from the archive (not for use on mag tapes!)\n\
-r, +append		append files to the end of an archive\n\
-t, +list		list the contents of an archive\n\
-u, +update		only append files that are newer than copy in archive\n\
-x, +extract,\n\
    +get		extract files from an archive\n",stderr);

	fprintf(stderr, "\
Other options:\n\
-b, +block-size N	block size of Nx512 bytes (default N=%d)\n", DEFBLOCKING);
	fputs ("\
-B, +read-full-blocks	reblock as we read (for reading 4.2BSD pipes)\n\
-C, +directory DIR	change to directory DIR\n\
", stderr); /* KLUDGE */ fprintf(stderr, "\
-f, +file [HOSTNAME:]F	use archive file or device F (default %s)\n",
				 DEF_AR_FILE); fputs("\
-F, +info-script F	run script at end of each tape (implies -M)\n\
-G, +incremental	create/list/extract old GNU-format incremental backup\n\
-g, +listed-incremental F create/list/extract new GNU-format incremental backup\n\
-h, +dereference	don't dump symlinks; dump the files they point to\n\
-i, +ignore-zeros	ignore blocks of zeros in archive (normally mean EOF)\n\
", stderr); /* CHRIS */ fputs("\
-k, +keep-old-files     keep existing files; don't overwrite them from archive\n\
-K, +starting-file FILE	begin at FILE in the archive\n\
-l, +one-file-system	stay in local file system when creating an archive\n\
-L, +tape-length LENGTH change tapes after writing LENGTH\n\
", stderr); /* KLUDGE */ fputs("\
-m, +modification-time	don't extract file modified time\n\
-M, +multi-volume	create/list/extract multi-volume archive\n\
-N, +after-date DATE,\n\
    +newer DATE		only store files newer than DATE\n\
", stderr); /* CHRIS */ fputs("\
-o, +old-archive,\n\
    +portability	write a V7 format archive, rather than ANSI format\n\
-O, +to-stdout		extract files to standard output\n\
-p, +same-permissions,\n\
    +preserve-permissions extract all protection information\n\
-P, +absolute-paths	don't strip leading `/'s from file names\n\
+preserve		like -p -s\n\
", stderr); /* KLUDGE */ fputs("\
-R, +record-number	show record number within archive with each message\n\
-s, +same-order,\n\
    +preserve-order	list of names to extract is sorted to match archive\n\
+same-order		create extracted files with the same ownership \n\
-S, +sparse		handle sparse files efficiently\n\
-T, +files-from F	get names to extract or create from file F\n\
+totals			print total bytes written with +create\n\
", stderr);  /* CHRIS */ fputs("\
-v, +verbose		verbosely list files processed\n\
-V, +label NAME		create archive with volume name NAME\n\
+version		print tar program version number\n\
-w, +interactive,\n\
    +confirmation	ask for confirmation for every action\n\
", stderr); /* KLUDGE */ fputs("\
-W, +verify		attempt to verify the archive after writing it\n\
-X, +exclude FILE	exclude file FILE\n\
+exclude-from FILE	exclude files listed in FILE\n\
-z, -Z, +compress,\n\
    +uncompress      	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(char *)) : ck_malloc(n_indalloc*sizeof(char *)));
	}
	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;	/* Holding pattern */
	static buffer_siz;
	register char	*p;
	register char	*q = 0;
	register char	*q2 = 0;
	extern char *un_quote_string();

	if(buffer_siz==0) {
		buffer=ck_malloc(NAMSIZ+2);
		buffer_siz=NAMSIZ;
	}
 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, buffer_siz+1 /*nl*/, namef)) {
		q = p+strlen(p)-1;		/* Find the newline */
		if (q <= p)			/* Ignore empty lines */
			continue;
		while(q==p+buffer_siz && *q!='\n') {
			buffer=ck_realloc(buffer,buffer_siz+NAMSIZ+2);
			p=buffer;
			q=buffer+buffer_siz;
			buffer_siz+=NAMSIZ;
			fgets(q+1,NAMSIZ,namef);
			q=p+strlen(p)-1;
		}
		*q-- = '\0';			/* Zap the newline */
		while (q > p && *q == '/')	/* Zap trailing /s */
			*q-- = '\0';
		if (c && !q2 && p[0] == '-' && p[1] == 'C' && p[2] == '\0') {
			q2 = p;
			goto tryagain;
		}
		if (q2) {
			if (chdir (p) < 0)
				msg_perror ("Can't chdir to %s", p);
			q2 = 0;
			goto tryagain;
		}
		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;	/* One-name buffer */
	static namelen;
	static char *chdir_name;

	if (f_sorted_names) {
		if(!namelen) {
			namelen=NAMSIZ;
			namebuf=(struct name *)ck_malloc(sizeof(struct name)+NAMSIZ);
		}
		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->change_dir=chdir_name;
			}
			namebuf->length = strlen(p);
			if (namebuf->length >= namelen) {
				namebuf=(struct name *)ck_realloc(namebuf,sizeof(struct name)+namebuf->length);
				namelen=namebuf->length;
			}
			strncpy(namebuf->name, p, namebuf->length);
			namebuf->name[ namebuf->length ] = 0;
			namebuf->next = (struct name *)NULL;
			namebuf->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.
 */

⌨️ 快捷键说明

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