"b:cef:hmopqruts:vwxzBC:HLOPXZ014578"))
"b:cef:hmopqruts:vwxzBC:HLOPT:XZ014578"))
static char *getline __P((FILE *fp));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));static void cpio_options __P((register int, register char **));static void cpio_usage __P((void));/* errors from getline */#define GETLINE_FILE_CORRUPT 1#define GETLINE_OUT_OF_MEM 2static int getline_error;#define GZIP_CMD	"gzip"		/* command to run as gzip */#define COMPRESS_CMD	"compress"	/* command to run as compress *//* *	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_OCPIO	0	/* format when called as cpio -6 */#define	F_ACPIO	1	/* format when called as cpio -c */#define	F_CPIO	3	/* format when called as cpio */#define F_OTAR	4	/* format when called as tar -o */#define F_TAR	5	/* 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 */#ifdef __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));	else if (strcmp(NM_CPIO, argv0) == 0)		return(cpio_options(argc, argv));	/*	 * 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 */#ifdef __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;	/*	 * process option flags	 */	while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ"))	    != -1) {		switch (c) {		case 'a':			/*			 * append			 */			flg |= AF;			break;		case 'b':			/*			 * specify blocksize			 */			flg |= BF;			if ((wrblksz = (int)str_offt(optarg)) <= 0) {				paxwarn(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:					paxwarn(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)) != NULL) {				flg |= XF;				break;			}			paxwarn(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 'z':			/*			 * use gzip.  Non standard option.			 */			gzip_program = GZIP_CMD;			break;		case 'B':			/*			 * non-standard option on number of bytes written on a			 * single archive volume.			 */			if ((wrlimit = str_offt(optarg)) <= 0) {				paxwarn(1, "Invalid write limit %s", optarg);				pax_usage();			}			if (wrlimit % BLKMULT) {				paxwarn(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) {				paxwarn(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;		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;		listf = stdout;		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], NULL) < 0)				pax_usage();		break;	case COPY:		if (optind >= argc) {			paxwarn(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) < 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 *	the user specified a legal set of flags. If not, complain and exit */#ifdef __STDC__static voidtar_options(register int argc, register char **argv)#elsestatic voidtar_options(argc, argv)	register int argc;	register char **argv;#endif{	register int c;	int fstdin = 0;	int Oflag = 0;	/*	 * Set default values.	 */	rmleadslash = 1;	/*	 * process option flags	 */	while ((c = getoldopt(argc, argv,	    "b:cef:hmopqruts:vwxzBC:HLOPXZ014578"))	    != -1) {		switch(c) {		case 'b':			/*			 * specify blocksize in 512-byte blocks			 */			if ((wrblksz = (int)str_offt(optarg)) <= 0) {				paxwarn(1, "Invalid block size %s", optarg);				tar_usage();			}			wrblksz *= 512;		/* XXX - check for int oflow */			break;		case 'c':			/*			 * create an archive			 */			act = ARCHIVE;			break;		case 'e':			/*			 * stop after first error			 */			maxflt = 0;			break;		case 'f':			/*			 * filename where the archive is stored			 */			if ((optarg[0] == '-') && (optarg[1]== '\0')) {				/*				 * treat a - as stdin				 */				fstdin = 1;				arcname = NULL;				break;			}			fstdin = 0;			arcname = optarg;			break;		case 'h':			/*			 * follow symlinks			 */			Lflag = 1;			break;		case 'm':			/*			 * do not preserve modification time			 */			pmtime = 0;			break;		case 'o':			if (opt_add("write_opt=nodir") < 0)				tar_usage();		case 'O':			Oflag = 1;			break;		case 'p':			/*			 * preserve uid/gid and file mode, regardless of umask			 */			pmode = 1;			pids = 1;			break;		case 'q':			/*			 * select first match for a pattern only			 */			nflag = 1;			break;		case 'r':		case 'u':			/*			 * append to the archive			 */			act = APPND;			break;		case 's':			/*			 * file name substitution name pattern			 */			if (rep_add(optarg) < 0) {				tar_usage();				break;			}			break;		case 't':			/*			 * list contents of the tape			 */			act = LIST;			break;		case 'v':			/*			 * verbose operation mode			 */			vflag++;			break;		case 'w':			/*			 * interactive file rename			 */			iflag = 1;			break;		case 'x':			/*			 * extract an archive, preserving mode,			 * and mtime if possible.			 */			act = EXTRACT;			pmtime = 1;			break;		case 'z':			/*			 * use gzip.  Non standard option.			 */			gzip_program = GZIP_CMD;			break;		case 'B':			/*			 * Nothing to do here, this is pax default			 */			break;		case 'C':			chdname = optarg;			break;		case 'H':			/*			 * follow command line symlinks only			 */			Hflag = 1;			break;		case 'L':			/*			 * follow symlinks			 */			Lflag = 1;			break;		case 'P':			/*			 * do not remove leading '/' from pathnames			 */			rmleadslash = 0;			break;		case 'X':			/*			 * do not pass over mount points in the file system			 */			Xflag = 1;			break;		case 'Z':			/*			 * use compress.			 */			gzip_program = COMPRESS_CMD;			break;		case '0':			arcname = DEV_0;			break;		case '1':			arcname = DEV_1;			break;		case '4':			arcname = DEV_4;			break;		case '5':			arcname = DEV_5;			break;		case '7':			arcname = DEV_7;			break;		case '8':			arcname = DEV_8;			break;		default:			tar_usage();			break;		}	}	argc -= optind;	argv += optind;	/* Traditional tar behaviour (pax uses stderr unless in list mode) */	if (fstdin == 1 && act == ARCHIVE)		listf = stderr;	else		listf = stdout;	/* Traditional tar behaviour (pax wants to read filelist from stdin) */	if ((act == ARCHIVE || act == APPND) && argc == 0)		exit(0);	/*	 * if we are writing (ARCHIVE) specify tar, otherwise run like pax	 * (unless -o specified)	 */	if (act == ARCHIVE || act == APPND)		frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);	else if (Oflag) {		paxwarn(1, "The -O/-o options are only valid when writing an archive");		tar_usage();		/* only valid when writing */	}	/*	 * process the args as they are interpreted by the operation mode	 */	switch (act) {	case LIST:	case EXTRACT:	default:		{			int sawpat = 0;			while (*argv != NULL) {				if (strcmp(*argv, "-C") == 0) {					if(*++argv == NULL)						break;					chdname = *argv++;					continue;				} 				if (strcmp(*argv, "-T") == 0) {					FILE *fp;					char *str;					if (*++argv == NULL)						break;					if ((fp = fopen(*argv, "r")) == NULL) {						paxwarn(1, "Unable to open file '%s' for read", *argv);						tar_usage();					}					while ((str = getline(fp)) != NULL) {						if (pat_add(str, chdname) < 0)							tar_usage();						sawpat++;					}					fclose(fp);					if (getline_error) {						paxwarn(1, "Problem with file '%s'", *argv);						tar_usage();					}					argv++;					continue;				}				if (pat_add(*argv++, chdname) < 0)					tar_usage();				sawpat++;			}			/*			 * if patterns were added, we are doing	chdir()			 * on a file-by-file basis, else, just one 			 * global chdir (if any) after opening input.			 */			if (sawpat > 0)				chdname = NULL;		}		break;	case ARCHIVE:	case APPND:		if (chdname != NULL) {	/* initial chdir() */			if (ftree_add(chdname, 1) < 0)				tar_usage();		}		while (*argv != NULL) {			if (strcmp(*argv, "-C") == 0) {				if (*++argv == NULL)					break;				if (ftree_add(*argv++, 1) < 0)					tar_usage();				continue;			}			if (strcmp(*argv, "-T") == 0) {				FILE *fp;				char *str;				if (*++argv == NULL)					break;				if ((fp = fopen(*argv, "r")) == NULL) {					paxwarn(1, "Unable to open file '%s' for read", *argv);					tar_usage();				}				while ((str = getline(fp)) != NULL) {					if (ftree_add(str, 0) < 0)						tar_usage();				}				fclose(fp);				if (getline_error) {					paxwarn(1, "Problem with file '%s'", *argv);					tar_usage();				}				argv++;				continue;			}			if (ftree_add(*argv++, 0) < 0)				tar_usage();		}		/*		 * no read errors allowed on updates/append operation!		 */		maxflt = 0;		break;	}	if (!fstdin && ((arcname == NULL) || (*arcname == '\0'))) {		arcname = getenv("TAPE");		if ((arcname == NULL) || (*arcname == '\0'))			arcname = _PATH_DEFTAPE;	}}intmkpath(path)	char *path;{	struct stat sb;	register char *slash;	int done = 0;	slash = path;	while (!done) {		slash += strspn(slash, "/");		slash += strcspn(slash, "/");		done = (*slash == '\0');		*slash = '\0';		if (stat(path, &sb)) {			if (errno != ENOENT || mkdir(path, 0777)) {				paxwarn(1, "%s", path);				return (-1);			}		} else if (!S_ISDIR(sb.st_mode)) {			syswarn(1, ENOTDIR, "%s", path);			return (-1);		}		if (!done)			*slash = '/';	}	return (0);}/* * cpio_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 */#ifdef __STDC__static voidcpio_options(register int argc, register char **argv)#elsestatic voidcpio_options(argc, argv)	register int argc;	register char **argv;#endif{	register int c, i;	char *str;	FSUB tmp;	FILE *fp;	kflag = 1;	pids = 1;	pmode = 1;	pmtime = 0;	arcname = NULL;	dflag = 1;	act = -1;	nodirs = 1;	while ((c=getopt(argc,argv,"abcdfiklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1)		switch (c) {			case 'a':				/*				 * preserve access time on files read				 */				tflag = 1;				break;			case 'b':				/*				 * swap bytes and half-words when reading data				 */				break;			case 'c':				/*				 * ASCII cpio header				 */				frmt = &(fsub[F_ACPIO]);				break;			case 'd':				/*				 * create directories as needed				 */				nodirs = 0;				break;			case 'f':				/*				 * invert meaning of pattern list				 */				cflag = 1;				break;			case 'i':				/*				 * restore an archive				 */				act = EXTRACT;				break;			case 'k':				break;			case 'l':				/*				 * use links instead of copies when possible				 */				lflag = 1;				break;			case 'm':				/*				 * preserve modification time				 */				pmtime = 1;				break;			case 'o':				/*				 * create an archive				 */				act = ARCHIVE;				frmt = &(fsub[F_CPIO]);				break;			case 'p':				/*				 * copy-pass mode				 */				act = COPY;				break;			case 'r':				/*				 * interactively rename files				 */				iflag = 1;				break;			case 's':				/*				 * swap bytes after reading data				 */				break;			case 't':				/*				 * list contents of archive				 */				act = LIST;				listf = stdout;				break;			case 'u':				/*				 * replace newer files				 */				kflag = 0;				break;			case 'v':				/*				 * verbose operation mode				 */				vflag = 1;				break;			case 'z':				/*				 * use gzip.  Non standard option.				 */				gzip_program = GZIP_CMD;				break;			case 'A':				/*				 * append mode				 */				act = APPND;				break;			case 'B':				/*				 * Use 5120 byte block size				 */				wrblksz = 5120;				break;			case 'C':				/*				 * set block size in bytes				 */				wrblksz = atoi(optarg);				break;			case 'E':				/*				 * file with patterns to extract or list				 */				if ((fp = fopen(optarg, "r")) == NULL) {					paxwarn(1, "Unable to open file '%s' for read", optarg);					cpio_usage();				}				while ((str = getline(fp)) != NULL) {					pat_add(str, NULL);				}				fclose(fp);				if (getline_error) {					paxwarn(1, "Problem with file '%s'", optarg);					cpio_usage();				}				break;			case 'F':			case 'I':			case 'O':				/*				 * filename where the archive is stored				 */				if ((optarg[0] == '-') && (optarg[1]== '\0')) {					/*					 * treat a - as stdin					 */					arcname = NULL;					break;				}				arcname = optarg;				break;			case 'H':				/*				 * 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)) != NULL)					break;				paxwarn(1, "Unknown -H format: %s", optarg);				(void)fputs("cpio: Known -H formats are:", stderr);				for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)					(void)fprintf(stderr, " %s", fsub[i].name);				(void)fputs("\n\n", stderr);				cpio_usage();				break;			case 'L':				/*				 * follow symbolic links				 */				Lflag = 1;				break;			case 'S':				/*				 * swap halfwords after reading data				 */				break;			case 'Z':				/*				 * use compress.  Non standard option.				 */				gzip_program = COMPRESS_CMD;				break;			case '6':				/*				 * process Version 6 cpio format				 */				frmt = &(fsub[F_OCPIO]);				break;			case '?':			default:				cpio_usage();				break;		}	argc -= optind;	argv += optind;	/*	 * process the args as they are interpreted by the operation mode	 */	switch (act) {		case LIST:		case EXTRACT:			while (*argv != NULL)				if (pat_add(*argv++, NULL) < 0)					cpio_usage();			break;		case COPY:			if (*argv == NULL) {				paxwarn(0, "Destination directory was not supplied");				cpio_usage();			}			dirptr = *argv;			if (mkpath(dirptr) < 0)				cpio_usage();			--argc;			++argv;			/* FALL THROUGH */		case ARCHIVE:		case APPND:			if (*argv != NULL)				cpio_usage();			/*			 * no read errors allowed on updates/append operation!			 */			maxflt = 0;			while ((str = getline(stdin)) != NULL) {				ftree_add(str, NULL);			}			if (getline_error) {				paxwarn(1, "Problem while reading stdin");				cpio_usage();			}			break;		default:			cpio_usage();			break;	}}/* * printflg() *	print out those invalid flag sets found to the user */#ifdef __STDC__static voidprintflg(unsigned int flg)#elsestatic voidprintflg(flg)	unsigned int flg;#endif{	int nxt;	int pos = 0;	(void)fprintf(stderr,"%s: Invalid combination of options:", argv0);	while ((nxt = ffs(flg)) != 0) {		flg = flg >> nxt;		pos += nxt;		(void)fprintf(stderr, " -%c", flgch[pos-1]);	}	(void)putc('\n', stderr);}/* * c_frmt() *	comparison routine used by bsearch to find the format specified *	by the user */#ifdef __STDC__static intc_frmt(const void *a, const void *b)#elsestatic intc_frmt(a, b)	void *a;	void *b;#endif{	return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name));}/* * opt_next() *	called by format specific options routines to get each format specific *	flag and value specified with -o * Return: *	pointer to next OPLIST entry or NULL (end of list). */#ifdef __STDC__OPLIST *opt_next(void)#elseOPLIST *opt_next()#endif{	OPLIST *opt;	if ((opt = ophead) != NULL)		ophead = ophead->fow;	return(opt);}/* * bad_opt() *	generic routine used to complain about a format specific options *	when the format does not support options. */#ifdef __STDC__intbad_opt(void)#elseintbad_opt()#endif{	register OPLIST *opt;	if (ophead == NULL)		return(0);	/*	 * print all we were given	 */	paxwarn(1,"These format options are not supported");	while ((opt = opt_next()) != NULL)		(void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value);	pax_usage();	return(0);}/* * opt_add() *	breaks the value supplied to -o into a option name and value. options *	are given to -o in the form -o name-value,name=value *	mulltiple -o may be specified. * Return: *	0 if format in name=value format, -1 if -o is passed junk */#ifdef __STDC__intopt_add(register char *str)#elseintopt_add(str)	register char *str;#endif{	register OPLIST *opt;	register char *frpt;	register char *pt;	register char *endpt;	if ((str == NULL) || (*str == '\0')) {		paxwarn(0, "Invalid option name");		return(-1);	}	if ((str = strdup(str)) == NULL) {		paxwarn(0, "Unable to allocate space for option list");		return(-1);	}	frpt = endpt = str;	/*	 * break into name and values pieces and stuff each one into a	 * OPLIST structure. When we know the format, the format specific	 * option function will go through this list	 */	while ((frpt != NULL) && (*frpt != '\0')) {		if ((endpt = strchr(frpt, ',')) != NULL)			*endpt = '\0';		if ((pt = strchr(frpt, '=')) == NULL) {			paxwarn(0, "Invalid options format");			free(str);			return(-1);		}		if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) {			paxwarn(0, "Unable to allocate space for option list");			free(str);			return(-1);		}		*pt++ = '\0';		opt->name = frpt;		opt->value = pt;		opt->fow = NULL;		if (endpt != NULL)			frpt = endpt + 1;		else			frpt = NULL;		if (ophead == NULL) {			optail = ophead = opt;			continue;		}		optail->fow = opt;		optail = opt;	}	return(0);}/* * str_offt() *	Convert an expression of the following forms to an off_t > 0. * 	1) A positive decimal number. *	2) A positive decimal number followed by a b (mult by 512). *	3) A positive decimal number followed by a k (mult by 1024). *	4) A positive decimal number followed by a m (mult by 512). *	5) A positive decimal number followed by a w (mult by sizeof int) *	6) Two or more positive decimal numbers (with/without k,b or w). *	   separated by x (also * for backwards compatibility), specifying *	   the product of the indicated values. * Return: *	0 for an error, a positive value o.w. */#ifdef __STDC__static off_tstr_offt(char *val)#elsestatic off_tstr_offt(val)	char *val;#endif{	char *expr;	off_t num, t;#	ifdef NET2_STAT	num = strtol(val, &expr, 0);	if ((num == LONG_MAX) || (num <= 0) || (expr == val))#	else	num = strtoq(val, &expr, 0);	if ((num == QUAD_MAX) || (num <= 0) || (expr == val))#	endif		return(0);	switch(*expr) {	case 'b':		t = num;		num *= 512;		if (t > num)			return(0);		++expr;		break;	case 'k':		t = num;		num *= 1024;		if (t > num)			return(0);		++expr;		break;	case 'm':		t = num;		num *= 1048576;		if (t > num)			return(0);		++expr;		break;	case 'w':		t = num;		num *= sizeof(int);		if (t > num)			return(0);		++expr;		break;	}	switch(*expr) {		case '\0':			break;		case '*':		case 'x':			t = num;			num *= str_offt(expr + 1);			if (t > num)				return(0);			break;		default:			return(0);	}	return(num);}#ifdef __STDC__char *getline(FILE *f)#elsechar *getline(f)	FILE *f;#endif{	char *name, *temp;	size_t len;	name = fgetln(f, &len);	if (!name) {		getline_error = ferror(f) ? GETLINE_FILE_CORRUPT : 0;		return(0);	}	if (name[len-1] != '\n')		len++;	temp = malloc(len);	if (!temp) {		getline_error = GETLINE_OUT_OF_MEM;		return(0);	}	memcpy(temp, name, len-1);	temp[len-1] = 0;	return(temp);}