options.c revision 72089
11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1992 Keith Muller. 31556Srgrimes * Copyright (c) 1992, 1993 41556Srgrimes * The Regents of the University of California. All rights reserved. 51556Srgrimes * 61556Srgrimes * This code is derived from software contributed to Berkeley by 71556Srgrimes * Keith Muller of the University of California, San Diego. 81556Srgrimes * 91556Srgrimes * Redistribution and use in source and binary forms, with or without 101556Srgrimes * modification, are permitted provided that the following conditions 111556Srgrimes * are met: 121556Srgrimes * 1. Redistributions of source code must retain the above copyright 131556Srgrimes * notice, this list of conditions and the following disclaimer. 141556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151556Srgrimes * notice, this list of conditions and the following disclaimer in the 161556Srgrimes * documentation and/or other materials provided with the distribution. 171556Srgrimes * 3. All advertising materials mentioning features or use of this software 181556Srgrimes * must display the following acknowledgement: 191556Srgrimes * This product includes software developed by the University of 201556Srgrimes * California, Berkeley and its contributors. 211556Srgrimes * 4. Neither the name of the University nor the names of its contributors 221556Srgrimes * may be used to endorse or promote products derived from this software 231556Srgrimes * without specific prior written permission. 241556Srgrimes * 251556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 261556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 271556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 281556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 291556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 301556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 311556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 321556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 331556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 341556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 351556Srgrimes * SUCH DAMAGE. 361556Srgrimes */ 371556Srgrimes 381556Srgrimes#ifndef lint 3936049Scharnier#if 0 4036049Scharnierstatic char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; 4136049Scharnier#endif 4236049Scharnierstatic const char rcsid[] = 4350471Speter "$FreeBSD: head/bin/pax/options.c 72089 2001-02-06 10:39:38Z asmodai $"; 441556Srgrimes#endif /* not lint */ 451556Srgrimes 461556Srgrimes#include <sys/types.h> 471556Srgrimes#include <sys/stat.h> 481556Srgrimes#include <sys/mtio.h> 491556Srgrimes#include <stdio.h> 501556Srgrimes#include <string.h> 511556Srgrimes#include <unistd.h> 521556Srgrimes#include <stdlib.h> 531556Srgrimes#include <limits.h> 541556Srgrimes#include "pax.h" 551556Srgrimes#include "options.h" 561556Srgrimes#include "cpio.h" 571556Srgrimes#include "tar.h" 581556Srgrimes#include "extern.h" 591556Srgrimes 601556Srgrimes/* 611556Srgrimes * Routines which handle command line options 621556Srgrimes */ 631556Srgrimes 641556Srgrimesstatic char flgch[] = FLGCH; /* list of all possible flags */ 651556Srgrimesstatic OPLIST *ophead = NULL; /* head for format specific options -x */ 661556Srgrimesstatic OPLIST *optail = NULL; /* option tail */ 671556Srgrimes 681556Srgrimesstatic int no_op __P((void)); 691556Srgrimesstatic void printflg __P((unsigned int)); 701556Srgrimesstatic int c_frmt __P((const void *, const void *)); 711556Srgrimesstatic off_t str_offt __P((char *)); 721556Srgrimesstatic void pax_options __P((register int, register char **)); 731556Srgrimesstatic void pax_usage __P((void)); 741556Srgrimesstatic void tar_options __P((register int, register char **)); 751556Srgrimesstatic void tar_usage __P((void)); 761556Srgrimes#ifdef notdef 771556Srgrimesstatic void cpio_options __P((register int, register char **)); 781556Srgrimesstatic void cpio_usage __P((void)); 791556Srgrimes#endif 801556Srgrimes 811556Srgrimes/* 821556Srgrimes * Format specific routine table - MUST BE IN SORTED ORDER BY NAME 831556Srgrimes * (see pax.h for description of each function) 841556Srgrimes * 851556Srgrimes * name, blksz, hdsz, udev, hlk, blkagn, inhead, id, st_read, 861556Srgrimes * read, end_read, st_write, write, end_write, trail, 871556Srgrimes * rd_data, wr_data, options 881556Srgrimes */ 891556Srgrimes 901556SrgrimesFSUB fsub[] = { 911556Srgrimes/* 0: OLD BINARY CPIO */ 927165Sjoerg {"bcpio", 5120, sizeof(HD_BCPIO), 1, 0, 0, 1, bcpio_id, cpio_strd, 931556Srgrimes bcpio_rd, bcpio_endrd, cpio_stwr, bcpio_wr, cpio_endwr, cpio_trail, 947165Sjoerg rd_wrfile, wr_rdfile, bad_opt}, 951556Srgrimes 961556Srgrimes/* 1: OLD OCTAL CHARACTER CPIO */ 977165Sjoerg {"cpio", 5120, sizeof(HD_CPIO), 1, 0, 0, 1, cpio_id, cpio_strd, 981556Srgrimes cpio_rd, cpio_endrd, cpio_stwr, cpio_wr, cpio_endwr, cpio_trail, 997165Sjoerg rd_wrfile, wr_rdfile, bad_opt}, 1001556Srgrimes 1011556Srgrimes/* 2: SVR4 HEX CPIO */ 1027165Sjoerg {"sv4cpio", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, vcpio_id, cpio_strd, 1031556Srgrimes vcpio_rd, vcpio_endrd, cpio_stwr, vcpio_wr, cpio_endwr, cpio_trail, 1047165Sjoerg rd_wrfile, wr_rdfile, bad_opt}, 1051556Srgrimes 1061556Srgrimes/* 3: SVR4 HEX CPIO WITH CRC */ 1077165Sjoerg {"sv4crc", 5120, sizeof(HD_VCPIO), 1, 0, 0, 1, crc_id, crc_strd, 1081556Srgrimes vcpio_rd, vcpio_endrd, crc_stwr, vcpio_wr, cpio_endwr, cpio_trail, 1097165Sjoerg rd_wrfile, wr_rdfile, bad_opt}, 1101556Srgrimes 1111556Srgrimes/* 4: OLD TAR */ 1127165Sjoerg {"tar", 10240, BLKMULT, 0, 1, BLKMULT, 0, tar_id, no_op, 1131556Srgrimes tar_rd, tar_endrd, no_op, tar_wr, tar_endwr, tar_trail, 1147165Sjoerg rd_wrfile, wr_rdfile, tar_opt}, 1151556Srgrimes 1161556Srgrimes/* 5: POSIX USTAR */ 1177165Sjoerg {"ustar", 10240, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, ustar_strd, 1181556Srgrimes ustar_rd, tar_endrd, ustar_stwr, ustar_wr, tar_endwr, tar_trail, 1197165Sjoerg rd_wrfile, wr_rdfile, bad_opt}, 1201556Srgrimes}; 1211556Srgrimes#define F_TAR 4 /* format when called as tar */ 1221556Srgrimes#define DEFLT 5 /* default write format from list above */ 1231556Srgrimes 1241556Srgrimes/* 1251556Srgrimes * ford is the archive search order used by get_arc() to determine what kind 1261556Srgrimes * of archive we are dealing with. This helps to properly id archive formats 1271556Srgrimes * some formats may be subsets of others.... 1281556Srgrimes */ 1291556Srgrimesint ford[] = {5, 4, 3, 2, 1, 0, -1 }; 1301556Srgrimes 1311556Srgrimes/* 1321556Srgrimes * options() 1331556Srgrimes * figure out if we are pax, tar or cpio. Call the appropriate options 1341556Srgrimes * parser 1351556Srgrimes */ 1361556Srgrimes 1371556Srgrimes#if __STDC__ 1381556Srgrimesvoid 1391556Srgrimesoptions(register int argc, register char **argv) 1401556Srgrimes#else 1411556Srgrimesvoid 1421556Srgrimesoptions(argc, argv) 1431556Srgrimes register int argc; 1441556Srgrimes register char **argv; 1451556Srgrimes#endif 1461556Srgrimes{ 1471556Srgrimes 1481556Srgrimes /* 1491556Srgrimes * Are we acting like pax, tar or cpio (based on argv[0]) 1501556Srgrimes */ 1511556Srgrimes if ((argv0 = strrchr(argv[0], '/')) != NULL) 1521556Srgrimes argv0++; 1531556Srgrimes else 1541556Srgrimes argv0 = argv[0]; 1551556Srgrimes 1561556Srgrimes if (strcmp(NM_TAR, argv0) == 0) 1571556Srgrimes return(tar_options(argc, argv)); 1581556Srgrimes# ifdef notdef 1591556Srgrimes else if (strcmp(NM_CPIO, argv0) == 0) 1601556Srgrimes return(cpio_options(argc, argv)); 1611556Srgrimes# endif 1621556Srgrimes /* 1631556Srgrimes * assume pax as the default 1641556Srgrimes */ 1651556Srgrimes argv0 = NM_PAX; 1661556Srgrimes return(pax_options(argc, argv)); 1671556Srgrimes} 1681556Srgrimes 1691556Srgrimes/* 1701556Srgrimes * pax_options() 1711556Srgrimes * look at the user specified flags. set globals as required and check if 1721556Srgrimes * the user specified a legal set of flags. If not, complain and exit 1731556Srgrimes */ 1741556Srgrimes 1751556Srgrimes#if __STDC__ 1761556Srgrimesstatic void 1771556Srgrimespax_options(register int argc, register char **argv) 1781556Srgrimes#else 1791556Srgrimesstatic void 1801556Srgrimespax_options(argc, argv) 1811556Srgrimes register int argc; 1821556Srgrimes register char **argv; 1831556Srgrimes#endif 1841556Srgrimes{ 1851556Srgrimes register int c; 1861556Srgrimes register int i; 1871556Srgrimes unsigned int flg = 0; 1881556Srgrimes unsigned int bflg = 0; 1891556Srgrimes register char *pt; 1901556Srgrimes FSUB tmp; 1911556Srgrimes 1921556Srgrimes /* 1931556Srgrimes * process option flags 1941556Srgrimes */ 1951556Srgrimes while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:B:DE:G:HLPT:U:XYZ")) 19624348Simp != -1) { 1971556Srgrimes switch (c) { 1981556Srgrimes case 'a': 1991556Srgrimes /* 2001556Srgrimes * append 2011556Srgrimes */ 2021556Srgrimes flg |= AF; 2031556Srgrimes break; 2041556Srgrimes case 'b': 2051556Srgrimes /* 2061556Srgrimes * specify blocksize 2071556Srgrimes */ 2081556Srgrimes flg |= BF; 2091556Srgrimes if ((wrblksz = (int)str_offt(optarg)) <= 0) { 21028904Ssos pax_warn(1, "Invalid block size %s", optarg); 2111556Srgrimes pax_usage(); 2121556Srgrimes } 2131556Srgrimes break; 2141556Srgrimes case 'c': 2151556Srgrimes /* 2161556Srgrimes * inverse match on patterns 2171556Srgrimes */ 2181556Srgrimes cflag = 1; 2191556Srgrimes flg |= CF; 2201556Srgrimes break; 2211556Srgrimes case 'd': 2221556Srgrimes /* 2231556Srgrimes * match only dir on extract, not the subtree at dir 2241556Srgrimes */ 2251556Srgrimes dflag = 1; 2261556Srgrimes flg |= DF; 2271556Srgrimes break; 2281556Srgrimes case 'f': 2291556Srgrimes /* 2301556Srgrimes * filename where the archive is stored 2311556Srgrimes */ 2321556Srgrimes arcname = optarg; 2331556Srgrimes flg |= FF; 2341556Srgrimes break; 2351556Srgrimes case 'i': 2361556Srgrimes /* 2371556Srgrimes * interactive file rename 2381556Srgrimes */ 2391556Srgrimes iflag = 1; 2401556Srgrimes flg |= IF; 2411556Srgrimes break; 2421556Srgrimes case 'k': 2431556Srgrimes /* 2441556Srgrimes * do not clobber files that exist 2451556Srgrimes */ 2461556Srgrimes kflag = 1; 2471556Srgrimes flg |= KF; 2481556Srgrimes break; 2491556Srgrimes case 'l': 2501556Srgrimes /* 2511556Srgrimes * try to link src to dest with copy (-rw) 2521556Srgrimes */ 2531556Srgrimes lflag = 1; 2541556Srgrimes flg |= LF; 2551556Srgrimes break; 2561556Srgrimes case 'n': 2571556Srgrimes /* 2581556Srgrimes * select first match for a pattern only 2591556Srgrimes */ 2601556Srgrimes nflag = 1; 2611556Srgrimes flg |= NF; 2621556Srgrimes break; 2631556Srgrimes case 'o': 2641556Srgrimes /* 2651556Srgrimes * pass format specific options 2661556Srgrimes */ 2671556Srgrimes flg |= OF; 2681556Srgrimes if (opt_add(optarg) < 0) 2691556Srgrimes pax_usage(); 2701556Srgrimes break; 2711556Srgrimes case 'p': 2721556Srgrimes /* 2731556Srgrimes * specify file characteristic options 2741556Srgrimes */ 2751556Srgrimes for (pt = optarg; *pt != '\0'; ++pt) { 2761556Srgrimes switch(*pt) { 2771556Srgrimes case 'a': 2781556Srgrimes /* 2791556Srgrimes * do not preserve access time 2801556Srgrimes */ 2811556Srgrimes patime = 0; 2821556Srgrimes break; 2831556Srgrimes case 'e': 2841556Srgrimes /* 2851556Srgrimes * preserve user id, group id, file 2861556Srgrimes * mode, access/modification times 2871556Srgrimes */ 2881556Srgrimes pids = 1; 2891556Srgrimes pmode = 1; 2901556Srgrimes patime = 1; 2911556Srgrimes pmtime = 1; 2921556Srgrimes break; 2931556Srgrimes case 'm': 2941556Srgrimes /* 2951556Srgrimes * do not preserve modification time 2961556Srgrimes */ 2971556Srgrimes pmtime = 0; 2981556Srgrimes break; 2991556Srgrimes case 'o': 3001556Srgrimes /* 3011556Srgrimes * preserve uid/gid 3021556Srgrimes */ 3031556Srgrimes pids = 1; 3041556Srgrimes break; 3051556Srgrimes case 'p': 3061556Srgrimes /* 3071556Srgrimes * preserver file mode bits 3081556Srgrimes */ 3091556Srgrimes pmode = 1; 3101556Srgrimes break; 3111556Srgrimes default: 31228904Ssos pax_warn(1, "Invalid -p string: %c", *pt); 3131556Srgrimes pax_usage(); 3141556Srgrimes break; 3151556Srgrimes } 3161556Srgrimes } 3171556Srgrimes flg |= PF; 3181556Srgrimes break; 3191556Srgrimes case 'r': 3201556Srgrimes /* 3211556Srgrimes * read the archive 3221556Srgrimes */ 3231556Srgrimes flg |= RF; 3241556Srgrimes break; 3251556Srgrimes case 's': 3261556Srgrimes /* 3271556Srgrimes * file name substitution name pattern 3281556Srgrimes */ 3291556Srgrimes if (rep_add(optarg) < 0) { 3301556Srgrimes pax_usage(); 3311556Srgrimes break; 3321556Srgrimes } 3331556Srgrimes flg |= SF; 3341556Srgrimes break; 3351556Srgrimes case 't': 3361556Srgrimes /* 3371556Srgrimes * preserve access time on filesystem nodes we read 3381556Srgrimes */ 3391556Srgrimes tflag = 1; 3401556Srgrimes flg |= TF; 3411556Srgrimes break; 3421556Srgrimes case 'u': 3431556Srgrimes /* 3441556Srgrimes * ignore those older files 3451556Srgrimes */ 3461556Srgrimes uflag = 1; 3471556Srgrimes flg |= UF; 3481556Srgrimes break; 3491556Srgrimes case 'v': 3501556Srgrimes /* 3511556Srgrimes * verbose operation mode 3521556Srgrimes */ 3531556Srgrimes vflag = 1; 3541556Srgrimes flg |= VF; 3551556Srgrimes break; 3561556Srgrimes case 'w': 3571556Srgrimes /* 3581556Srgrimes * write an archive 3591556Srgrimes */ 3601556Srgrimes flg |= WF; 3611556Srgrimes break; 3621556Srgrimes case 'x': 3631556Srgrimes /* 3641556Srgrimes * specify an archive format on write 3651556Srgrimes */ 3661556Srgrimes tmp.name = optarg; 3677165Sjoerg if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, 3687165Sjoerg sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt))) { 3691556Srgrimes flg |= XF; 3701556Srgrimes break; 3711556Srgrimes } 37228904Ssos pax_warn(1, "Unknown -x format: %s", optarg); 3731556Srgrimes (void)fputs("pax: Known -x formats are:", stderr); 3741556Srgrimes for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) 3751556Srgrimes (void)fprintf(stderr, " %s", fsub[i].name); 3761556Srgrimes (void)fputs("\n\n", stderr); 3771556Srgrimes pax_usage(); 3781556Srgrimes break; 3791556Srgrimes case 'B': 3801556Srgrimes /* 3811556Srgrimes * non-standard option on number of bytes written on a 3821556Srgrimes * single archive volume. 3831556Srgrimes */ 3841556Srgrimes if ((wrlimit = str_offt(optarg)) <= 0) { 38528904Ssos pax_warn(1, "Invalid write limit %s", optarg); 3861556Srgrimes pax_usage(); 3871556Srgrimes } 3881556Srgrimes if (wrlimit % BLKMULT) { 38928904Ssos pax_warn(1, "Write limit is not a %d byte multiple", 3901556Srgrimes BLKMULT); 3911556Srgrimes pax_usage(); 3921556Srgrimes } 3931556Srgrimes flg |= CBF; 3941556Srgrimes break; 3951556Srgrimes case 'D': 3961556Srgrimes /* 3971556Srgrimes * On extraction check file inode change time before the 3981556Srgrimes * modification of the file name. Non standard option. 3991556Srgrimes */ 4001556Srgrimes Dflag = 1; 4011556Srgrimes flg |= CDF; 4021556Srgrimes break; 4031556Srgrimes case 'E': 4041556Srgrimes /* 4051556Srgrimes * non-standard limit on read faults 4061556Srgrimes * 0 indicates stop after first error, values 4071556Srgrimes * indicate a limit, "NONE" try forever 4081556Srgrimes */ 4091556Srgrimes flg |= CEF; 4101556Srgrimes if (strcmp(NONE, optarg) == 0) 4111556Srgrimes maxflt = -1; 4121556Srgrimes else if ((maxflt = atoi(optarg)) < 0) { 41328904Ssos pax_warn(1, "Error count value must be positive"); 4141556Srgrimes pax_usage(); 4151556Srgrimes } 4161556Srgrimes break; 4171556Srgrimes case 'G': 4181556Srgrimes /* 4191556Srgrimes * non-standard option for selecting files within an 4201556Srgrimes * archive by group (gid or name) 4211556Srgrimes */ 4221556Srgrimes if (grp_add(optarg) < 0) { 4231556Srgrimes pax_usage(); 4241556Srgrimes break; 4251556Srgrimes } 4261556Srgrimes flg |= CGF; 4271556Srgrimes break; 4281556Srgrimes case 'H': 4291556Srgrimes /* 4301556Srgrimes * follow command line symlinks only 4311556Srgrimes */ 4321556Srgrimes Hflag = 1; 4331556Srgrimes flg |= CHF; 4341556Srgrimes break; 4351556Srgrimes case 'L': 4361556Srgrimes /* 4371556Srgrimes * follow symlinks 4381556Srgrimes */ 4391556Srgrimes Lflag = 1; 4401556Srgrimes flg |= CLF; 4411556Srgrimes break; 4421556Srgrimes case 'P': 4431556Srgrimes /* 4441556Srgrimes * do NOT follow symlinks (default) 4451556Srgrimes */ 4461556Srgrimes Lflag = 0; 4471556Srgrimes flg |= CPF; 4481556Srgrimes break; 4491556Srgrimes case 'T': 4501556Srgrimes /* 4511556Srgrimes * non-standard option for selecting files within an 4521556Srgrimes * archive by modification time range (lower,upper) 4531556Srgrimes */ 4541556Srgrimes if (trng_add(optarg) < 0) { 4551556Srgrimes pax_usage(); 4561556Srgrimes break; 4571556Srgrimes } 4581556Srgrimes flg |= CTF; 4591556Srgrimes break; 4601556Srgrimes case 'U': 4611556Srgrimes /* 4621556Srgrimes * non-standard option for selecting files within an 4631556Srgrimes * archive by user (uid or name) 4641556Srgrimes */ 4651556Srgrimes if (usr_add(optarg) < 0) { 4661556Srgrimes pax_usage(); 4671556Srgrimes break; 4681556Srgrimes } 4691556Srgrimes flg |= CUF; 4701556Srgrimes break; 4711556Srgrimes case 'X': 4721556Srgrimes /* 4731556Srgrimes * do not pass over mount points in the file system 4741556Srgrimes */ 4751556Srgrimes Xflag = 1; 4761556Srgrimes flg |= CXF; 4771556Srgrimes break; 4781556Srgrimes case 'Y': 4791556Srgrimes /* 4801556Srgrimes * On extraction check file inode change time after the 4811556Srgrimes * modification of the file name. Non standard option. 4821556Srgrimes */ 4831556Srgrimes Yflag = 1; 4841556Srgrimes flg |= CYF; 4851556Srgrimes break; 4861556Srgrimes case 'Z': 4871556Srgrimes /* 4881556Srgrimes * On extraction check modification time after the 4891556Srgrimes * modification of the file name. Non standard option. 4901556Srgrimes */ 4911556Srgrimes Zflag = 1; 4921556Srgrimes flg |= CZF; 4931556Srgrimes break; 4941556Srgrimes case '?': 4951556Srgrimes default: 4961556Srgrimes pax_usage(); 4971556Srgrimes break; 4981556Srgrimes } 4991556Srgrimes } 5001556Srgrimes 5011556Srgrimes /* 5021556Srgrimes * figure out the operation mode of pax read,write,extract,copy,append 5031556Srgrimes * or list. check that we have not been given a bogus set of flags 5041556Srgrimes * for the operation mode. 5051556Srgrimes */ 5061556Srgrimes if (ISLIST(flg)) { 5071556Srgrimes act = LIST; 5081556Srgrimes bflg = flg & BDLIST; 5091556Srgrimes } else if (ISEXTRACT(flg)) { 5101556Srgrimes act = EXTRACT; 5111556Srgrimes bflg = flg & BDEXTR; 5121556Srgrimes } else if (ISARCHIVE(flg)) { 5131556Srgrimes act = ARCHIVE; 5141556Srgrimes bflg = flg & BDARCH; 5151556Srgrimes } else if (ISAPPND(flg)) { 5161556Srgrimes act = APPND; 5171556Srgrimes bflg = flg & BDARCH; 5181556Srgrimes } else if (ISCOPY(flg)) { 5191556Srgrimes act = COPY; 5201556Srgrimes bflg = flg & BDCOPY; 5211556Srgrimes } else 5221556Srgrimes pax_usage(); 5231556Srgrimes if (bflg) { 5241556Srgrimes printflg(flg); 5251556Srgrimes pax_usage(); 5261556Srgrimes } 5271556Srgrimes 5281556Srgrimes /* 5291556Srgrimes * if we are writing (ARCHIVE) we use the default format if the user 5301556Srgrimes * did not specify a format. when we write during an APPEND, we will 5311556Srgrimes * adopt the format of the existing archive if none was supplied. 5321556Srgrimes */ 5331556Srgrimes if (!(flg & XF) && (act == ARCHIVE)) 5341556Srgrimes frmt = &(fsub[DEFLT]); 5351556Srgrimes 5361556Srgrimes /* 5371556Srgrimes * process the args as they are interpreted by the operation mode 5381556Srgrimes */ 5391556Srgrimes switch (act) { 5401556Srgrimes case LIST: 5411556Srgrimes case EXTRACT: 5421556Srgrimes for (; optind < argc; optind++) 5431556Srgrimes if (pat_add(argv[optind]) < 0) 5441556Srgrimes pax_usage(); 5451556Srgrimes break; 5461556Srgrimes case COPY: 5471556Srgrimes if (optind >= argc) { 54828904Ssos pax_warn(0, "Destination directory was not supplied"); 5491556Srgrimes pax_usage(); 5501556Srgrimes } 5511556Srgrimes --argc; 5521556Srgrimes dirptr = argv[argc]; 5531556Srgrimes /* FALL THROUGH */ 5541556Srgrimes case ARCHIVE: 5551556Srgrimes case APPND: 5561556Srgrimes for (; optind < argc; optind++) 5571556Srgrimes if (ftree_add(argv[optind]) < 0) 5581556Srgrimes pax_usage(); 5591556Srgrimes /* 5601556Srgrimes * no read errors allowed on updates/append operation! 5611556Srgrimes */ 5621556Srgrimes maxflt = 0; 5631556Srgrimes break; 5641556Srgrimes } 5651556Srgrimes} 5661556Srgrimes 5671556Srgrimes 5681556Srgrimes/* 5691556Srgrimes * tar_options() 5701556Srgrimes * look at the user specified flags. set globals as required and check if 5711556Srgrimes * the user specified a legal set of flags. If not, complain and exit 5721556Srgrimes */ 5731556Srgrimes 5741556Srgrimes#if __STDC__ 5751556Srgrimesstatic void 5761556Srgrimestar_options(register int argc, register char **argv) 5771556Srgrimes#else 5781556Srgrimesstatic void 5791556Srgrimestar_options(argc, argv) 5801556Srgrimes register int argc; 5811556Srgrimes register char **argv; 5821556Srgrimes#endif 5831556Srgrimes{ 5841556Srgrimes register char *cp; 5851556Srgrimes int fstdin = 0; 5861556Srgrimes 5871556Srgrimes if (argc < 2) 5881556Srgrimes tar_usage(); 5891556Srgrimes /* 5901556Srgrimes * process option flags 5911556Srgrimes */ 5921556Srgrimes ++argv; 5931556Srgrimes for (cp = *argv++; *cp != '\0'; ++cp) { 5941556Srgrimes switch (*cp) { 5951556Srgrimes case '-': 5961556Srgrimes /* 5971556Srgrimes * skip over - 5981556Srgrimes */ 5991556Srgrimes break; 6001556Srgrimes case 'b': 6011556Srgrimes /* 6021556Srgrimes * specify blocksize 6031556Srgrimes */ 6041556Srgrimes if (*argv == (char *)NULL) { 60528904Ssos pax_warn(1,"blocksize must be specified with 'b'"); 6061556Srgrimes tar_usage(); 6071556Srgrimes } 6081556Srgrimes if ((wrblksz = (int)str_offt(*argv)) <= 0) { 60928904Ssos pax_warn(1, "Invalid block size %s", *argv); 6101556Srgrimes tar_usage(); 6111556Srgrimes } 6121556Srgrimes ++argv; 6131556Srgrimes break; 6141556Srgrimes case 'c': 6151556Srgrimes /* 6161556Srgrimes * create an archive 6171556Srgrimes */ 6181556Srgrimes act = ARCHIVE; 6191556Srgrimes break; 6201556Srgrimes case 'e': 6211556Srgrimes /* 6221556Srgrimes * stop after first error 6231556Srgrimes */ 6241556Srgrimes maxflt = 0; 6251556Srgrimes break; 6261556Srgrimes case 'f': 6271556Srgrimes /* 6281556Srgrimes * filename where the archive is stored 6291556Srgrimes */ 6301556Srgrimes if (*argv == (char *)NULL) { 63128904Ssos pax_warn(1, "filename must be specified with 'f'"); 6321556Srgrimes tar_usage(); 6331556Srgrimes } 6341556Srgrimes if ((argv[0][0] == '-') && (argv[0][1]== '\0')) { 6351556Srgrimes /* 6361556Srgrimes * treat a - as stdin 6371556Srgrimes */ 6381556Srgrimes ++argv; 6391556Srgrimes ++fstdin; 6401556Srgrimes arcname = (char *)0; 6411556Srgrimes break; 6421556Srgrimes } 6431556Srgrimes fstdin = 0; 6441556Srgrimes arcname = *argv++; 6451556Srgrimes break; 6461556Srgrimes case 'm': 6471556Srgrimes /* 6481556Srgrimes * do not preserve modification time 6491556Srgrimes */ 6501556Srgrimes pmtime = 0; 6511556Srgrimes break; 6521556Srgrimes case 'o': 6531556Srgrimes if (opt_add("write_opt=nodir") < 0) 6541556Srgrimes tar_usage(); 6551556Srgrimes break; 6561556Srgrimes case 'p': 6571556Srgrimes /* 6581556Srgrimes * preserve user id, group id, file 6591556Srgrimes * mode, access/modification times 6601556Srgrimes */ 6611556Srgrimes pids = 1; 6621556Srgrimes pmode = 1; 6631556Srgrimes patime = 1; 6641556Srgrimes pmtime = 1; 6651556Srgrimes break; 6661556Srgrimes case 'r': 6671556Srgrimes case 'u': 6681556Srgrimes /* 6691556Srgrimes * append to the archive 6701556Srgrimes */ 6711556Srgrimes act = APPND; 6721556Srgrimes break; 6731556Srgrimes case 't': 6741556Srgrimes /* 6751556Srgrimes * list contents of the tape 6761556Srgrimes */ 6771556Srgrimes act = LIST; 6781556Srgrimes break; 6791556Srgrimes case 'v': 6801556Srgrimes /* 6811556Srgrimes * verbose operation mode 6821556Srgrimes */ 6831556Srgrimes vflag = 1; 6841556Srgrimes break; 6851556Srgrimes case 'w': 6861556Srgrimes /* 6871556Srgrimes * interactive file rename 6881556Srgrimes */ 6891556Srgrimes iflag = 1; 6901556Srgrimes break; 6911556Srgrimes case 'x': 6921556Srgrimes /* 6931556Srgrimes * write an archive 6941556Srgrimes */ 6951556Srgrimes act = EXTRACT; 6961556Srgrimes break; 6971556Srgrimes case 'B': 6981556Srgrimes /* 6991556Srgrimes * Nothing to do here, this is pax default 7001556Srgrimes */ 7011556Srgrimes break; 7021556Srgrimes case 'H': 7031556Srgrimes /* 7041556Srgrimes * follow command line symlinks only 7051556Srgrimes */ 7061556Srgrimes Hflag = 1; 7071556Srgrimes break; 7081556Srgrimes case 'L': 7091556Srgrimes /* 7101556Srgrimes * follow symlinks 7111556Srgrimes */ 7121556Srgrimes Lflag = 1; 7131556Srgrimes break; 7141556Srgrimes case 'P': 7151556Srgrimes /* 7161556Srgrimes * do not follow symlinks 7171556Srgrimes */ 7181556Srgrimes Lflag = 0; 7191556Srgrimes break; 7201556Srgrimes case 'X': 7211556Srgrimes /* 7221556Srgrimes * do not pass over mount points in the file system 7231556Srgrimes */ 7241556Srgrimes Xflag = 1; 7251556Srgrimes break; 7261556Srgrimes case '0': 7271556Srgrimes arcname = DEV_0; 7281556Srgrimes break; 7291556Srgrimes case '1': 7301556Srgrimes arcname = DEV_1; 7311556Srgrimes break; 7321556Srgrimes case '4': 7331556Srgrimes arcname = DEV_4; 7341556Srgrimes break; 7351556Srgrimes case '5': 7361556Srgrimes arcname = DEV_5; 7371556Srgrimes break; 7381556Srgrimes case '7': 7391556Srgrimes arcname = DEV_7; 7401556Srgrimes break; 7411556Srgrimes case '8': 7421556Srgrimes arcname = DEV_8; 7431556Srgrimes break; 7441556Srgrimes default: 7451556Srgrimes tar_usage(); 7461556Srgrimes break; 7471556Srgrimes } 7481556Srgrimes } 7491556Srgrimes 7501556Srgrimes /* 7511556Srgrimes * if we are writing (ARCHIVE) specify tar, otherwise run like pax 7521556Srgrimes */ 7531556Srgrimes if (act == ARCHIVE) 7541556Srgrimes frmt = &(fsub[F_TAR]); 7551556Srgrimes 7561556Srgrimes /* 7571556Srgrimes * process the args as they are interpreted by the operation mode 7581556Srgrimes */ 7591556Srgrimes switch (act) { 7601556Srgrimes case LIST: 7611556Srgrimes case EXTRACT: 7621556Srgrimes default: 7631556Srgrimes while (*argv != (char *)NULL) 7641556Srgrimes if (pat_add(*argv++) < 0) 7651556Srgrimes tar_usage(); 7661556Srgrimes break; 7671556Srgrimes case ARCHIVE: 7681556Srgrimes case APPND: 7691556Srgrimes while (*argv != (char *)NULL) 7701556Srgrimes if (ftree_add(*argv++) < 0) 7711556Srgrimes tar_usage(); 7721556Srgrimes /* 7731556Srgrimes * no read errors allowed on updates/append operation! 7741556Srgrimes */ 7751556Srgrimes maxflt = 0; 7761556Srgrimes break; 7771556Srgrimes } 7781556Srgrimes if (!fstdin && ((arcname == (char *)NULL) || (*arcname == '\0'))) { 7791556Srgrimes arcname = getenv("TAPE"); 7801556Srgrimes if ((arcname == (char *)NULL) || (*arcname == '\0')) 7811556Srgrimes arcname = DEV_8; 7821556Srgrimes } 7831556Srgrimes} 7841556Srgrimes 7851556Srgrimes#ifdef notdef 7861556Srgrimes/* 7871556Srgrimes * cpio_options() 7881556Srgrimes * look at the user specified flags. set globals as required and check if 7891556Srgrimes * the user specified a legal set of flags. If not, complain and exit 7901556Srgrimes */ 7911556Srgrimes 7921556Srgrimes#if __STDC__ 7931556Srgrimesstatic void 7941556Srgrimescpio_options(register int argc, register char **argv) 7951556Srgrimes#else 7961556Srgrimesstatic void 7971556Srgrimescpio_options(argc, argv) 7981556Srgrimes register int argc; 7991556Srgrimes register char **argv; 8001556Srgrimes#endif 8011556Srgrimes{ 8021556Srgrimes} 8031556Srgrimes#endif 8041556Srgrimes 8051556Srgrimes/* 8061556Srgrimes * printflg() 8071556Srgrimes * print out those invalid flag sets found to the user 8081556Srgrimes */ 8091556Srgrimes 8101556Srgrimes#if __STDC__ 8111556Srgrimesstatic void 8121556Srgrimesprintflg(unsigned int flg) 8131556Srgrimes#else 8141556Srgrimesstatic void 8151556Srgrimesprintflg(flg) 8161556Srgrimes unsigned int flg; 8171556Srgrimes#endif 8181556Srgrimes{ 8191556Srgrimes int nxt; 8201556Srgrimes int pos = 0; 8211556Srgrimes 8221556Srgrimes (void)fprintf(stderr,"%s: Invalid combination of options:", argv0); 8237165Sjoerg while ((nxt = ffs(flg))) { 8241556Srgrimes flg = flg >> nxt; 8251556Srgrimes pos += nxt; 8261556Srgrimes (void)fprintf(stderr, " -%c", flgch[pos-1]); 8271556Srgrimes } 8281556Srgrimes (void)putc('\n', stderr); 8291556Srgrimes} 8301556Srgrimes 8311556Srgrimes/* 8321556Srgrimes * c_frmt() 8331556Srgrimes * comparison routine used by bsearch to find the format specified 8341556Srgrimes * by the user 8351556Srgrimes */ 8361556Srgrimes 8371556Srgrimes#if __STDC__ 8381556Srgrimesstatic int 8391556Srgrimesc_frmt(const void *a, const void *b) 8401556Srgrimes#else 8411556Srgrimesstatic int 8421556Srgrimesc_frmt(a, b) 8431556Srgrimes void *a; 8441556Srgrimes void *b; 8451556Srgrimes#endif 8461556Srgrimes{ 8471556Srgrimes return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); 8481556Srgrimes} 8491556Srgrimes 8501556Srgrimes/* 8511556Srgrimes * opt_next() 8521556Srgrimes * called by format specific options routines to get each format specific 8531556Srgrimes * flag and value specified with -o 8541556Srgrimes * Return: 8551556Srgrimes * pointer to next OPLIST entry or NULL (end of list). 8561556Srgrimes */ 8571556Srgrimes 8581556Srgrimes#if __STDC__ 8591556SrgrimesOPLIST * 8601556Srgrimesopt_next(void) 8611556Srgrimes#else 8621556SrgrimesOPLIST * 8631556Srgrimesopt_next() 8641556Srgrimes#endif 8651556Srgrimes{ 8661556Srgrimes OPLIST *opt; 8671556Srgrimes 8681556Srgrimes if ((opt = ophead) != NULL) 8691556Srgrimes ophead = ophead->fow; 8701556Srgrimes return(opt); 8711556Srgrimes} 8721556Srgrimes 8731556Srgrimes/* 8741556Srgrimes * bad_opt() 8751556Srgrimes * generic routine used to complain about a format specific options 8761556Srgrimes * when the format does not support options. 8771556Srgrimes */ 8781556Srgrimes 8791556Srgrimes#if __STDC__ 8801556Srgrimesint 8811556Srgrimesbad_opt(void) 8821556Srgrimes#else 8831556Srgrimesint 8841556Srgrimesbad_opt() 8851556Srgrimes#endif 8861556Srgrimes{ 8871556Srgrimes register OPLIST *opt; 8881556Srgrimes 8891556Srgrimes if (ophead == NULL) 8901556Srgrimes return(0); 8911556Srgrimes /* 8921556Srgrimes * print all we were given 8931556Srgrimes */ 89428904Ssos pax_warn(1,"These format options are not supported"); 8951556Srgrimes while ((opt = opt_next()) != NULL) 8961556Srgrimes (void)fprintf(stderr, "\t%s = %s\n", opt->name, opt->value); 8971556Srgrimes pax_usage(); 8981556Srgrimes return(0); 8991556Srgrimes} 9001556Srgrimes 9011556Srgrimes/* 9021556Srgrimes * opt_add() 9031556Srgrimes * breaks the value supplied to -o into a option name and value. options 9041556Srgrimes * are given to -o in the form -o name-value,name=value 90546684Skris * multiple -o may be specified. 9061556Srgrimes * Return: 9071556Srgrimes * 0 if format in name=value format, -1 if -o is passed junk 9081556Srgrimes */ 9091556Srgrimes 9101556Srgrimes#if __STDC__ 9111556Srgrimesint 9121556Srgrimesopt_add(register char *str) 9131556Srgrimes#else 9141556Srgrimesint 9151556Srgrimesopt_add(str) 9161556Srgrimes register char *str; 9171556Srgrimes#endif 9181556Srgrimes{ 9191556Srgrimes register OPLIST *opt; 9201556Srgrimes register char *frpt; 9211556Srgrimes register char *pt; 9221556Srgrimes register char *endpt; 9231556Srgrimes 9241556Srgrimes if ((str == NULL) || (*str == '\0')) { 92528904Ssos pax_warn(0, "Invalid option name"); 9261556Srgrimes return(-1); 9271556Srgrimes } 9281556Srgrimes frpt = endpt = str; 9291556Srgrimes 9301556Srgrimes /* 9311556Srgrimes * break into name and values pieces and stuff each one into a 9321556Srgrimes * OPLIST structure. When we know the format, the format specific 9331556Srgrimes * option function will go through this list 9341556Srgrimes */ 9351556Srgrimes while ((frpt != NULL) && (*frpt != '\0')) { 9361556Srgrimes if ((endpt = strchr(frpt, ',')) != NULL) 9371556Srgrimes *endpt = '\0'; 9381556Srgrimes if ((pt = strchr(frpt, '=')) == NULL) { 93928904Ssos pax_warn(0, "Invalid options format"); 9401556Srgrimes return(-1); 9411556Srgrimes } 9421556Srgrimes if ((opt = (OPLIST *)malloc(sizeof(OPLIST))) == NULL) { 94328904Ssos pax_warn(0, "Unable to allocate space for option list"); 9441556Srgrimes return(-1); 9451556Srgrimes } 9461556Srgrimes *pt++ = '\0'; 9471556Srgrimes opt->name = frpt; 9481556Srgrimes opt->value = pt; 9491556Srgrimes opt->fow = NULL; 9501556Srgrimes if (endpt != NULL) 9511556Srgrimes frpt = endpt + 1; 9521556Srgrimes else 9531556Srgrimes frpt = NULL; 9541556Srgrimes if (ophead == NULL) { 9551556Srgrimes optail = ophead = opt; 9561556Srgrimes continue; 9571556Srgrimes } 9581556Srgrimes optail->fow = opt; 9591556Srgrimes optail = opt; 9601556Srgrimes } 9611556Srgrimes return(0); 9621556Srgrimes} 9631556Srgrimes 9641556Srgrimes/* 9651556Srgrimes * str_offt() 9661556Srgrimes * Convert an expression of the following forms to an off_t > 0. 9671556Srgrimes * 1) A positive decimal number. 9681556Srgrimes * 2) A positive decimal number followed by a b (mult by 512). 9691556Srgrimes * 3) A positive decimal number followed by a k (mult by 1024). 9701556Srgrimes * 4) A positive decimal number followed by a m (mult by 512). 9711556Srgrimes * 5) A positive decimal number followed by a w (mult by sizeof int) 9721556Srgrimes * 6) Two or more positive decimal numbers (with/without k,b or w). 97372089Sasmodai * separated by x (also * for backwards compatibility), specifying 9741556Srgrimes * the product of the indicated values. 9751556Srgrimes * Return: 9761556Srgrimes * 0 for an error, a positive value o.w. 9771556Srgrimes */ 9781556Srgrimes 9791556Srgrimes#if __STDC__ 9801556Srgrimesstatic off_t 9811556Srgrimesstr_offt(char *val) 9821556Srgrimes#else 9831556Srgrimesstatic off_t 9841556Srgrimesstr_offt(val) 9851556Srgrimes char *val; 9861556Srgrimes#endif 9871556Srgrimes{ 9881556Srgrimes char *expr; 9891556Srgrimes off_t num, t; 9901556Srgrimes 9911556Srgrimes# ifdef NET2_STAT 9921556Srgrimes num = strtol(val, &expr, 0); 9931556Srgrimes if ((num == LONG_MAX) || (num <= 0) || (expr == val)) 9941556Srgrimes# else 9951556Srgrimes num = strtoq(val, &expr, 0); 9961556Srgrimes if ((num == QUAD_MAX) || (num <= 0) || (expr == val)) 9971556Srgrimes# endif 9981556Srgrimes return(0); 9991556Srgrimes 10001556Srgrimes switch(*expr) { 10011556Srgrimes case 'b': 10021556Srgrimes t = num; 10031556Srgrimes num *= 512; 10041556Srgrimes if (t > num) 10051556Srgrimes return(0); 10061556Srgrimes ++expr; 10071556Srgrimes break; 10081556Srgrimes case 'k': 10091556Srgrimes t = num; 10101556Srgrimes num *= 1024; 10111556Srgrimes if (t > num) 10121556Srgrimes return(0); 10131556Srgrimes ++expr; 10141556Srgrimes break; 10151556Srgrimes case 'm': 10161556Srgrimes t = num; 10171556Srgrimes num *= 1048576; 10181556Srgrimes if (t > num) 10191556Srgrimes return(0); 10201556Srgrimes ++expr; 10211556Srgrimes break; 10221556Srgrimes case 'w': 10231556Srgrimes t = num; 10241556Srgrimes num *= sizeof(int); 10251556Srgrimes if (t > num) 10261556Srgrimes return(0); 10271556Srgrimes ++expr; 10281556Srgrimes break; 10291556Srgrimes } 10301556Srgrimes 10311556Srgrimes switch(*expr) { 10321556Srgrimes case '\0': 10331556Srgrimes break; 10341556Srgrimes case '*': 10351556Srgrimes case 'x': 10361556Srgrimes t = num; 10371556Srgrimes num *= str_offt(expr + 1); 10381556Srgrimes if (t > num) 10391556Srgrimes return(0); 10401556Srgrimes break; 10411556Srgrimes default: 10421556Srgrimes return(0); 10431556Srgrimes } 10441556Srgrimes return(num); 10451556Srgrimes} 10461556Srgrimes 10471556Srgrimes/* 10481556Srgrimes * no_op() 10491556Srgrimes * for those option functions where the archive format has nothing to do. 10501556Srgrimes * Return: 10511556Srgrimes * 0 10521556Srgrimes */ 10531556Srgrimes 10541556Srgrimes#if __STDC__ 10551556Srgrimesstatic int 10561556Srgrimesno_op(void) 10571556Srgrimes#else 10581556Srgrimesstatic int 10591556Srgrimesno_op() 10601556Srgrimes#endif 10611556Srgrimes{ 10621556Srgrimes return(0); 10631556Srgrimes} 10641556Srgrimes 10651556Srgrimes/* 10661556Srgrimes * pax_usage() 10671556Srgrimes * print the usage summary to the user 10681556Srgrimes */ 10691556Srgrimes 10701556Srgrimes#if __STDC__ 10711556Srgrimesvoid 10721556Srgrimespax_usage(void) 10731556Srgrimes#else 10741556Srgrimesvoid 10751556Srgrimespax_usage() 10761556Srgrimes#endif 10771556Srgrimes{ 10781556Srgrimes (void)fputs("usage: pax [-cdnv] [-E limit] [-f archive] ", stderr); 10791556Srgrimes (void)fputs("[-s replstr] ... [-U user] ...", stderr); 10801556Srgrimes (void)fputs("\n [-G group] ... ", stderr); 10811556Srgrimes (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 10821556Srgrimes (void)fputs("[pattern ...]\n", stderr); 10831556Srgrimes (void)fputs(" pax -r [-cdiknuvDYZ] [-E limit] ", stderr); 10841556Srgrimes (void)fputs("[-f archive] [-o options] ... \n", stderr); 10851556Srgrimes (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); 10861556Srgrimes (void)fputs("[-U user] ... [-G group] ...\n ", stderr); 10871556Srgrimes (void)fputs("[-T [from_date][,to_date]] ... ", stderr); 10881556Srgrimes (void)fputs(" [pattern ...]\n", stderr); 10891556Srgrimes (void)fputs(" pax -w [-dituvHLPX] [-b blocksize] ", stderr); 10901556Srgrimes (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); 10911556Srgrimes (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); 10921556Srgrimes (void)fputs("[-o options] ... [-U user] ...", stderr); 10931556Srgrimes (void)fputs("\n [-G group] ... ", stderr); 10941556Srgrimes (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 10951556Srgrimes (void)fputs("[file ...]\n", stderr); 10961556Srgrimes (void)fputs(" pax -r -w [-diklntuvDHLPXYZ] ", stderr); 10971556Srgrimes (void)fputs("[-p string] ... [-s replstr] ...", stderr); 10981556Srgrimes (void)fputs("\n [-U user] ... [-G group] ... ", stderr); 10991556Srgrimes (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); 11001556Srgrimes (void)fputs("\n [file ...] directory\n", stderr); 11011556Srgrimes exit(1); 11021556Srgrimes} 11031556Srgrimes 11041556Srgrimes/* 11051556Srgrimes * tar_usage() 11061556Srgrimes * print the usage summary to the user 11071556Srgrimes */ 11081556Srgrimes 11091556Srgrimes#if __STDC__ 11101556Srgrimesvoid 11111556Srgrimestar_usage(void) 11121556Srgrimes#else 11131556Srgrimesvoid 11141556Srgrimestar_usage() 11151556Srgrimes#endif 11161556Srgrimes{ 11171556Srgrimes (void)fputs("usage: tar -{txru}[cevfbmopwBHLPX014578] [tapefile] ", 11181556Srgrimes stderr); 11191556Srgrimes (void)fputs("[blocksize] file1 file2...\n", stderr); 11201556Srgrimes exit(1); 11211556Srgrimes} 11221556Srgrimes 11231556Srgrimes#ifdef notdef 11241556Srgrimes/* 11251556Srgrimes * cpio_usage() 11261556Srgrimes * print the usage summary to the user 11271556Srgrimes */ 11281556Srgrimes 11291556Srgrimes#if __STDC__ 11301556Srgrimesvoid 11311556Srgrimescpio_usage(void) 11321556Srgrimes#else 11331556Srgrimesvoid 11341556Srgrimescpio_usage() 11351556Srgrimes#endif 11361556Srgrimes{ 11371556Srgrimes exit(1); 11381556Srgrimes} 11391556Srgrimes#endif 1140