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

📄 options.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1992 Keith Muller. * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Keith Muller of the University of California, San Diego. * * 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[] = "@(#)options.c	8.2 (Berkeley) 4/18/94";#endif /* not lint */#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/mtio.h>#include <sys/param.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <limits.h>#include "pax.h"#include "options.h"#include "cpio.h"#include "tar.h"#include "extern.h"/* * Routines which handle command line options */static char flgch[] = FLGCH;	/* list of all possible flags */static OPLIST *ophead = NULL;	/* head for format specific options -x */static OPLIST *optail = NULL;	/* option tail */static int no_op __P((void));static void printflg __P((unsigned int));static int c_frmt __P((const void *, const void *));static off_t str_offt __P((char *));static void pax_options __P((register int, register char **));static void pax_usage __P((void));static void tar_options __P((register int, register char **));static void tar_usage __P((void));#ifdef notdefstatic void cpio_options __P((register int, register char **));static void cpio_usage __P((void));#endif/* *	Format specific routine table - MUST BE IN SORTED ORDER BY NAME *	(see pax.h for description of each function) * * 	name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, *	read, end_read, st_write, write, end_write, trail, *	rd_data, wr_data, options */FSUB fsub[] = {/* 0: OLD BINARY CPIO */	"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd,	bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail,	rd_wrfile, wr_rdfile, bad_opt,/* 1: OLD OCTAL CHARACTER CPIO */	"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd,	cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail,	rd_wrfile, wr_rdfile, bad_opt,/* 2: SVR4 HEX CPIO */	"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd,	vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail,	rd_wrfile, wr_rdfile, bad_opt,/* 3: SVR4 HEX CPIO WITH CRC */	"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd,	vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail,	rd_wrfile, wr_rdfile, bad_opt,/* 4: OLD TAR */	"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op,	tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail,	rd_wrfile, wr_rdfile, tar_opt,/* 5: POSIX USTAR */	"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd,	ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail,	rd_wrfile, wr_rdfile, bad_opt,};#define F_TAR	4	/* format when called as tar */#define DEFLT	5	/* default write format from list above *//* * ford is the archive search order used by get_arc() to determine what kind * of archive we are dealing with. This helps to properly id  archive formats * some formats may be subsets of others.... */int ford[] = {5, 4, 3, 2, 1, 0, -1 };/* * options() *	figure out if we are pax, tar or cpio. Call the appropriate options *	parser */#if __STDC__voidoptions(register int argc, register char **argv)#elsevoidoptions(argc, argv)	register int argc;	register char **argv;#endif{	/*	 * Are we acting like pax, tar or cpio (based on argv[0])	 */	if ((argv0 = strrchr(argv[0], '/')) != NULL)		argv0++;	else		argv0 = argv[0];	if (strcmp(NM_TAR, argv0) == 0)		return(tar_options(argc, argv));#	ifdef notdef	else if (strcmp(NM_CPIO, argv0) == 0)		return(cpio_options(argc, argv));#	endif	/*	 * assume pax as the default	 */	argv0 = NM_PAX;	return(pax_options(argc, argv));}/* * pax_options() *	look at the user specified flags. set globals as required and check if *	the user specified a legal set of flags. If not, complain and exit */#if __STDC__static voidpax_options(register int argc, register char **argv)#elsestatic voidpax_options(argc, argv)	register int argc;	register char **argv;#endif{	register int c;	register int i;	unsigned int flg = 0;	unsigned int bflg = 0;	register char *pt;        FSUB tmp;	extern char *optarg;	extern int optind;	/*	 * process option flags	 */	while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLPT:U:XYZ"))	    != EOF) {		switch (c) {		case 'a':			/*			 * append			 */			flg |= AF;			break;		case 'b':			/*			 * specify blocksize			 */			flg |= BF;			if ((wrblksz = (int)str_offt(optarg)) <= 0) {				warn(1, "Invalid block size %s", optarg);				pax_usage();			}			break;		case 'c':			/*			 * inverse match on patterns			 */			cflag = 1;			flg |= CF;			break;		case 'd':			/*			 * match only dir on extract, not the subtree at dir			 */			dflag = 1;			flg |= DF;			break;		case 'f':			/*			 * filename where the archive is stored			 */			arcname = optarg;			flg |= FF;			break;		case 'i':			/*			 * interactive file rename			 */			iflag = 1;			flg |= IF;			break;		case 'k':			/*			 * do not clobber files that exist			 */			kflag = 1;			flg |= KF;			break;		case 'l':			/*			 * try to link src to dest with copy (-rw)			 */			lflag = 1;			flg |= LF;			break;		case 'n':			/*			 * select first match for a pattern only			 */			nflag = 1;			flg |= NF;			break;		case 'o':			/*			 * pass format specific options			 */			flg |= OF;			if (opt_add(optarg) < 0)				pax_usage();			break;		case 'p':			/*			 * specify file characteristic options			 */			for (pt = optarg; *pt != '\0'; ++pt) {				switch(*pt) {				case 'a':					/*					 * do not preserve access time					 */					patime = 0;					break;				case 'e':					/*					 * preserve user id, group id, file					 * mode, access/modification times					 */					pids = 1;					pmode = 1;					patime = 1;					pmtime = 1;					break;				case 'm':					/*					 * do not preserve modification time					 */					pmtime = 0;					break;				case 'o':					/*					 * preserve uid/gid					 */					pids = 1;					break;				case 'p':					/*					 * preserver file mode bits					 */					pmode = 1;					break;				default:					warn(1, "Invalid -p string: %c", *pt);					pax_usage();					break;				}			}			flg |= PF;			break;		case 'r':			/*			 * read the archive			 */			flg |= RF;			break;		case 's':			/*			 * file name substitution name pattern			 */			if (rep_add(optarg) < 0) {				pax_usage();				break;			}			flg |= SF;			break;		case 't':			/*			 * preserve access time on filesystem nodes we read			 */			tflag = 1;			flg |= TF;			break;		case 'u':			/*			 * ignore those older files			 */			uflag = 1;			flg |= UF;			break;		case 'v':			/*			 * verbose operation mode			 */			vflag = 1;			flg |= VF;			break;		case 'w':			/*			 * write an archive			 */			flg |= WF;			break;		case 'x':			/*			 * specify an archive format on write			 */			tmp.name = optarg;			if (frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub,			    sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) {				flg |= XF;				break;			}			warn(1, "Unknown -x format: %s", optarg);			(void)fputs("pax: Known -x formats are:", stderr);			for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)				(void)fprintf(stderr, " %s", fsub[i].name);			(void)fputs("\n\n", stderr);			pax_usage();			break;		case 'B':			/*			 * non-standard option on number of bytes written on a			 * single archive volume.			 */			if ((wrlimit = str_offt(optarg)) <= 0) {				warn(1, "Invalid write limit %s", optarg);				pax_usage();			}			if (wrlimit % BLKMULT) {				warn(1, "Write limit is not a %d byte multiple",				    BLKMULT);				pax_usage();			}			flg |= CBF;			break;		case 'D':			/*			 * On extraction check file inode change time before the			 * modification of the file name. Non standard option.			 */			Dflag = 1;			flg |= CDF;			break;		case 'E':			/*			 * non-standard limit on read faults			 * 0 indicates stop after first error, values			 * indicate a limit, "NONE" try forever			 */			flg |= CEF;			if (strcmp(NONE, optarg) == 0)				maxflt = -1;			else if ((maxflt = atoi(optarg)) < 0) {				warn(1, "Error count value must be positive");				pax_usage();			}			break;		case 'G':			/*			 * non-standard option for selecting files within an			 * archive by group (gid or name)			 */			if (grp_add(optarg) < 0) {				pax_usage();				break;			}			flg |= CGF;			break;		case 'H':			/*			 * follow command line symlinks only			 */			Hflag = 1;			flg |= CHF;			break;		case 'L':			/*			 * follow symlinks			 */			Lflag = 1;			flg |= CLF;			break;		case 'P':			/*			 * do NOT follow symlinks (default)			 */			Lflag = 0;			flg |= CPF;			break;		case 'T':			/*			 * non-standard option for selecting files within an			 * archive by modification time range (lower,upper)			 */			if (trng_add(optarg) < 0) {				pax_usage();				break;			}			flg |= CTF;			break;		case 'U':			/*			 * non-standard option for selecting files within an			 * archive by user (uid or name)			 */			if (usr_add(optarg) < 0) {				pax_usage();				break;			}			flg |= CUF;			break;		case 'X':			/*			 * do not pass over mount points in the file system			 */			Xflag = 1;			flg |= CXF;			break;		case 'Y':			/*			 * On extraction check file inode change time after the			 * modification of the file name. Non standard option.			 */			Yflag = 1;			flg |= CYF;			break;		case 'Z':			/*			 * On extraction check modification time after the			 * modification of the file name. Non standard option.			 */			Zflag = 1;			flg |= CZF;			break;		case '?':		default:			pax_usage();			break;		}	}	/*	 * figure out the operation mode of pax read,write,extract,copy,append	 * or list. check that we have not been given a bogus set of flags	 * for the operation mode.	 */	if (ISLIST(flg)) {		act = LIST;		bflg = flg & BDLIST;	} else if (ISEXTRACT(flg)) {		act = EXTRACT;		bflg = flg & BDEXTR;	} else if (ISARCHIVE(flg)) {		act = ARCHIVE;		bflg = flg & BDARCH;	} else if (ISAPPND(flg)) {		act = APPND;		bflg = flg & BDARCH;	} else if (ISCOPY(flg)) {		act = COPY;		bflg = flg & BDCOPY;	} else		pax_usage();	if (bflg) {		printflg(flg);		pax_usage();	}	/*	 * if we are writing (ARCHIVE) we use the default format if the user	 * did not specify a format. when we write during an APPEND, we will	 * adopt the format of the existing archive if none was supplied.	 */	if (!(flg & XF) && (act == ARCHIVE))		frmt = &(fsub[DEFLT]);	/*	 * process the args as they are interpreted by the operation mode	 */	switch (act) {	case LIST:	case EXTRACT:		for (; optind < argc; optind++)			if (pat_add(argv[optind]) < 0)				pax_usage();		break;	case COPY:		if (optind >= argc) {			warn(0, "Destination directory was not supplied");			pax_usage();		}		--argc;		dirptr = argv[argc];		/* FALL THROUGH */	case ARCHIVE:	case APPND:		for (; optind < argc; optind++)			if (ftree_add(argv[optind]) < 0)				pax_usage();		/*		 * no read errors allowed on updates/append operation!		 */		maxflt = 0;		break;	}}/* * tar_options() *	look at the user specified flags. set globals as required and check if

⌨️ 快捷键说明

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