diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/cmd/pax/tar.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/cmd/pax/tar.c')
-rwxr-xr-x | sys/src/ape/cmd/pax/tar.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/sys/src/ape/cmd/pax/tar.c b/sys/src/ape/cmd/pax/tar.c new file mode 100755 index 000000000..d0477b6f7 --- /dev/null +++ b/sys/src/ape/cmd/pax/tar.c @@ -0,0 +1,335 @@ +/* $Source: /u/mark/src/pax/RCS/tar.c,v $ + * + * $Revision: 1.2 $ + * + * tar.c - tar specific functions for archive handling + * + * DESCRIPTION + * + * These routines provide a tar conforming interface to the pax + * program. + * + * AUTHOR + * + * Mark H. Colburn, NAPS International (mark@jhereg.mn.org) + * + * Sponsored by The USENIX Association for public distribution. + * + * Copyright (c) 1989 Mark H. Colburn. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice is duplicated in all such + * forms and that any documentation, advertising materials, and other + * materials related to such distribution and use acknowledge that the + * software was developed by Mark H. Colburn and sponsored by The + * USENIX Association. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Log: tar.c,v $ + * Revision 1.2 89/02/12 10:06:05 mark + * 1.2 release fixes + * + * Revision 1.1 88/12/23 18:02:38 mark + * Initial revision + * + */ + +#ifndef lint +static char *ident = "$Id: tar.c,v 1.2 89/02/12 10:06:05 mark Exp $"; +static char *copyright ="Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved."; +#endif /* not lint */ + +/* Headers */ + +#include "pax.h" + + +/* Defines */ + +#define DEF_BLOCKING 20 /* default blocking factor for extract */ + + +/* Function Prototypes */ + +#ifdef __STDC__ + +static int taropt(int , char **, char *); +static void usage(void); + +#else /* !__STDC__ */ + +static int taropt(); +static void usage(); + +#endif /* __STDC__ */ + + +/* do_tar - main routine for tar. + * + * DESCRIPTION + * + * Provides a tar interface to the PAX program. All tar standard + * command line options are supported. + * + * PARAMETERS + * + * int argc - argument count (argc from main) + * char **argv - argument list (argv from main) + * + * RETURNS + * + * zero + */ + +#ifdef __STDC__ + +int do_tar(int argc, char **argv) + +#else + +int do_tar(argc, argv) +int argc; /* argument count (argc from main) */ +char **argv; /* argument list (argv from main) */ + +#endif +{ + int c; /* Option letter */ + + /* Set default option values */ + names_from_stdin = 0; + ar_file = getenv("TAPE"); /* From environment, or */ + if (ar_file == 0) { + ar_file = DEF_AR_FILE; /* From Makefile */ + } + + /* + * set up the flags to reflect the default pax inteface. Unfortunately + * the pax interface has several options which are completely opposite + * of the tar and/or cpio interfaces... + */ + f_unconditional = 1; + f_mtime = 1; + f_dir_create = 1; + blocking = 0; + ar_interface = TAR; + ar_format = TAR; + msgfile=stderr; + + /* Parse options */ + while ((c = taropt(argc, argv, "b:cf:hlmortuvwx")) != EOF) { + switch (c) { + case 'b': /* specify blocking factor */ + /* + * FIXME - we should use a conversion routine that does + * some kind of reasonable error checking, but... + */ + blocking = atoi(optarg); + break; + case 'c': /* create a new archive */ + f_create = 1; + break; + case 'f': /* specify input/output file */ + ar_file = optarg; + break; + case 'h': + f_follow_links = 1; /* follow symbolic links */ + break; + case 'l': /* report unresolved links */ + f_linksleft = 1; + break; + case 'm': /* don't restore modification times */ + f_modified = 1; + break; + case 'o': /* take on user's group rather than + * archives */ + break; + case 'r': /* named files are appended to archive */ + f_append = 1; + break; + case 't': + f_list = 1; /* list files in archive */ + break; + case 'u': /* named files are added to archive */ + f_newer = 1; + break; + case 'v': /* verbose mode */ + f_verbose = 1; + break; + case 'w': /* user interactive mode */ + f_disposition = 1; + break; + case 'x': /* named files are extracted from archive */ + f_extract = 1; + break; + case '?': + usage(); + exit(EX_ARGSBAD); + } + } + + /* check command line argument sanity */ + if (f_create + f_extract + f_list + f_append + f_newer != 1) { + (void) fprintf(stderr, + "%s: you must specify exactly one of the c, t, r, u or x options\n", + myname); + usage(); + exit(EX_ARGSBAD); + } + + /* set the blocking factor, if not set by the user */ + if (blocking == 0) { +#ifdef USG + if (f_extract || f_list) { + blocking = DEF_BLOCKING; + fprintf(stderr, "Tar: blocksize = %d\n", blocking); + } else { + blocking = 1; + } +#else /* !USG */ + blocking = 20; +#endif /* USG */ + } + blocksize = blocking * BLOCKSIZE; + buf_allocate((OFFSET) blocksize); + + if (f_create) { + open_archive(AR_WRITE); + create_archive(); /* create the archive */ + } else if (f_extract) { + open_archive(AR_READ); + read_archive(); /* extract files from archive */ + } else if (f_list) { + open_archive(AR_READ); + read_archive(); /* read and list contents of archive */ + } else if (f_append) { + open_archive(AR_APPEND); + append_archive(); /* append files to archive */ + } + + if (f_linksleft) { + linkleft(); /* report any unresolved links */ + } + + return (0); +} + + +/* taropt - tar specific getopt + * + * DESCRIPTION + * + * Plug-compatible replacement for getopt() for parsing tar-like + * arguments. If the first argument begins with "-", it uses getopt; + * otherwise, it uses the old rules used by tar, dump, and ps. + * + * PARAMETERS + * + * int argc - argument count (argc from main) + * char **argv - argument list (argv from main) + * char *optstring - sring which describes allowable options + * + * RETURNS + * + * Returns the next option character in the option string(s). If the + * option requires an argument and an argument was given, the argument + * is pointed to by "optarg". If no option character was found, + * returns an EOF. + * + */ + +#ifdef __STDC__ + +static int taropt(int argc, char **argv, char *optstring) + +#else + +static int taropt(argc, argv, optstring) +int argc; +char **argv; +char *optstring; + +#endif +{ + extern char *optarg; /* Points to next arg */ + extern int optind; /* Global argv index */ + static char *key; /* Points to next keyletter */ + static char use_getopt; /* !=0 if argv[1][0] was '-' */ + char c; + char *place; + + optarg = (char *)NULL; + + if (key == (char *)NULL) { /* First time */ + if (argc < 2) + return EOF; + key = argv[1]; + if (*key == '-') + use_getopt++; + else + optind = 2; + } + if (use_getopt) { + return getopt(argc, argv, optstring); + } + + c = *key++; + if (c == '\0') { + key--; + return EOF; + } + place = strchr(optstring, c); + + if (place == (char *)NULL || c == ':') { + fprintf(stderr, "%s: unknown option %c\n", argv[0], c); + return ('?'); + } + place++; + if (*place == ':') { + if (optind < argc) { + optarg = argv[optind]; + optind++; + } else { + fprintf(stderr, "%s: %c argument missing\n", + argv[0], c); + return ('?'); + } + } + return (c); +} + + +/* usage - print a helpful message and exit + * + * DESCRIPTION + * + * Usage prints out the usage message for the TAR interface and then + * exits with a non-zero termination status. This is used when a user + * has provided non-existant or incompatible command line arguments. + * + * RETURNS + * + * Returns an exit status of 1 to the parent process. + * + */ + +#ifdef __STDC__ + +static void usage(void) + +#else + +static void usage() + +#endif +{ + fprintf(stderr, "Usage: %s -c[bfvw] device block filename..\n", myname); + fprintf(stderr, " %s -r[bvw] device block [filename...]\n", myname); + fprintf(stderr, " %s -t[vf] device\n", myname); + fprintf(stderr, " %s -u[bvw] device block [filename...]\n", myname); + fprintf(stderr, " %s -x[flmovw] device [filename...]\n", myname); + exit(1); +} |