Annotation of coherent/d/usr/bin/pax/public/part02.sh, revision 1.1.1.1

1.1       root        1: # This is a shell archive.  Remove anything before this line, then unpack
                      2: # it by saving it into a file and typing "sh file".  To overwrite existing
                      3: # files, type "sh file -c".  You can also feed this as standard input via
                      4: # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
                      5: # will see the following message at the end:
                      6: #              "End of archive 2 (of 6)."
                      7: # Contents:  cpio.1 create.c func.h link.c names.c replace.c ttyio.c
                      8: #   warn.c
                      9: # Wrapped by mark@jhereg on Tue Dec 27 19:37:38 1988
                     10: PATH=/bin:/usr/bin:/usr/ucb ; export PATH
                     11: if test -f cpio.1 -a "${1}" != "-c" ; then 
                     12:   echo shar: Will not over-write existing file \"cpio.1\"
                     13: else
                     14: echo shar: Extracting \"cpio.1\" \(6231 characters\)
                     15: sed "s/^X//" >cpio.1 <<'END_OF_cpio.1'
                     16: X.\" $Id: cpio.1,v 1.1 88/12/23 18:02:04 mark Rel $
                     17: X.TH CPIO 1 "USENIX Association" ""
                     18: X.SH NAME
                     19: Xcpio \- copy file archives in and out
                     20: X.SH SYNOPSIS
                     21: X.B cpio
                     22: X.BR \-o [ Bacv ]
                     23: X.br
                     24: X.B cpio
                     25: X.BR \-i [ Bcdfmrtuv ]
                     26: X.RI [ pattern... ]
                     27: X.br
                     28: X.B cpio
                     29: X.BR \-p [ adlmruv ]
                     30: X.I directory
                     31: X.SH DESCRIPTION
                     32: XThe
                     33: X.B cpio
                     34: Xutility produces and reads files in the format specified by the
                     35: X.B cpio
                     36: X.B "Archive/Interchange File Format"
                     37: Xspecified in
                     38: X.IR "IEEE Std. 1003.1-1988" .
                     39: X.PP
                     40: XThe
                     41: X.B "cpio -i"
                     42: X(copy in) utility extracts files from the standard input, which is
                     43: Xassumed to be the product of a previous
                     44: X.B "cpio -o" .
                     45: XOnly files with names that match
                     46: X.I patterns
                     47: Xare selected.
                     48: XMultiple
                     49: X.I patterns
                     50: Xmay be specified and if no
                     51: X.I patterns
                     52: Xare specified, the default for
                     53: X.I patterns
                     54: Xis \*, selecting all files.
                     55: XThe extracted files are conditionally created and copied into the
                     56: Xcurrent directory, and possibly any levels below, based upon the
                     57: Xoptions described below and the permissions of the files will be those
                     58: Xof the previous
                     59: X.B "cpio -o" .
                     60: XThe owner and group of the files will be that of the current user
                     61: Xunless the user has appropriate privileges, which causes
                     62: X.B cpio
                     63: Xto retains the owner and group of the files of the previous
                     64: X.B "cpio -o" .
                     65: X.PP
                     66: XThe 
                     67: X.B "cpio -p"
                     68: X(pass) utility reads the standard input to obtain a list of path names
                     69: Xof files that are conditionally created and copied into the
                     70: Xdestination
                     71: X.I directory 
                     72: Xbased upon the options described below.
                     73: X.PP
                     74: XIf an error is detected, the cause is reported and the
                     75: X.B cpio
                     76: Xutility will continue to copy other files.
                     77: X.B cpio
                     78: Xwill skip over any unrecognized files which it encounters in the archive.
                     79: X.PP
                     80: XThe following restrictions apply to the 
                     81: X.B cpio
                     82: Xutility:
                     83: X.IP 1 .25i
                     84: XPathnames are restricted to 256 characters.
                     85: X.IP 2 .25i
                     86: XAppropriate privileges are required to copy special files.
                     87: X.IP 3 .25i
                     88: XBlocks are reported in 512-byte quantities.
                     89: X.SS Options
                     90: XThe following options are available:
                     91: X.TP .5i
                     92: X.B \-B
                     93: XInput/output is to be blocked 5120 bytes to the record.
                     94: XCan only be used with
                     95: X.B "cpio -o" 
                     96: Xor
                     97: X.B "cpio -i"
                     98: Xfor data that is directed to or from character special files.
                     99: X.TP .5i
                    100: X.B \-a
                    101: XReset access times of input files after they have been copied.
                    102: XWhen the
                    103: X.B \-l
                    104: Xoption is also specified, the linked files do not have their access
                    105: Xtimes reset.
                    106: XCan only be used with
                    107: X.B "cpio -o"
                    108: Xor
                    109: X.B "cpio -i" .
                    110: X.TP .5i
                    111: X.B \-c
                    112: XWrite header information in ASCII character for for portability.
                    113: XCan only be used with
                    114: X.B "cpio -i"
                    115: Xor
                    116: X.B "cpio -o" .
                    117: XNote that this option should always be used to write portable files.
                    118: X.TP .5i
                    119: X.B \-d
                    120: XCreates directories as needed.
                    121: XCan only be used with 
                    122: X.B "cpio -i" 
                    123: Xor
                    124: X.B "cpio -p" .
                    125: X.TP .5i
                    126: X.B \-f
                    127: XCopy in all files except those in
                    128: X.I patterns .
                    129: XCan only be used with
                    130: X.B "cpio -i" .
                    131: X.TP .5i
                    132: X.B \-l
                    133: XWhenever possible, link files rather than copying them.
                    134: XCan only be used with 
                    135: X.B "cpio -p" .
                    136: X.TP .5i
                    137: X.B \-m
                    138: XRetain previous modification times.
                    139: XThis option is ineffective on directories that are being copied.
                    140: XCan only be used with
                    141: X.B "cpio -i" 
                    142: Xor
                    143: X.B "cpio -p" .
                    144: X.TP .5i
                    145: X.B \-r
                    146: XInteractively rename files.
                    147: XThe user is asked whether to rename
                    148: X.I pattern
                    149: Xeach invocation.
                    150: XRead and write permissions for
                    151: X.B "/dev/tty"
                    152: Xare required for this option.
                    153: XIf the user types a null line, the file is skipped.
                    154: XShould only be used with
                    155: X.B "cpio -i"
                    156: Xor
                    157: X.B "cpio -o" .
                    158: X.TP .5i
                    159: X.B \-t
                    160: XPrint a table of contents of the input.
                    161: XNo files are created.
                    162: XCan only be used with
                    163: X.B "cpio -i" .
                    164: X.TP .5i
                    165: X.B \-u
                    166: XCopy files unconditionally; usually an older file will not replace a
                    167: Xnew file with the same name.
                    168: XCan only be used with
                    169: X.B "cpio -i"
                    170: Xor
                    171: X.B "cpio -p" .
                    172: X.TP .5i
                    173: X.B \-v
                    174: XVerbose: cause the names of the affected files to be printed.
                    175: XCan only be used with
                    176: X.B "cpio -i" .
                    177: XProvides a detailed listing when used with the 
                    178: X.B \-t
                    179: Xoption.
                    180: X.SS Operands
                    181: XThe following operands are available:
                    182: X.TP 1i
                    183: X.I patterns
                    184: XSimple regular expressions given in the name-generating notation of the
                    185: Xshell.
                    186: X.TP 1i
                    187: X.I directory
                    188: XThe destination directory.
                    189: X.SS "Exit Status"
                    190: XThe
                    191: X.B cpio
                    192: Xutility exits with one of the following values:
                    193: X.TP .5i
                    194: X0
                    195: XAll input files were copied.
                    196: X.TP .5i
                    197: X2
                    198: XThe utility encountered errors in copying or accessing files or
                    199: Xdirectories.
                    200: XAn error will be reported for nonexistent files or directories, or
                    201: Xpermissions that do not allow the user to access the source or target
                    202: Xfiles.
                    203: X.SS
                    204: XIt is important to use the
                    205: X.B "-depth"
                    206: Xoption of the
                    207: X.B find
                    208: Xutility to generate pathnames for 
                    209: X.B cpio .
                    210: XThis eliminates problems
                    211: X.B cpio
                    212: Xcould have trying to create files under read-only directories.
                    213: X.PP
                    214: XThe following command:
                    215: X.RS
                    216: Xls | cpio -o > ../newfile
                    217: X.RE
                    218: Xcopies out the files listed by the 
                    219: X.B ls
                    220: Xutility and redirects them to the file
                    221: X.B newfile .
                    222: X.PP
                    223: XThe following command:
                    224: X.RS
                    225: Xcat newfile | cpio -id "memo/al" "memo/b*"
                    226: X.RE
                    227: Xuses the output file
                    228: X.B newfile
                    229: Xfrom the
                    230: X.B "cpio -o"
                    231: Xutility, takes those files that match the patterns
                    232: X.B "memo/al"
                    233: Xand
                    234: X.B "memo/b*" ,
                    235: Xcreates the directories below the current directory, and places the
                    236: Xfiles in the appropriate directories.
                    237: X.PP
                    238: XThe command
                    239: X.RS
                    240: Xfind . -depth -print | cpio -pdlmv newdir
                    241: X.RE
                    242: Xtakes the file names piped to it from the
                    243: X.B find
                    244: Xutility and copies or links those files to another directory
                    245: Xnamed
                    246: X.B newdir ,
                    247: Xwhile retaining the modification time.
                    248: X.SH FILES
                    249: X.TP 1i
                    250: X/dev/tty
                    251: Xused to prompt the user for information when the
                    252: X.B \-i 
                    253: Xor 
                    254: X.B \-r
                    255: Xoptions are specified.
                    256: X.SH "SEE ALSO"
                    257: Xfind(1), pax(1), tar(1), cpio(5), tar(5)
                    258: X.SH COPYRIGHT
                    259: XCopyright (c) 1989 Mark H. Colburn.  
                    260: X.br
                    261: XAll rights reserved.
                    262: X.PP
                    263: XRedistribution and use in source and binary forms are permitted
                    264: Xprovided that the above copyright notice is duplicated in all such 
                    265: Xforms and that any documentation, advertising materials, and other 
                    266: Xmaterials related to such distribution and use acknowledge that the 
                    267: Xsoftware was developed by Mark H. Colburn and sponsored by The 
                    268: XUSENIX Association. 
                    269: X.PP
                    270: XTHE SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                    271: XIMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                    272: XWARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                    273: X.SH AUTHOR
                    274: XMark H. Colburn
                    275: X.br
                    276: XNAPS International
                    277: X.br
                    278: X117 Mackubin Street, Suite 1
                    279: X.br
                    280: XSt. Paul, MN 55102
                    281: X.br
                    282: [email protected]
                    283: X.sp 2
                    284: XSponsored by
                    285: X.B "The USENIX Association"
                    286: Xfor public distribution.
                    287: END_OF_cpio.1
                    288: if test 6231 -ne `wc -c <cpio.1`; then
                    289:     echo shar: \"cpio.1\" unpacked with wrong size!
                    290: fi
                    291: # end of overwriting check
                    292: fi
                    293: if test -f create.c -a "${1}" != "-c" ; then 
                    294:   echo shar: Will not over-write existing file \"create.c\"
                    295: else
                    296: echo shar: Extracting \"create.c\" \(7830 characters\)
                    297: sed "s/^X//" >create.c <<'END_OF_create.c'
                    298: X/* $Source: /u/mark/src/pax/RCS/create.c,v $
                    299: X *
                    300: X * $Revision: 1.1 $
                    301: X *
                    302: X * create.c - Create a tape archive. 
                    303: X *
                    304: X * DESCRIPTION
                    305: X *
                    306: X *    These functions are used to create/write and archive from an set of
                    307: X *    named files.
                    308: X *
                    309: X * AUTHOR
                    310: X *
                    311: X *            Mark H. Colburn, NAPS International ([email protected])
                    312: X *
                    313: X * Sponsored by The USENIX Association for public distribution. 
                    314: X *
                    315: X * Copyright (c) 1989 Mark H. Colburn.
                    316: X * All rights reserved.
                    317: X *
                    318: X * Redistribution and use in source and binary forms are permitted
                    319: X * provided that the above copyright notice is duplicated in all such 
                    320: X * forms and that any documentation, advertising materials, and other 
                    321: X * materials related to such distribution and use acknowledge that the 
                    322: X * software was developed * by Mark H. Colburn and sponsored by The 
                    323: X * USENIX Association. 
                    324: X *
                    325: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                    326: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                    327: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                    328: X *
                    329: X * $Log:      create.c,v $
                    330: X * Revision 1.1  88/12/23  18:02:06  mark
                    331: X * Initial revision
                    332: X * 
                    333: X */
                    334: X
                    335: X#ifndef lint
                    336: Xstatic char *ident = "$Id: create.c,v 1.1 88/12/23 18:02:06 mark Rel $";
                    337: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                    338: X#endif /* ! lint */
                    339: X
                    340: X
                    341: X/* Headers */
                    342: X
                    343: X#include "pax.h"
                    344: X
                    345: X
                    346: X/* Function Prototypes */
                    347: X
                    348: X#ifdef __STDC__
                    349: X
                    350: Xstatic void writetar(char *, Stat *);
                    351: Xstatic void writecpio(char *, Stat *);
                    352: Xstatic char tartype(int);
                    353: X
                    354: X#else /* !__STDC__ */
                    355: X
                    356: Xstatic void writetar();
                    357: Xstatic void writecpio();
                    358: Xstatic char tartype();
                    359: X
                    360: X#endif /* __STDC__ */
                    361: X
                    362: X
                    363: X/* create_archive - create a tar archive.
                    364: X *
                    365: X * DESCRIPTION
                    366: X *
                    367: X *    Create_archive is used as an entry point to both create and append
                    368: X *    archives.  Create archive goes through the files specified by the
                    369: X *    user and writes each one to the archive if it can.  Create_archive
                    370: X *    knows how to write both cpio and tar headers and the padding which
                    371: X *    is needed for each type of archive.
                    372: X *
                    373: X * RETURNS
                    374: X *
                    375: X *    Always returns 0
                    376: X */
                    377: X
                    378: X#ifdef __STDC__
                    379: X
                    380: Xint create_archive(void)
                    381: X
                    382: X#else
                    383: X
                    384: Xint create_archive()
                    385: X
                    386: X#endif
                    387: X{
                    388: X    char            name[PATH_MAX + 1];
                    389: X    Stat            sb;
                    390: X    int             fd;
                    391: X
                    392: X    while (name_next(name, &sb) != -1) {
                    393: X      if ((fd = openi(name, &sb)) < 0) {
                    394: X          /* FIXME: pax wants to exit here??? */
                    395: X          continue;
                    396: X      }
                    397: X
                    398: X      if (rplhead != NULL) {
                    399: X          rpl_name(name);
                    400: X          if (strlen(name) == 0) {
                    401: X              continue;
                    402: X          }
                    403: X      }
                    404: X      if (get_disposition("add", name) || get_newname(name, sizeof(name))) {
                    405: X          /* skip file... */
                    406: X          if (fd) {
                    407: X              close(fd);
                    408: X          }
                    409: X          continue;
                    410: X      } 
                    411: X
                    412: X      if (!f_link && sb.sb_nlink > 1) {
                    413: X          if (islink(name, &sb)) {
                    414: X              sb.sb_size = 0;
                    415: X          }
                    416: X          linkto(name, &sb);
                    417: X      }
                    418: X      if (ar_format == TAR) {
                    419: X          writetar(name, &sb);
                    420: X      } else {
                    421: X          writecpio(name, &sb);
                    422: X      }
                    423: X      if (fd) {
                    424: X          outdata(fd, name, sb.sb_size);
                    425: X      }
                    426: X      if (f_verbose) {
                    427: X          print_entry(name, &sb);
                    428: X      }
                    429: X    }
                    430: X
                    431: X    write_eot();
                    432: X    close_archive();
                    433: X    return (0);
                    434: X}
                    435: X
                    436: X
                    437: X/* writetar - write a header block for a tar file
                    438: X *
                    439: X * DESCRIPTION
                    440: X *
                    441: X *    Make a header block for the file name whose stat info is in st.  
                    442: X *    Return header pointer for success, NULL if the name is too long.
                    443: X *
                    444: X *    The tar header block is structured as follows:
                    445: X *
                    446: X *            FIELD NAME      OFFSET          SIZE
                    447: X *            -------------|---------------|------
                    448: X *            name              0             100
                    449: X *            mode            100               8
                    450: X *            uid             108               8
                    451: X *            gid             116               8
                    452: X *            size            124              12
                    453: X *            mtime           136              12
                    454: X *            chksum          148               8
                    455: X *            typeflag        156               1
                    456: X *            linkname        157             100
                    457: X *            magic           257               6
                    458: X *            version         263               2
                    459: X *            uname           265              32
                    460: X *            gname           297              32
                    461: X *            devmajor        329               8
                    462: X *            devminor        337               8
                    463: X *            prefix          345             155
                    464: X *
                    465: X * PARAMETERS
                    466: X *
                    467: X *    char    *name   - name of file to create a header block for
                    468: X *    Stat    *asb    - pointer to the stat structure for the named file
                    469: X *
                    470: X */
                    471: X
                    472: X#ifdef __STDC__
                    473: X
                    474: Xstatic void writetar(char *name, Stat *asb)
                    475: X
                    476: X#else
                    477: X    
                    478: Xstatic void writetar(name, asb)
                    479: Xchar           *name;
                    480: XStat           *asb;
                    481: X
                    482: X#endif
                    483: X{
                    484: X    char         *p;
                    485: X    char           *prefix = NULL;
                    486: X    int             i;
                    487: X    int             sum;
                    488: X    char            hdr[BLOCKSIZE];
                    489: X    Link           *from;
                    490: X
                    491: X    memset(hdr, 0, BLOCKSIZE);
                    492: X    if (strlen(name) > 255) {
                    493: X      warn(name, "name too long");
                    494: X      return;
                    495: X    }
                    496: X
                    497: X    /* 
                    498: X     * If the pathname is longer than TNAMLEN, but less than 255, then
                    499: X     * we can split it up into the prefix and the filename.
                    500: X     */
                    501: X    if (strlen(name) > 100) {
                    502: X      prefix = name;
                    503: X      name += 155;
                    504: X      while (name > prefix && *name != '/') {
                    505: X          name--;
                    506: X      }
                    507: X
                    508: X      /* no slash found....hmmm.... */
                    509: X      if (name == prefix) {
                    510: X          warn(prefix, "Name too long");
                    511: X          return;
                    512: X      }
                    513: X      *name++ = '\0';
                    514: X    }
                    515: X
                    516: X#ifdef S_IFLNK
                    517: X    if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
                    518: X      strcpy(&hdr[157], asb->sb_link);
                    519: X      asb->sb_size = 0;
                    520: X    }
                    521: X#endif
                    522: X    strcpy(hdr, name);
                    523: X    sprintf(&hdr[100], "%06o \0", asb->sb_mode & ~S_IFMT);
                    524: X    sprintf(&hdr[108], "%06o \0", asb->sb_uid);
                    525: X    sprintf(&hdr[116], "%06o \0", asb->sb_gid);
                    526: X    sprintf(&hdr[124], "%011lo ", (long) asb->sb_size);
                    527: X    sprintf(&hdr[136], "%011lo ", (long) asb->sb_mtime);
                    528: X    strncpy(&hdr[148], "        ", 8);
                    529: X    hdr[156] = tartype(asb->sb_mode);
                    530: X    if (asb->sb_nlink > 1 && (from = linkfrom(name, asb)) != NULL) {
                    531: X      strcpy(&hdr[157], from->l_name);
                    532: X      hdr[156] = LNKTYPE;
                    533: X    }
                    534: X    strcpy(&hdr[257], TMAGIC);
                    535: X    strncpy(&hdr[263], TVERSION, 2);
                    536: X    strcpy(&hdr[265], finduname((int) asb->sb_uid));
                    537: X    strcpy(&hdr[297], findgname((int) asb->sb_gid));
                    538: X    sprintf(&hdr[329], "%06o \0", major(asb->sb_rdev));
                    539: X    sprintf(&hdr[337], "%06o \0", minor(asb->sb_rdev));
                    540: X    if (prefix != NULL) {
                    541: X      strncpy(&hdr[345], prefix, 155);
                    542: X    }
                    543: X
                    544: X    /* Calculate the checksum */
                    545: X
                    546: X    sum = 0;
                    547: X    p = hdr;
                    548: X    for (i = 0; i < 500; i++) {
                    549: X      sum += 0xFF & *p++;
                    550: X    }
                    551: X
                    552: X    /* Fill in the checksum field. */
                    553: X
                    554: X    sprintf(&hdr[148], "%06o \0", sum);
                    555: X
                    556: X    outwrite(hdr, BLOCKSIZE);
                    557: X}
                    558: X
                    559: X
                    560: X/* tartype - return tar file type from file mode
                    561: X *
                    562: X * DESCRIPTION
                    563: X *
                    564: X *    tartype returns the character which represents the type of file
                    565: X *    indicated by "mode". 
                    566: X *
                    567: X * PARAMETERS
                    568: X *
                    569: X *    int     mode    - file mode from a stat block
                    570: X *
                    571: X * RETURNS
                    572: X *
                    573: X *    The character which represents the particular file type in the 
                    574: X *    ustar standard headers.
                    575: X */
                    576: X
                    577: X#ifdef __STDC__
                    578: X
                    579: Xstatic char tartype(int mode)
                    580: X
                    581: X#else
                    582: X    
                    583: Xstatic char tartype(mode)
                    584: Xint       mode;
                    585: X
                    586: X#endif
                    587: X{
                    588: X    switch (mode & S_IFMT) {
                    589: X
                    590: X#ifdef S_IFCTG
                    591: X    case S_IFCTG:
                    592: X      return(CONTTYPE);
                    593: X#endif
                    594: X
                    595: X    case S_IFDIR:
                    596: X      return (DIRTYPE);
                    597: X
                    598: X#ifdef S_IFLNK
                    599: X    case S_IFLNK:
                    600: X      return (SYMTYPE);
                    601: X#endif
                    602: X
                    603: X#ifdef S_IFFIFO
                    604: X    case S_IFIFO:
                    605: X      return (FIFOTYPE);
                    606: X#endif
                    607: X
                    608: X#ifdef S_IFCHR
                    609: X    case S_IFCHR:
                    610: X      return (CHRTYPE);
                    611: X#endif
                    612: X
                    613: X#ifdef S_IFBLK
                    614: X    case S_IFBLK:
                    615: X      return (BLKTYPE);
                    616: X#endif
                    617: X
                    618: X    default:
                    619: X      return (REGTYPE);
                    620: X    }
                    621: X}
                    622: X
                    623: X
                    624: X/* writecpio - write a cpio archive header
                    625: X *
                    626: X * DESCRIPTION
                    627: X *
                    628: X *    Writes a new CPIO style archive header for the file specified.
                    629: X *
                    630: X * PARAMETERS
                    631: X *
                    632: X *    char    *name   - name of file to create a header block for
                    633: X *    Stat    *asb    - pointer to the stat structure for the named file
                    634: X */
                    635: X
                    636: X#ifdef __STDC__
                    637: X
                    638: Xstatic void writecpio(char *name, Stat *asb)
                    639: X
                    640: X#else
                    641: X    
                    642: Xstatic void writecpio(name, asb)
                    643: Xchar           *name;
                    644: XStat           *asb;
                    645: X
                    646: X#endif
                    647: X{
                    648: X    uint            namelen;
                    649: X    char            header[M_STRLEN + H_STRLEN + 1];
                    650: X
                    651: X    namelen = (uint) strlen(name) + 1;
                    652: X    strcpy(header, M_ASCII);
                    653: X    sprintf(header + M_STRLEN, "%06o%06o%06o%06o%06o",
                    654: X          USH(asb->sb_dev), USH(asb->sb_ino), USH(asb->sb_mode), 
                    655: X          USH(asb->sb_uid), USH(asb->sb_gid));
                    656: X    sprintf(header + M_STRLEN + 30, "%06o%06o%011lo%06o%011lo",
                    657: X          USH(asb->sb_nlink), USH(asb->sb_rdev),
                    658: X          f_modification_time ? asb->sb_mtime : time((time_t *) 0),
                    659: X          namelen, asb->sb_size);
                    660: X    outwrite(header, M_STRLEN + H_STRLEN);
                    661: X    outwrite(name, namelen);
                    662: X#ifdef        S_IFLNK
                    663: X    if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
                    664: X      outwrite(asb->sb_link, (uint) asb->sb_size);
                    665: X    }
                    666: X#endif        /* S_IFLNK */
                    667: X}
                    668: END_OF_create.c
                    669: if test 7830 -ne `wc -c <create.c`; then
                    670:     echo shar: \"create.c\" unpacked with wrong size!
                    671: fi
                    672: # end of overwriting check
                    673: fi
                    674: if test -f func.h -a "${1}" != "-c" ; then 
                    675:   echo shar: Will not over-write existing file \"func.h\"
                    676: else
                    677: echo shar: Extracting \"func.h\" \(5047 characters\)
                    678: sed "s/^X//" >func.h <<'END_OF_func.h'
                    679: X/* $Source: /u/mark/src/pax/RCS/func.h,v $
                    680: X *
                    681: X * $Revision: 1.1 $
                    682: X *
                    683: X * func.h - function type and argument declarations
                    684: X *
                    685: X * DESCRIPTION
                    686: X *
                    687: X *    This file contains function delcarations in both ANSI style
                    688: X *    (function prototypes) and traditional style. 
                    689: X *
                    690: X * AUTHOR
                    691: X *
                    692: X *     Mark H. Colburn, NAPS International ([email protected])
                    693: X *
                    694: X * Sponsored by The USENIX Association for public distribution. 
                    695: X *
                    696: X * Copyright (c) 1989 Mark H. Colburn.
                    697: X * All rights reserved.
                    698: X *
                    699: X * Redistribution and use in source and binary forms are permitted
                    700: X * provided that the above copyright notice and this paragraph are
                    701: X * duplicated in all such forms and that any documentation,
                    702: X * advertising materials, and other materials related to such
                    703: X * distribution and use acknowledge that the software was developed
                    704: X * by Mark H. Colburn and sponsored by The USENIX Association. 
                    705: X *
                    706: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                    707: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                    708: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                    709: X */
                    710: X
                    711: X#ifndef _PAX_FUNC_H
                    712: X#define _PAX_FUNC_H
                    713: X
                    714: X/* Function Prototypes */
                    715: X
                    716: X#ifdef __STDC__
                    717: X
                    718: Xextern Link                  *linkfrom(char *, Stat *);
                    719: Xextern Link                  *linkto(char *, Stat *);
                    720: Xextern char                  *mem_get(uint);
                    721: Xextern char                  *mem_str(char *);
                    722: Xextern char                  *syserr(void);
                    723: Xextern int            ar_read(void);
                    724: Xextern int            buf_read(char *, uint);
                    725: Xextern int            buf_skip(OFFSET);
                    726: Xextern int            create_archive(void);
                    727: Xextern int            dirneed(char *);
                    728: Xextern int            read_archive(void);
                    729: Xextern int            inentry(char *, Stat *);
                    730: Xextern int            lineget(FILE *, char *);
                    731: Xextern int            name_match(char *);
                    732: Xextern int            name_next(char *, Stat *);
                    733: Xextern int            nameopt(char *);
                    734: Xextern int            open_archive(int);
                    735: Xextern int            open_tty(void);
                    736: Xextern int            openi(char *, Stat *);
                    737: Xextern int            openo(char *, Stat *, Link *, int);
                    738: Xextern int            pass(char *);
                    739: Xextern int            passitem(char *, Stat *, int, char *);
                    740: Xextern int            read_header(char *, Stat *);
                    741: Xextern int            wildmat(char *, char *);
                    742: Xextern void           buf_allocate(OFFSET);
                    743: Xextern void           close_archive(void);
                    744: Xextern void           fatal(char *);
                    745: Xextern void           name_gather(void);
                    746: Xextern void           name_init(int, char **);
                    747: Xextern void           names_notfound(void);
                    748: Xextern void           next(int);
                    749: Xextern int            nextask(char *, char *, int);
                    750: Xextern void           outdata(int, char *, OFFSET);
                    751: Xextern void           outwrite(char *, uint);
                    752: Xextern void           passdata(char *, int, char *, int);
                    753: Xextern void           print_entry(char *, Stat *);
                    754: Xextern void           warn();
                    755: Xextern void           warnarch(char *, OFFSET);
                    756: Xextern void           write_eot(void);
                    757: Xextern void           get_archive_type(void);
                    758: Xextern struct group    *getgrgid();
                    759: Xextern struct group    *getgrnam();
                    760: Xextern struct passwd   *getpwuid();
                    761: Xextern char                  *getenv(char *);
                    762: Xextern SIG_T                (*signal())();
                    763: Xextern Link            *islink(char *, Stat *);
                    764: Xextern char            *finduname(int);
                    765: Xextern char            *findgname(int);
                    766: Xextern int            findgid(char *gname);
                    767: X
                    768: X#else /* !__STDC__ */
                    769: X
                    770: Xextern Link                  *linkfrom();
                    771: Xextern Link                  *linkto();
                    772: Xextern char                  *mem_get();
                    773: Xextern char                  *mem_str();
                    774: Xextern char                  *syserr();
                    775: Xextern int            ar_read();
                    776: Xextern int            buf_read();
                    777: Xextern int            buf_skip();
                    778: Xextern int            create_archive();
                    779: Xextern int            dirneed();
                    780: Xextern int            read_archive();
                    781: Xextern int            inentry();
                    782: Xextern int            lineget();
                    783: Xextern int            name_match();
                    784: Xextern int            name_next();
                    785: Xextern int            nameopt();
                    786: Xextern int            open_archive();
                    787: Xextern int            open_tty();
                    788: Xextern int            openi();
                    789: Xextern int            openo();
                    790: Xextern int            pass();
                    791: Xextern int            passitem();
                    792: Xextern int                    read_header();
                    793: Xextern int            wildmat();
                    794: Xextern void           buf_allocate();
                    795: Xextern void           close_archive();
                    796: Xextern void           fatal();
                    797: Xextern void           name_gather();
                    798: Xextern void           name_init();
                    799: Xextern void           names_notfound();
                    800: Xextern void           next();
                    801: Xextern int            nextask();
                    802: Xextern void           outdata();
                    803: Xextern void           outwrite();
                    804: Xextern void           passdata();
                    805: Xextern void           print_entry();
                    806: Xextern void           warn();
                    807: Xextern void           warnarch();
                    808: Xextern void           write_eot();
                    809: Xextern void           get_archive_type();
                    810: Xextern char                  *getenv();
                    811: Xextern char                  *malloc();
                    812: Xextern char                  *strcat();
                    813: Xextern char                  *strcpy();
                    814: Xextern char                  *strncpy();
                    815: Xextern SIG_T                (*signal())();
                    816: Xextern OFFSET         lseek();
                    817: Xextern struct group    *getgrgid();
                    818: Xextern struct group    *getgrnam();
                    819: Xextern struct passwd   *getpwuid();
                    820: Xextern struct tm       *localtime();
                    821: Xextern time_t                 time();
                    822: Xextern uint                   sleep();
                    823: Xextern void                   _exit();
                    824: Xextern void                   exit();
                    825: Xextern void                   free();
                    826: Xextern Link            *islink();
                    827: Xextern char            *finduname();
                    828: Xextern char            *findgname();
                    829: Xextern int            findgid();
                    830: X
                    831: X#endif /* __STDC__ */
                    832: X#endif /* _PAX_FUNC_H */
                    833: END_OF_func.h
                    834: if test 5047 -ne `wc -c <func.h`; then
                    835:     echo shar: \"func.h\" unpacked with wrong size!
                    836: fi
                    837: # end of overwriting check
                    838: fi
                    839: if test -f link.c -a "${1}" != "-c" ; then 
                    840:   echo shar: Will not over-write existing file \"link.c\"
                    841: else
                    842: echo shar: Extracting \"link.c\" \(7575 characters\)
                    843: sed "s/^X//" >link.c <<'END_OF_link.c'
                    844: X/* $Source: /u/mark/src/pax/RCS/link.c,v $
                    845: X *
                    846: X * $Revision: 1.1 $
                    847: X *
                    848: X * link.c - functions for handling multiple file links 
                    849: X *
                    850: X * DESCRIPTION
                    851: X *
                    852: X *    These function manage the link chains which are used to keep track
                    853: X *    of outstanding links during archive reading and writing.
                    854: X *
                    855: X * AUTHOR
                    856: X *
                    857: X *    Mark H. Colburn, NAPS International ([email protected])
                    858: X *
                    859: X * Sponsored by The USENIX Association for public distribution. 
                    860: X *
                    861: X * Copyright (c) 1989 Mark H. Colburn.
                    862: X * All rights reserved.
                    863: X *
                    864: X * Redistribution and use in source and binary forms are permitted
                    865: X * provided that the above copyright notice is duplicated in all such 
                    866: X * forms and that any documentation, advertising materials, and other 
                    867: X * materials related to such distribution and use acknowledge that the 
                    868: X * software was developed * by Mark H. Colburn and sponsored by The 
                    869: X * USENIX Association. 
                    870: X *
                    871: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                    872: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                    873: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                    874: X *
                    875: X * $Log:      link.c,v $
                    876: X * Revision 1.1  88/12/23  18:02:12  mark
                    877: X * Initial revision
                    878: X * 
                    879: X */
                    880: X
                    881: X#ifndef lint
                    882: Xstatic char *ident = "$Id: link.c,v 1.1 88/12/23 18:02:12 mark Rel $";
                    883: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                    884: X#endif /* ! lint */
                    885: X
                    886: X
                    887: X/* Headers */
                    888: X
                    889: X#include "pax.h"
                    890: X
                    891: X
                    892: X/* Defines */
                    893: X
                    894: X/*
                    895: X * Address link information base. 
                    896: X */
                    897: X#define       LINKHASH(ino)   (linkbase + (ino) % NEL(linkbase))
                    898: X
                    899: X/*
                    900: X * Number of array elements. 
                    901: X */
                    902: X#define       NEL(a)          (sizeof(a) / sizeof(*(a)))
                    903: X
                    904: X
                    905: X
                    906: X/* Internal Identifiers */
                    907: X
                    908: Xstatic Link    *linkbase[256];        /* Unresolved link information */
                    909: X
                    910: X
                    911: X/* linkfrom - find a file to link from 
                    912: X *
                    913: X * DESCRIPTION
                    914: X *
                    915: X *    Linkfrom searches the link chain to see if there is a file in the
                    916: X *    link chain which has the same inode number as the file specified
                    917: X *    by the stat block pointed at by asb.  If a file is found, the
                    918: X *    name is returned to the caller, otherwise a NULL is returned.
                    919: X *
                    920: X * PARAMETERS
                    921: X *
                    922: X *    char    *name   - name of the file which we are attempting
                    923: X *                        to find a link for
                    924: X *    Stat    *asb    - stat structure of file to find a link to
                    925: X *
                    926: X * RETURNS
                    927: X *
                    928: X *    Returns a pointer to a link structure, or NULL if unsuccessful. 
                    929: X *
                    930: X */
                    931: X
                    932: X#ifdef __STDC__
                    933: X
                    934: XLink *linkfrom(char *name, Stat *asb)
                    935: X
                    936: X#else
                    937: X    
                    938: XLink *linkfrom(name, asb)
                    939: Xchar           *name;
                    940: XStat           *asb;
                    941: X
                    942: X#endif
                    943: X{
                    944: X    Link           *linkp;
                    945: X    Link           *linknext;
                    946: X    Path           *path;
                    947: X    Path           *pathnext;
                    948: X    Link          **abase;
                    949: X
                    950: X    for (linkp = *(abase = LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
                    951: X      if (linkp->l_nlink == 0) {
                    952: X          if (linkp->l_name) {
                    953: X              free((char *) linkp->l_name);
                    954: X          }
                    955: X          if (linknext = linkp->l_forw) {
                    956: X              linknext->l_back = linkp->l_back;
                    957: X          }
                    958: X          if (linkp->l_back) {
                    959: X              linkp->l_back->l_forw = linkp->l_forw;
                    960: X          }
                    961: X          free((char *) linkp);
                    962: X          *abase = (Link *) NULL;
                    963: X      } else if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
                    964: X          /* 
                    965: X           * check to see if a file with the name "name" exists in the 
                    966: X           * chain of files which we have for this particular link
                    967: X           */
                    968: X          for (path = linkp->l_path; path; path = pathnext) {
                    969: X              if (strcmp(path->p_name, name) == 0) {
                    970: X                  --linkp->l_nlink;
                    971: X                  if (path->p_name) {
                    972: X                      free(path->p_name);
                    973: X                  }
                    974: X                  if (pathnext = path->p_forw) {
                    975: X                      pathnext->p_back = path->p_back;
                    976: X                  }
                    977: X                  if (path->p_back) {
                    978: X                      path->p_back->p_forw = pathnext;
                    979: X                  }
                    980: X                  if (linkp->l_path == path) {
                    981: X                      linkp->l_path = pathnext;
                    982: X                  }
                    983: X                  free(path);
                    984: X                  return (linkp);
                    985: X              }
                    986: X              pathnext = path->p_forw;
                    987: X          }
                    988: X          return((Link *)NULL);
                    989: X      } else {
                    990: X          linknext = linkp->l_forw;
                    991: X      }
                    992: X    }
                    993: X    return ((Link *)NULL);
                    994: X}
                    995: X
                    996: X
                    997: X
                    998: X/* islink - determine whether a given file really a link
                    999: X *
                   1000: X * DESCRIPTION
                   1001: X *
                   1002: X *    Islink searches the link chain to see if there is a file in the
                   1003: X *    link chain which has the same inode number as the file specified
                   1004: X *    by the stat block pointed at by asb.  If a file is found, a
                   1005: X *    non-zero value is returned to the caller, otherwise a 0 is
                   1006: X *    returned.
                   1007: X *
                   1008: X * PARAMETERS
                   1009: X *
                   1010: X *    char    *name   - name of file to check to see if it is link.
                   1011: X *    Stat    *asb    - stat structure of file to find a link to
                   1012: X *
                   1013: X * RETURNS
                   1014: X *
                   1015: X *    Returns a pointer to a link structure, or NULL if unsuccessful. 
                   1016: X *
                   1017: X */
                   1018: X
                   1019: X#ifdef __STDC__
                   1020: X
                   1021: XLink *islink(char *name, Stat *asb)
                   1022: X
                   1023: X#else
                   1024: X    
                   1025: XLink *islink(name, asb)
                   1026: Xchar           *name;
                   1027: XStat           *asb;
                   1028: X
                   1029: X#endif
                   1030: X{
                   1031: X    Link           *linkp;
                   1032: X    Link           *linknext;
                   1033: X
                   1034: X    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
                   1035: X      if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
                   1036: X          if (strcmp(name, linkp->l_name) == 0) {
                   1037: X              return ((Link *) NULL);
                   1038: X          } 
                   1039: X          return (linkp);
                   1040: X      } else {
                   1041: X          linknext = linkp->l_forw;
                   1042: X      }
                   1043: X    }
                   1044: X    return ((Link *)NULL);
                   1045: X}
                   1046: X
                   1047: X
                   1048: X/* linkto  - remember a file with outstanding links 
                   1049: X *
                   1050: X * DESCRIPTION
                   1051: X *
                   1052: X *    Linkto adds the specified file to the link chain.  Any subsequent
                   1053: X *    calls to linkfrom which have the same inode will match the file
                   1054: X *    just entered.  If not enough space is available to make the link
                   1055: X *    then the item is not added to the link chain, and a NULL is
                   1056: X *    returned to the calling function.
                   1057: X *
                   1058: X * PARAMETERS
                   1059: X *
                   1060: X *    char    *name   - name of file to remember
                   1061: X *    Stat    *asb    - pointer to stat structure of file to remember
                   1062: X *
                   1063: X * RETURNS
                   1064: X *
                   1065: X *    Returns a pointer to the associated link structure, or NULL when 
                   1066: X *    linking is not possible. 
                   1067: X *
                   1068: X */
                   1069: X
                   1070: X#ifdef __STDC__
                   1071: X
                   1072: XLink *linkto(char *name, Stat *asb)
                   1073: X
                   1074: X#else
                   1075: X    
                   1076: XLink *linkto(name, asb)
                   1077: Xchar           *name;
                   1078: XStat           *asb;
                   1079: X
                   1080: X#endif
                   1081: X{
                   1082: X    Link           *linkp;
                   1083: X    Link           *linknext;
                   1084: X    Path           *path;
                   1085: X    Link          **abase;
                   1086: X
                   1087: X    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
                   1088: X      if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
                   1089: X          if ((path = (Path *) mem_get(sizeof(Path))) == (Path *) NULL || 
                   1090: X              (path->p_name = mem_str(name)) == (char *) NULL) {
                   1091: X              return((Link *) NULL);
                   1092: X          }
                   1093: X          if (path->p_forw = linkp->l_path) {
                   1094: X              if (linkp->l_path->p_forw) {
                   1095: X                  linkp->l_path->p_forw->p_back = path;
                   1096: X              }
                   1097: X          } else {
                   1098: X              linkp->l_path = path;
                   1099: X          }
                   1100: X          path->p_back = (Path *) NULL;
                   1101: X          return(linkp);
                   1102: X      } else {
                   1103: X          linknext = linkp->l_forw;
                   1104: X      }
                   1105: X    }
                   1106: X    /*
                   1107: X     * This is a brand new link, for which there is no other information
                   1108: X     */
                   1109: X
                   1110: X    if ((asb->sb_mode & S_IFMT) == S_IFDIR
                   1111: X      || (linkp = (Link *) mem_get(sizeof(Link))) == NULL
                   1112: X      || (linkp->l_name = mem_str(name)) == NULL) {
                   1113: X      return ((Link *) NULL);
                   1114: X    }
                   1115: X    linkp->l_dev = asb->sb_dev;
                   1116: X    linkp->l_ino = asb->sb_ino;
                   1117: X    linkp->l_nlink = asb->sb_nlink - 1;
                   1118: X    linkp->l_size = asb->sb_size;
                   1119: X    linkp->l_path = (Path *) NULL;
                   1120: X    if (linkp->l_forw = *(abase = LINKHASH(asb->sb_ino))) {
                   1121: X      linkp->l_forw->l_back = linkp;
                   1122: X    } else {
                   1123: X      *abase = linkp;
                   1124: X    }
                   1125: X    linkp->l_back = NULL;
                   1126: X    return (linkp);
                   1127: X}
                   1128: X
                   1129: X
                   1130: X/* linkleft - complain about files with unseen links 
                   1131: X *
                   1132: X * DESCRIPTION
                   1133: X *
                   1134: X *    Linksleft scans through the link chain to see if there were any
                   1135: X *    files which have outstanding links that were not processed by the
                   1136: X *    archive.  For each file in the link chain for which there was not
                   1137: X *    a file,  and error message is printed.
                   1138: X */
                   1139: X
                   1140: X#ifdef __STDC__
                   1141: X
                   1142: Xvoid linkleft(void)
                   1143: X
                   1144: X#else
                   1145: X    
                   1146: Xvoid linkleft()
                   1147: X
                   1148: X#endif
                   1149: X{
                   1150: X    Link           *lp;
                   1151: X    Link          **base;
                   1152: X
                   1153: X    for (base = linkbase; base < linkbase + NEL(linkbase); ++base) {
                   1154: X      for (lp = *base; lp; lp = lp->l_forw) {
                   1155: X          if (lp->l_nlink) {
                   1156: X              warn(lp->l_path->p_name, "Unseen link(s)");
                   1157: X          }
                   1158: X      }
                   1159: X    }
                   1160: X}
                   1161: END_OF_link.c
                   1162: if test 7575 -ne `wc -c <link.c`; then
                   1163:     echo shar: \"link.c\" unpacked with wrong size!
                   1164: fi
                   1165: # end of overwriting check
                   1166: fi
                   1167: if test -f names.c -a "${1}" != "-c" ; then 
                   1168:   echo shar: Will not over-write existing file \"names.c\"
                   1169: else
                   1170: echo shar: Extracting \"names.c\" \(5005 characters\)
                   1171: sed "s/^X//" >names.c <<'END_OF_names.c'
                   1172: X/* $Source: /u/mark/src/pax/RCS/names.c,v $
                   1173: X *
                   1174: X * $Revision: 1.1 $
                   1175: X *
                   1176: X * names.c - Look up user and/or group names. 
                   1177: X *
                   1178: X * DESCRIPTION
                   1179: X *
                   1180: X *    These functions support UID and GID name lookup.  The results are
                   1181: X *    cached to improve performance.
                   1182: X *
                   1183: X * AUTHOR
                   1184: X *
                   1185: X *    Mark H. Colburn, NAPS International ([email protected])
                   1186: X *
                   1187: X * Sponsored by The USENIX Association for public distribution. 
                   1188: X *
                   1189: X * Copyright (c) 1989 Mark H. Colburn.
                   1190: X * All rights reserved.
                   1191: X *
                   1192: X * Redistribution and use in source and binary forms are permitted
                   1193: X * provided that the above copyright notice is duplicated in all such 
                   1194: X * forms and that any documentation, advertising materials, and other 
                   1195: X * materials related to such distribution and use acknowledge that the 
                   1196: X * software was developed * by Mark H. Colburn and sponsored by The 
                   1197: X * USENIX Association. 
                   1198: X *
                   1199: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                   1200: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                   1201: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                   1202: X *
                   1203: X * $Log:      names.c,v $
                   1204: X * Revision 1.1  88/12/23  18:02:19  mark
                   1205: X * Initial revision
                   1206: X * 
                   1207: X */
                   1208: X
                   1209: X#ifndef lint
                   1210: Xstatic char *ident = "$Id: names.c,v 1.1 88/12/23 18:02:19 mark Rel $";
                   1211: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                   1212: X#endif /* ! lint */
                   1213: X
                   1214: X
                   1215: X/* Headers */
                   1216: X
                   1217: X#include "pax.h"
                   1218: X
                   1219: X
                   1220: X/* Defines */
                   1221: X
                   1222: X#define myuid ( my_uid < 0? (my_uid = getuid()): my_uid )
                   1223: X#define       mygid   ( my_gid < 0? (my_gid = getgid()): my_gid )
                   1224: X
                   1225: X
                   1226: X/* Internal Identifiers */
                   1227: X
                   1228: Xstatic int      saveuid = -993;
                   1229: Xstatic char     saveuname[TUNMLEN];
                   1230: Xstatic int      my_uid = -993;
                   1231: X
                   1232: Xstatic int      savegid = -993;
                   1233: Xstatic char     savegname[TGNMLEN];
                   1234: Xstatic int      my_gid = -993;
                   1235: X
                   1236: X
                   1237: X/* finduname - find a user or group name from a uid or gid
                   1238: X *
                   1239: X * DESCRIPTION
                   1240: X *
                   1241: X *    Look up a user name from a uid/gid, maintaining a cache. 
                   1242: X *
                   1243: X * PARAMETERS
                   1244: X *
                   1245: X *    char    uname[]         - name (to be returned to user)
                   1246: X *    int     uuid            - id of name to find
                   1247: X *
                   1248: X *
                   1249: X * RETURNS
                   1250: X *
                   1251: X *    Returns a name which is associated with the user id given.  If there
                   1252: X *    is not name which corresponds to the user-id given, then a pointer
                   1253: X *    to a string of zero length is returned.
                   1254: X *    
                   1255: X * FIXME
                   1256: X *
                   1257: X *    1. for now it's a one-entry cache. 
                   1258: X *    2. The "-993" is to reduce the chance of a hit on the first lookup. 
                   1259: X */
                   1260: X
                   1261: X#ifdef __STDC__
                   1262: X
                   1263: Xchar *finduname(int uuid)
                   1264: X
                   1265: X#else
                   1266: X    
                   1267: Xchar *finduname(uuid)
                   1268: Xint             uuid;
                   1269: X
                   1270: X#endif
                   1271: X{
                   1272: X    struct passwd  *pw;
                   1273: X
                   1274: X    if (uuid != saveuid) {
                   1275: X      saveuid = uuid;
                   1276: X      saveuname[0] = '\0';
                   1277: X      pw = getpwuid(uuid);
                   1278: X      if (pw) {
                   1279: X          strncpy(saveuname, pw->pw_name, TUNMLEN);
                   1280: X      }
                   1281: X    }
                   1282: X    return(saveuname);
                   1283: X}
                   1284: X
                   1285: X
                   1286: X/* finduid - get the uid for a given user name
                   1287: X *
                   1288: X * DESCRIPTION
                   1289: X *
                   1290: X *    This does just the opposit of finduname.  Given a user name it
                   1291: X *    finds the corresponding UID for that name.
                   1292: X *
                   1293: X * PARAMETERS
                   1294: X *
                   1295: X *    char    uname[]         - username to find a UID for
                   1296: X *
                   1297: X * RETURNS
                   1298: X *
                   1299: X *    The UID which corresponds to the uname given, if any.  If no UID
                   1300: X *    could be found, then the UID which corrsponds the user running the
                   1301: X *    program is returned.
                   1302: X *
                   1303: X */
                   1304: X
                   1305: X#ifdef __STDC__
                   1306: X
                   1307: Xint finduid(char *uname)
                   1308: X
                   1309: X#else
                   1310: X    
                   1311: Xint finduid(uname)
                   1312: Xchar            *uname;
                   1313: X
                   1314: X#endif
                   1315: X{
                   1316: X    struct passwd  *pw;
                   1317: X    extern struct passwd *getpwnam();
                   1318: X
                   1319: X    if (uname[0] != saveuname[0]/* Quick test w/o proc call */
                   1320: X      ||0 != strncmp(uname, saveuname, TUNMLEN)) {
                   1321: X      strncpy(saveuname, uname, TUNMLEN);
                   1322: X      pw = getpwnam(uname);
                   1323: X      if (pw) {
                   1324: X          saveuid = pw->pw_uid;
                   1325: X      } else {
                   1326: X          saveuid = myuid;
                   1327: X      }
                   1328: X    }
                   1329: X    return (saveuid);
                   1330: X}
                   1331: X
                   1332: X
                   1333: X/* findgname - look up a group name from a gid
                   1334: X *
                   1335: X * DESCRIPTION
                   1336: X *
                   1337: X *    Look up a group name from a gid, maintaining a cache.
                   1338: X *    
                   1339: X *
                   1340: X * PARAMETERS
                   1341: X *
                   1342: X *    int     ggid            - goupid of group to find
                   1343: X *
                   1344: X * RETURNS
                   1345: X *
                   1346: X *    A string which is associated with the group ID given.  If no name
                   1347: X *    can be found, a string of zero length is returned.
                   1348: X */
                   1349: X
                   1350: X#ifdef __STDC__
                   1351: X
                   1352: Xchar *findgname(int ggid)
                   1353: X
                   1354: X#else
                   1355: X    
                   1356: Xchar *findgname(ggid)
                   1357: Xint             ggid;
                   1358: X
                   1359: X#endif
                   1360: X{
                   1361: X    struct group   *gr;
                   1362: X
                   1363: X    if (ggid != savegid) {
                   1364: X      savegid = ggid;
                   1365: X      savegname[0] = '\0';
                   1366: X      setgrent();
                   1367: X      gr = getgrgid(ggid);
                   1368: X      if (gr) {
                   1369: X          strncpy(savegname, gr->gr_name, TGNMLEN);
                   1370: X      }
                   1371: X    }
                   1372: X    return(savegname);
                   1373: X}
                   1374: X
                   1375: X
                   1376: X
                   1377: X/* findgid - get the gid for a given group name
                   1378: X *
                   1379: X * DESCRIPTION
                   1380: X *
                   1381: X *    This does just the opposit of finduname.  Given a group name it
                   1382: X *    finds the corresponding GID for that name.
                   1383: X *
                   1384: X * PARAMETERS
                   1385: X *
                   1386: X *    char    uname[]         - groupname to find a GID for
                   1387: X *
                   1388: X * RETURNS
                   1389: X *
                   1390: X *    The GID which corresponds to the uname given, if any.  If no GID
                   1391: X *    could be found, then the GID which corrsponds the group running the
                   1392: X *    program is returned.
                   1393: X *
                   1394: X */
                   1395: X
                   1396: X#ifdef __STDC__
                   1397: X
                   1398: Xint findgid(char *gname)
                   1399: X
                   1400: X#else
                   1401: X    
                   1402: Xint findgid(gname)
                   1403: Xchar           *gname;
                   1404: X
                   1405: X#endif
                   1406: X{
                   1407: X    struct group   *gr;
                   1408: X
                   1409: X    /* Quick test w/o proc call */
                   1410: X    if (gname[0] != savegname[0] || strncmp(gname, savegname, TUNMLEN) != 0) {
                   1411: X      strncpy(savegname, gname, TUNMLEN);
                   1412: X      gr = getgrnam(gname);
                   1413: X      if (gr) {
                   1414: X          savegid = gr->gr_gid;
                   1415: X      } else {
                   1416: X          savegid = mygid;
                   1417: X      }
                   1418: X    }
                   1419: X    return (savegid);
                   1420: X}
                   1421: END_OF_names.c
                   1422: if test 5005 -ne `wc -c <names.c`; then
                   1423:     echo shar: \"names.c\" unpacked with wrong size!
                   1424: fi
                   1425: # end of overwriting check
                   1426: fi
                   1427: if test -f replace.c -a "${1}" != "-c" ; then 
                   1428:   echo shar: Will not over-write existing file \"replace.c\"
                   1429: else
                   1430: echo shar: Extracting \"replace.c\" \(6493 characters\)
                   1431: sed "s/^X//" >replace.c <<'END_OF_replace.c'
                   1432: X/* $Source: /u/mark/src/pax/RCS/replace.c,v $
                   1433: X *
                   1434: X * $Revision: 1.1 $
                   1435: X *
                   1436: X * replace.c - regular expression pattern replacement functions
                   1437: X *
                   1438: X * DESCRIPTION
                   1439: X *
                   1440: X *    These routines provide for regular expression file name replacement
                   1441: X *    as required by pax.
                   1442: X *
                   1443: X * AUTHORS
                   1444: X *
                   1445: X *    Mark H. Colburn, NAPS International
                   1446: X *
                   1447: X * Sponsored by The USENIX Association for public distribution. 
                   1448: X *
                   1449: X * Copyright (c) 1989 Mark H. Colburn.
                   1450: X * All rights reserved.
                   1451: X *
                   1452: X * Redistribution and use in source and binary forms are permitted
                   1453: X * provided that the above copyright notice is duplicated in all such 
                   1454: X * forms and that any documentation, advertising materials, and other 
                   1455: X * materials related to such distribution and use acknowledge that the 
                   1456: X * software was developed * by Mark H. Colburn and sponsored by The 
                   1457: X * USENIX Association. 
                   1458: X *
                   1459: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                   1460: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                   1461: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                   1462: X *
                   1463: X * $Log:      replace.c,v $
                   1464: X * Revision 1.1  88/12/23  18:02:36  mark
                   1465: X * Initial revision
                   1466: X * 
                   1467: X */
                   1468: X
                   1469: X#ifndef lint
                   1470: Xstatic char *ident = "$Id: replace.c,v 1.1 88/12/23 18:02:36 mark Rel $";
                   1471: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                   1472: X#endif /* not lint */
                   1473: X
                   1474: X/* Headers */
                   1475: X
                   1476: X#include "pax.h"
                   1477: X
                   1478: X
                   1479: X/* add_replstr - add a replacement string to the replacement string list
                   1480: X *
                   1481: X * DESCRIPTION
                   1482: X *
                   1483: X *    Add_replstr adds a replacement string to the replacement string
                   1484: X *    list which is applied each time a file is about to be processed.
                   1485: X *
                   1486: X * PARAMETERS
                   1487: X *
                   1488: X *    char    *pattern        - A regular expression which is to be parsed
                   1489: X */
                   1490: X
                   1491: X#ifdef __STDC__
                   1492: X
                   1493: Xvoid add_replstr(char *pattern)
                   1494: X
                   1495: X#else
                   1496: X
                   1497: Xvoid add_replstr(pattern)
                   1498: Xchar           *pattern;
                   1499: X
                   1500: X#endif
                   1501: X{
                   1502: X    char           *p;
                   1503: X    char            sep;
                   1504: X    Replstr        *rptr;
                   1505: X    int             len;
                   1506: X
                   1507: X    if ((len = strlen(pattern)) < 4) {
                   1508: X      warn("Replacement string not added",
                   1509: X               "Malformed substitution syntax");
                   1510: X      return;
                   1511: X    }
                   1512: X    if ((rptr = (Replstr *) malloc(sizeof(Replstr))) == NULL) {
                   1513: X      warn("Replacement string not added", "No space");
                   1514: X      return;
                   1515: X    }
                   1516: X
                   1517: X    /* First character is the delimeter... */
                   1518: X    sep = *pattern;
                   1519: X
                   1520: X    /* Get trailing g and/or p */
                   1521: X    p = pattern + len - 1;
                   1522: X    while (*p != sep) {
                   1523: X      if (*p == 'g') {
                   1524: X            rptr->global = 1;
                   1525: X      } else if (*p == 'p') {
                   1526: X          rptr->print = 1;
                   1527: X      } else {
                   1528: X          warn(p, "Invalid RE modifier");
                   1529: X      }
                   1530: X      p--;
                   1531: X    }
                   1532: X
                   1533: X    if (*p != sep) {
                   1534: X      warn("Replacement string not added", "Bad delimeters");
                   1535: X      free(rptr);
                   1536: X      return;
                   1537: X    }
                   1538: X    /* strip off leading and trailing delimeter */
                   1539: X    *p = '\0';
                   1540: X    pattern++;
                   1541: X
                   1542: X    /* find the separating '/' in the pattern */
                   1543: X    p = pattern;
                   1544: X    while (*p) {
                   1545: X      if (*p == sep) {
                   1546: X          break;
                   1547: X      }
                   1548: X      if (*p == '\\' && *(p + 1) != '\0') {
                   1549: X          p++;
                   1550: X      }
                   1551: X      p++;
                   1552: X    }
                   1553: X    if (*p != sep) {
                   1554: X      warn("Replacement string not added", "Bad delimeters");
                   1555: X      free(rptr);
                   1556: X      return;
                   1557: X    }
                   1558: X    *p++ = '\0';
                   1559: X
                   1560: X    /*
                   1561: X     * Now pattern points to 'old' and p points to 'new' and both are '\0'
                   1562: X     * terminated 
                   1563: X     */
                   1564: X    if ((rptr->comp = regcomp(pattern)) == NULL) {
                   1565: X      warn("Replacement string not added", "Invalid RE");
                   1566: X      free(rptr);
                   1567: X      return;
                   1568: X    }
                   1569: X    rptr->replace = p;
                   1570: X    rptr->next = NULL;
                   1571: X    if (rplhead == NULL) {
                   1572: X      rplhead = rptr;
                   1573: X      rpltail = rptr;
                   1574: X    } else {
                   1575: X      rpltail->next = rptr;
                   1576: X      rpltail = rptr;
                   1577: X    }
                   1578: X}
                   1579: X
                   1580: X
                   1581: X
                   1582: X/* rpl_name - possibly replace a name with a regular expression
                   1583: X *
                   1584: X * DESCRIPTION
                   1585: X *
                   1586: X *    The string name is searched for in the list of regular expression
                   1587: X *    substituions.  If the string matches any of the regular expressions
                   1588: X *    then the string is modified as specified by the user.
                   1589: X *
                   1590: X * PARAMETERS
                   1591: X *
                   1592: X *    char    *name   - name to search for and possibly modify
                   1593: X */
                   1594: X
                   1595: X#ifdef __STDC__
                   1596: X
                   1597: Xvoid rpl_name(char *name)
                   1598: X
                   1599: X#else
                   1600: X
                   1601: Xvoid rpl_name(name)
                   1602: Xchar           *name;
                   1603: X
                   1604: X#endif
                   1605: X{
                   1606: X    int             found = 0;
                   1607: X    int             ret;
                   1608: X    Replstr        *rptr;
                   1609: X    char            buff[PATH_MAX + 1];
                   1610: X    char            buff1[PATH_MAX + 1];
                   1611: X    char            buff2[PATH_MAX + 1];
                   1612: X    char           *p;
                   1613: X    char           *b;
                   1614: X
                   1615: X    strcpy(buff, name);
                   1616: X    for (rptr = rplhead; !found && rptr != NULL; rptr = rptr->next) {
                   1617: X      do {
                   1618: X          if ((ret = regexec(rptr->comp, buff)) != 0) {
                   1619: X              p = buff;
                   1620: X              b = buff1;
                   1621: X              while (p < rptr->comp->startp[0]) {
                   1622: X                  *b++ = *p++;
                   1623: X              }
                   1624: X              p = rptr->replace;
                   1625: X              while (*p) {
                   1626: X                  *b++ = *p++;
                   1627: X              }
                   1628: X              strcpy(b, rptr->comp->endp[0]);
                   1629: X              found = 1;
                   1630: X              regsub(rptr->comp, buff1, buff2);
                   1631: X              strcpy(buff, buff2);
                   1632: X          }
                   1633: X      } while (ret && rptr->global);
                   1634: X      if (found) {
                   1635: X          if (rptr->print) {
                   1636: X              fprintf(stderr, "%s >> %s\n", name, buff);
                   1637: X          }
                   1638: X          strcpy(name, buff);
                   1639: X      }
                   1640: X    }
                   1641: X}
                   1642: X
                   1643: X
                   1644: X/* get_disposition - get a file disposition
                   1645: X *
                   1646: X * DESCRIPTION
                   1647: X *
                   1648: X *    Get a file disposition from the user.  If the user enters 'y'
                   1649: X *    the the file is processed, anything else and the file is ignored.
                   1650: X *    If the user enters EOF, then the PAX exits with a non-zero return
                   1651: X *    status.
                   1652: X *
                   1653: X * PARAMETERS
                   1654: X *
                   1655: X *    char    *mode   - string signifying the action to be taken on file
                   1656: X *    char    *name   - the name of the file
                   1657: X *
                   1658: X * RETURNS
                   1659: X *
                   1660: X *    Returns 1 if the file should be processed, 0 if it should not.
                   1661: X */
                   1662: X
                   1663: X#ifdef __STDC__
                   1664: X
                   1665: Xint get_disposition(char *mode, char *name)
                   1666: X
                   1667: X#else
                   1668: X
                   1669: Xint get_disposition(mode, name)
                   1670: Xchar  *mode;
                   1671: Xchar  *name;
                   1672: X
                   1673: X#endif
                   1674: X{
                   1675: X    char      ans[2];
                   1676: X    char      buf[PATH_MAX + 10];
                   1677: X
                   1678: X    if (f_disposition) {
                   1679: X      sprintf(buf, "%s %s? ", mode, name);
                   1680: X      if (nextask(buf, ans, sizeof(ans)) == -1 || ans[0] == 'q') {
                   1681: X          exit(0);
                   1682: X      }
                   1683: X      if (strlen(ans) == 0 || ans[0] != 'y') {
                   1684: X          return(1);
                   1685: X      } 
                   1686: X    } 
                   1687: X    return(0);
                   1688: X}
                   1689: X
                   1690: X
                   1691: X/* get_newname - prompt the user for a new filename
                   1692: X *
                   1693: X * DESCRIPTION
                   1694: X *
                   1695: X *    The user is prompted with the name of the file which is currently
                   1696: X *    being processed.  The user may choose to rename the file by
                   1697: X *    entering the new file name after the prompt; the user may press
                   1698: X *    carriage-return/newline, which will skip the file or the user may
                   1699: X *    type an 'EOF' character, which will cause the program to stop.
                   1700: X *
                   1701: X * PARAMETERS
                   1702: X *
                   1703: X *    char    *name           - filename, possibly modified by user
                   1704: X *    int     size            - size of allowable new filename
                   1705: X *
                   1706: X * RETURNS
                   1707: X *
                   1708: X *    Returns 0 if successfull, or -1 if an error occurred.
                   1709: X *
                   1710: X */
                   1711: X
                   1712: X#ifdef __STDC__
                   1713: X
                   1714: Xint get_newname(char *name, int size)
                   1715: X
                   1716: X#else
                   1717: X
                   1718: Xint get_newname(name, size)
                   1719: Xchar  *name;
                   1720: Xint   size;
                   1721: X
                   1722: X#endif
                   1723: X{
                   1724: X    char      buf[PATH_MAX + 10];
                   1725: X
                   1726: X    if (f_interactive) {
                   1727: X      sprintf(buf, "rename %s? ", name);
                   1728: X      if (nextask(buf, name, size) == -1) {
                   1729: X          exit(0);
                   1730: X      }
                   1731: X      if (strlen(name) == 0) {
                   1732: X          return(1);
                   1733: X      }
                   1734: X    }
                   1735: X    return(0);
                   1736: X}
                   1737: END_OF_replace.c
                   1738: if test 6493 -ne `wc -c <replace.c`; then
                   1739:     echo shar: \"replace.c\" unpacked with wrong size!
                   1740: fi
                   1741: # end of overwriting check
                   1742: fi
                   1743: if test -f ttyio.c -a "${1}" != "-c" ; then 
                   1744:   echo shar: Will not over-write existing file \"ttyio.c\"
                   1745: else
                   1746: echo shar: Extracting \"ttyio.c\" \(6321 characters\)
                   1747: sed "s/^X//" >ttyio.c <<'END_OF_ttyio.c'
                   1748: X/* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
                   1749: X *
                   1750: X * $Revision: 1.1 $
                   1751: X *
                   1752: X * ttyio.c - Terminal/Console I/O functions for all archive interfaces
                   1753: X *
                   1754: X * DESCRIPTION
                   1755: X *
                   1756: X *    These routines provide a consistent, general purpose interface to
                   1757: X *    the user via the users terminal, if it is available to the
                   1758: X *    process.
                   1759: X *
                   1760: X * AUTHOR
                   1761: X *
                   1762: X *     Mark H. Colburn, NAPS International ([email protected])
                   1763: X *
                   1764: X * Sponsored by The USENIX Association for public distribution. 
                   1765: X *
                   1766: X * Copyright (c) 1989 Mark H. Colburn.
                   1767: X * All rights reserved.
                   1768: X *
                   1769: X * Redistribution and use in source and binary forms are permitted
                   1770: X * provided that the above copyright notice is duplicated in all such 
                   1771: X * forms and that any documentation, advertising materials, and other 
                   1772: X * materials related to such distribution and use acknowledge that the 
                   1773: X * software was developed * by Mark H. Colburn and sponsored by The 
                   1774: X * USENIX Association. 
                   1775: X *
                   1776: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                   1777: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                   1778: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                   1779: X *
                   1780: X * $Log:      ttyio.c,v $
                   1781: X * Revision 1.1  88/12/23  18:02:39  mark
                   1782: X * Initial revision
                   1783: X * 
                   1784: X */
                   1785: X
                   1786: X#ifndef lint
                   1787: Xstatic char *ident = "$Id: ttyio.c,v 1.1 88/12/23 18:02:39 mark Rel $";
                   1788: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                   1789: X#endif /* ! lint */
                   1790: X
                   1791: X
                   1792: X/* Headers */
                   1793: X
                   1794: X#include "pax.h"
                   1795: X
                   1796: X
                   1797: X/* open_tty - open the terminal for interactive queries
                   1798: X *
                   1799: X * DESCRIPTION
                   1800: X *
                   1801: X *    Assumes that background processes ignore interrupts and that the
                   1802: X *    open() or the isatty() will fail for processes which are not
                   1803: X *    attached to terminals. Returns a file descriptor or -1 if
                   1804: X *    unsuccessful. 
                   1805: X *
                   1806: X * RETURNS
                   1807: X *
                   1808: X *    Returns a file descriptor which can be used to read and write
                   1809: X *    directly to the user's terminal, or -1 on failure.  
                   1810: X *
                   1811: X * ERRORS
                   1812: X *
                   1813: X *    If SIGINT cannot be ignored, or the open fails, or the newly opened
                   1814: X *    terminal device is not a tty, then open_tty will return a -1 to the
                   1815: X *    caller.
                   1816: X */
                   1817: X
                   1818: X#ifdef __STDC__
                   1819: X
                   1820: Xint open_tty(void)
                   1821: X
                   1822: X#else
                   1823: X
                   1824: Xint open_tty()
                   1825: X
                   1826: X#endif
                   1827: X{
                   1828: X    int             fd;               /* file descriptor for terminal */
                   1829: X    SIG_T         (*intr)();  /* used to restore interupts if signal fails */
                   1830: X
                   1831: X    if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
                   1832: X      return (-1);
                   1833: X    }
                   1834: X    signal(SIGINT, intr);
                   1835: X    if ((fd = open(TTY, O_RDWR)) < 0) {
                   1836: X      return (-1);
                   1837: X    }
                   1838: X    if (isatty(fd)) {
                   1839: X      return (fd);
                   1840: X    }
                   1841: X    close(fd);
                   1842: X    return (-1);
                   1843: X}
                   1844: X
                   1845: X
                   1846: X/* nextask - ask a question and get a response
                   1847: X *
                   1848: X * DESCRIPTION
                   1849: X *
                   1850: X *    Give the user a prompt and wait for their response.  The prompt,
                   1851: X *    located in "msg" is printed, then the user is allowed to type
                   1852: X *    a response to the message.  The first "limit" characters of the
                   1853: X *    user response is stored in "answer".
                   1854: X *
                   1855: X *    Nextask ignores spaces and tabs. 
                   1856: X *
                   1857: X * PARAMETERS
                   1858: X *
                   1859: X *    char *msg       - Message to display for user 
                   1860: X *    char *answer    - Pointer to user's response to question 
                   1861: X *    int limit       - Limit of length for user's response
                   1862: X *
                   1863: X * RETURNS
                   1864: X *
                   1865: X *    Returns the number of characters in the user response to the 
                   1866: X *    calling function.  If an EOF was encountered, a -1 is returned to
                   1867: X *    the calling function.  If an error occured which causes the read
                   1868: X *    to return with a value of -1, then the function will return a
                   1869: X *    non-zero return status to the calling process, and abort
                   1870: X *    execution.
                   1871: X */
                   1872: X
                   1873: X#ifdef __STDC__
                   1874: X
                   1875: Xint nextask(char *msg, char *answer, int limit)
                   1876: X
                   1877: X#else
                   1878: X
                   1879: Xint nextask(msg, answer, limit)
                   1880: Xchar           *msg;          /* message to display for user */
                   1881: Xchar           *answer;               /* pointer to user's response to question */
                   1882: Xint             limit;                /* limit of length for user's response */
                   1883: X
                   1884: X#endif
                   1885: X{
                   1886: X    int             idx;      /* index into answer for character input */
                   1887: X    int             got;      /* number of characters read */
                   1888: X    char            c;                /* character read */
                   1889: X
                   1890: X    if (ttyf < 0) {
                   1891: X      fatal("/dev/tty Unavailable");
                   1892: X    }
                   1893: X    write(ttyf, msg, (uint) strlen(msg));
                   1894: X    idx = 0;
                   1895: X    while ((got = read(ttyf, &c, 1)) == 1) {
                   1896: X      if (c == '\n') {
                   1897: X          break;
                   1898: X      } else if (c == ' ' || c == '\t') {
                   1899: X          continue;
                   1900: X      } else if (idx < limit - 1) {
                   1901: X          answer[idx++] = c;
                   1902: X      }
                   1903: X    }
                   1904: X    if (got == 0) {           /* got an EOF */
                   1905: X        return(-1);
                   1906: X    }
                   1907: X    if (got < 0) {
                   1908: X      fatal(syserr());
                   1909: X    }
                   1910: X    answer[idx] = '\0';
                   1911: X    return(0);
                   1912: X}
                   1913: X
                   1914: X
                   1915: X/* lineget - get a line from a given stream
                   1916: X *
                   1917: X * DESCRIPTION
                   1918: X * 
                   1919: X *    Get a line of input for the stream named by "stream".  The data on
                   1920: X *    the stream is put into the buffer "buf".
                   1921: X *
                   1922: X * PARAMETERS
                   1923: X *
                   1924: X *    FILE *stream            - Stream to get input from 
                   1925: X *    char *buf               - Buffer to put input into
                   1926: X *
                   1927: X * RETURNS
                   1928: X *
                   1929: X *    Returns 0 if successful, -1 at EOF. 
                   1930: X */
                   1931: X
                   1932: X#ifdef __STDC__
                   1933: X
                   1934: Xint lineget(FILE *stream, char *buf)
                   1935: X
                   1936: X#else
                   1937: X
                   1938: Xint lineget(stream, buf)
                   1939: XFILE           *stream;               /* stream to get input from */
                   1940: Xchar           *buf;          /* buffer to put input into */
                   1941: X
                   1942: X#endif
                   1943: X{
                   1944: X    int             c;
                   1945: X
                   1946: X    for (;;) {
                   1947: X      if ((c = getc(stream)) == EOF) {
                   1948: X          return (-1);
                   1949: X      }
                   1950: X      if (c == '\n') {
                   1951: X          break;
                   1952: X      }
                   1953: X      *buf++ = c;
                   1954: X    }
                   1955: X    *buf = '\0';
                   1956: X    return (0);
                   1957: X}
                   1958: X
                   1959: X
                   1960: X/* next - Advance to the next archive volume. 
                   1961: X *
                   1962: X * DESCRIPTION
                   1963: X *
                   1964: X *    Prompts the user to replace the backup medium with a new volume
                   1965: X *    when the old one is full.  There are some cases, such as when
                   1966: X *    archiving to a file on a hard disk, that the message can be a
                   1967: X *    little surprising.  Assumes that background processes ignore
                   1968: X *    interrupts and that the open() or the isatty() will fail for
                   1969: X *    processes which are not attached to terminals. Returns a file
                   1970: X *    descriptor or -1 if unsuccessful. 
                   1971: X *
                   1972: X * PARAMETERS
                   1973: X *
                   1974: X *    int mode        - mode of archive (READ, WRITE, PASS) 
                   1975: X */
                   1976: X
                   1977: X#ifdef __STDC__
                   1978: X
                   1979: Xvoid next(int mode)
                   1980: X
                   1981: X#else
                   1982: X
                   1983: Xvoid next(mode)
                   1984: Xint             mode;         /* mode of archive (READ, WRITE, PASS) */
                   1985: X
                   1986: X#endif
                   1987: X{
                   1988: X    char            msg[200]; /* buffer for message display */ 
                   1989: X    char            answer[20];       /* buffer for user's answer */
                   1990: X    int             ret;
                   1991: X
                   1992: X    close_archive();
                   1993: X
                   1994: X    sprintf(msg, "\
                   1995: X%s: Ready for volume %u\n\
                   1996: X%s: Type \"go\" when ready to proceed (or \"quit\" to abort): \07",
                   1997: X                 myname, arvolume + 1, myname);
                   1998: X    for (;;) {
                   1999: X      ret = nextask(msg, answer, sizeof(answer));
                   2000: X      if (ret == -1 || strcmp(answer, "quit") == 0) {
                   2001: X          fatal("Aborted");
                   2002: X      }
                   2003: X      if (strcmp(answer, "go") == 0 && open_archive(mode) == 0) {
                   2004: X          break;
                   2005: X      }
                   2006: X    }
                   2007: X    warnarch("Continuing", (OFFSET) 0);
                   2008: X}
                   2009: END_OF_ttyio.c
                   2010: if test 6321 -ne `wc -c <ttyio.c`; then
                   2011:     echo shar: \"ttyio.c\" unpacked with wrong size!
                   2012: fi
                   2013: # end of overwriting check
                   2014: fi
                   2015: if test -f warn.c -a "${1}" != "-c" ; then 
                   2016:   echo shar: Will not over-write existing file \"warn.c\"
                   2017: else
                   2018: echo shar: Extracting \"warn.c\" \(5446 characters\)
                   2019: sed "s/^X//" >warn.c <<'END_OF_warn.c'
                   2020: X/* $Source: /u/mark/src/pax/RCS/warn.c,v $
                   2021: X *
                   2022: X * $Revision: 1.1 $
                   2023: X *
                   2024: X * warn.c - miscellaneous user warning routines 
                   2025: X *
                   2026: X * DESCRIPTION
                   2027: X *
                   2028: X *    These routines provide the user with various forms of warning
                   2029: X *    and informational messages.
                   2030: X *
                   2031: X * AUTHOR
                   2032: X *
                   2033: X *     Mark H. Colburn, NAPS International ([email protected])
                   2034: X *
                   2035: X * Sponsored by The USENIX Association for public distribution. 
                   2036: X *
                   2037: X * Copyright (c) 1989 Mark H. Colburn.
                   2038: X * All rights reserved.
                   2039: X *
                   2040: X * Redistribution and use in source and binary forms are permitted
                   2041: X * provided that the above copyright notice is duplicated in all such 
                   2042: X * forms and that any documentation, advertising materials, and other 
                   2043: X * materials related to such distribution and use acknowledge that the 
                   2044: X * software was developed * by Mark H. Colburn and sponsored by The 
                   2045: X * USENIX Association. 
                   2046: X *
                   2047: X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                   2048: X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                   2049: X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                   2050: X *
                   2051: X * $Log:      warn.c,v $
                   2052: X * Revision 1.1  88/12/23  18:02:40  mark
                   2053: X * Initial revision
                   2054: X * 
                   2055: X */
                   2056: X
                   2057: X#ifndef lint
                   2058: Xstatic char *ident = "$Id: warn.c,v 1.1 88/12/23 18:02:40 mark Rel $";
                   2059: Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
                   2060: X#endif /* ! lint */
                   2061: X
                   2062: X
                   2063: X/* Headers */
                   2064: X
                   2065: X#include "pax.h"
                   2066: X
                   2067: X
                   2068: X/* Function Prototypes */
                   2069: X
                   2070: X#ifdef __STDC__
                   2071: X
                   2072: Xstatic void prsize(FILE *, OFFSET);
                   2073: X
                   2074: X#else /* !__STDC__ */
                   2075: X
                   2076: Xstatic void prsize();
                   2077: X
                   2078: X#endif /* __STDC__ */
                   2079: X
                   2080: X
                   2081: X/* warnarch - print an archive-related warning message and offset
                   2082: X *
                   2083: X * DESCRIPTION
                   2084: X *
                   2085: X *    Present the user with an error message and an archive offset at
                   2086: X *    which the error occured.   This can be useful for diagnosing or
                   2087: X *    fixing damaged archives.
                   2088: X *
                   2089: X * PARAMETERS
                   2090: X *
                   2091: X *    char    *msg    - A message string to be printed for the user.
                   2092: X *    OFFSET  adjust  - An adjustment which is added to the current 
                   2093: X *                      archive position to tell the user exactly where 
                   2094: X *                      the error occurred.
                   2095: X */
                   2096: X
                   2097: X#ifdef __STDC__
                   2098: X
                   2099: Xvoid warnarch(char *msg, OFFSET adjust)
                   2100: X
                   2101: X#else 
                   2102: X
                   2103: Xvoid warnarch(msg, adjust)
                   2104: Xchar           *msg;
                   2105: XOFFSET          adjust;
                   2106: X
                   2107: X#endif
                   2108: X{
                   2109: X    fprintf(stderr, "%s: [offset ", myname);
                   2110: X    prsize(stderr, total - adjust);
                   2111: X    fprintf(stderr, "]: %s\n", msg);
                   2112: X}
                   2113: X
                   2114: X
                   2115: X/* syserr - return pointer to appropriate system error message
                   2116: X *
                   2117: X * DESCRIPTION
                   2118: X *
                   2119: X *    Get an error message string which is appropriate for the setting
                   2120: X *    of the errno variable.
                   2121: X *
                   2122: X * RETURNS
                   2123: X *
                   2124: X *    Returns a pointer to a string which has an appropriate error
                   2125: X *    message for the present value of errno.  The error message
                   2126: X *    strings are taken from sys_errlist[] where appropriate.  If an
                   2127: X *    appropriate message is not available in sys_errlist, then a
                   2128: X *    pointer to the string "Unknown error (errno <errvalue>)" is 
                   2129: X *    returned instead.
                   2130: X */
                   2131: X
                   2132: X#ifdef __STDC__
                   2133: X
                   2134: Xchar *syserr(void)
                   2135: X
                   2136: X#else
                   2137: X
                   2138: Xchar *syserr()
                   2139: X
                   2140: X#endif
                   2141: X{
                   2142: X    static char     msg[40];          /* used for "Unknown error" messages */
                   2143: X
                   2144: X    if (errno > 0 && errno < sys_nerr) {
                   2145: X      return (sys_errlist[errno]);
                   2146: X    }
                   2147: X    sprintf(msg, "Unknown error (errno %d)", errno);
                   2148: X    return (msg);
                   2149: X}
                   2150: X
                   2151: X
                   2152: X/* prsize - print a file offset on a file stream
                   2153: X *
                   2154: X * DESCRIPTION
                   2155: X *
                   2156: X *    Prints a file offset to a specific file stream.  The file offset is
                   2157: X *    of the form "%dm+%dk+%d", where the number preceeding the "m" and
                   2158: X *    the "k" stand for the number of Megabytes and the number of
                   2159: X *    Kilobytes, respectivley, which have been processed so far.
                   2160: X *
                   2161: X * PARAMETERS
                   2162: X *
                   2163: X *    FILE  *stream   - Stream which is to be used for output 
                   2164: X *    OFFSET size     - Current archive position to be printed on the output 
                   2165: X *                      stream in the form: "%dm+%dk+%d".
                   2166: X *
                   2167: X */
                   2168: X
                   2169: X#ifdef __STDC__
                   2170: X
                   2171: Xstatic void prsize(FILE *stream, OFFSET size)
                   2172: X
                   2173: X#else
                   2174: X
                   2175: Xstatic void prsize(stream, size)
                   2176: XFILE           *stream;               /* stream which is used for output */
                   2177: XOFFSET          size;         /* current archive position to be printed */
                   2178: X
                   2179: X#endif
                   2180: X
                   2181: X{
                   2182: X    OFFSET          n;
                   2183: X
                   2184: X    if (n = (size / (1024 * 1024))) {
                   2185: X      fprintf(stream, "%ldm+", n);
                   2186: X      size -= n * 1024 * 1024;
                   2187: X    }
                   2188: X    if (n = (size / 1024)) {
                   2189: X      fprintf(stream, "%ldk+", n);
                   2190: X      size -= n * 1024;
                   2191: X    }
                   2192: X    fprintf(stream, "%ld", size);
                   2193: X}
                   2194: X
                   2195: X
                   2196: X/* fatal - print fatal message and exit
                   2197: X *
                   2198: X * DESCRIPTION
                   2199: X *
                   2200: X *    Fatal prints the program's name along with an error message, then
                   2201: X *    exits the program with a non-zero return code.
                   2202: X *
                   2203: X * PARAMETERS
                   2204: X *
                   2205: X *    char    *why    - description of reason for termination 
                   2206: X *            
                   2207: X * RETURNS
                   2208: X *
                   2209: X *    Returns an exit code of 1 to the parent process.
                   2210: X */
                   2211: X
                   2212: X#ifdef __STDC__
                   2213: X
                   2214: Xvoid fatal(char *why)
                   2215: X
                   2216: X#else
                   2217: X
                   2218: Xvoid fatal(why)
                   2219: Xchar           *why;          /* description of reason for termination */
                   2220: X
                   2221: X#endif
                   2222: X{
                   2223: X    fprintf(stderr, "%s: %s\n", myname, why);
                   2224: X    exit(1);
                   2225: X}
                   2226: X
                   2227: X
                   2228: X
                   2229: X/* warn - print a warning message
                   2230: X *
                   2231: X * DESCRIPTION
                   2232: X *
                   2233: X *    Print an error message listing the program name, the actual error
                   2234: X *    which occurred and an informational message as to why the error
                   2235: X *    occurred on the standard error device.  The standard error is
                   2236: X *    flushed after the error is printed to assure that the user gets
                   2237: X *    the message in a timely fasion.
                   2238: X *
                   2239: X * PARAMETERS
                   2240: X *
                   2241: X *    char *what      - Pointer to string describing what failed.
                   2242: X *    char *why       - Pointer to string describing why did it failed.
                   2243: X */
                   2244: X
                   2245: X#ifdef __STDC__
                   2246: X
                   2247: Xvoid warn(char *what, char *why)
                   2248: X
                   2249: X#else
                   2250: X
                   2251: Xvoid warn(what, why)
                   2252: Xchar           *what;         /* message as to what the error was */
                   2253: Xchar           *why;          /* explanation why the error occurred */
                   2254: X
                   2255: X#endif
                   2256: X{
                   2257: X    fprintf(stderr, "%s: %s : %s\n", myname, what, why);
                   2258: X    fflush(stderr);
                   2259: X}
                   2260: END_OF_warn.c
                   2261: if test 5446 -ne `wc -c <warn.c`; then
                   2262:     echo shar: \"warn.c\" unpacked with wrong size!
                   2263: fi
                   2264: # end of overwriting check
                   2265: fi
                   2266: echo shar: End of archive 2 \(of 6\).
                   2267: cp /dev/null ark2isdone
                   2268: MISSING=""
                   2269: for I in 1 2 3 4 5 6 ; do
                   2270:     if test ! -f ark${I}isdone ; then
                   2271:        MISSING="${MISSING} ${I}"
                   2272:     fi
                   2273: done
                   2274: if test "${MISSING}" = "" ; then
                   2275:     echo You have unpacked all 6 archives.
                   2276:     rm -f ark[1-9]isdone
                   2277: else
                   2278:     echo You still need to unpack the following archives:
                   2279:     echo "        " ${MISSING}
                   2280: fi
                   2281: ##  End of shell archive.
                   2282: exit 0
                   2283: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.