home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / linux / backup / star-1.3.1.tar.gz / star-1.3.1.tar / star-1.3.1 / star / header.c < prev    next >
C/C++ Source or Header  |  2001-04-07  |  35KB  |  1,466 lines

  1. /* @(#)header.c    1.43 01/04/07 Copyright 1985, 1995 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)header.c    1.43 01/04/07 Copyright 1985, 1995 J. Schilling";
  5. #endif
  6. /*
  7.  *    Handling routines to read/write, parse/create
  8.  *    archive headers
  9.  *
  10.  *    Copyright (c) 1985, 1995 J. Schilling
  11.  */
  12. /*
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2, or (at your option)
  16.  * any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. #include <mconfig.h>
  29. #include <stdio.h>
  30. #include "star.h"
  31. #include "props.h"
  32. #include "table.h"
  33. #include <sys/types.h>
  34. #include <dirdefs.h>
  35. #include <standard.h>
  36. #include <stdxlib.h>
  37. #include <strdefs.h>
  38. #define    __XDEV__    /* Needed to activate _dev_major()/_dev_minor() */
  39. #include <device.h>
  40. #include <schily.h>
  41. #include "starsubs.h"
  42.  
  43.     /* ustar */
  44. LOCAL    char    magic[TMAGLEN] = TMAGIC;
  45.     /* star */
  46. LOCAL    char    stmagic[STMAGLEN] = STMAGIC;
  47.     /* gnu tar */
  48. LOCAL    char    gmagic[GMAGLEN] = GMAGIC;
  49.  
  50. LOCAL    char    *hdrtxt[] = {
  51.     /* 0 */    "UNDEFINED",
  52.     /* 1 */    "unknown tar",
  53.     /* 2 */    "old tar",
  54.     /* 3 */    "star",
  55.     /* 4 */    "gnu tar",
  56.     /* 5 */    "ustar",
  57.     /* 6 */    "xstar",
  58.     /* 7 */    "xustar",
  59.     /* 8 */    "res8",        /* Reserved    */
  60.     /* 9 */    "bar",
  61.     /*10 */    "cpio binary",
  62.     /*11 */    "cpio -c",
  63.     /*12 */    "cpio",
  64.     /*13 */    "cpio crc",
  65.     /*14 */    "cpio ascii",
  66.     /*15 */    "cpio ascii crc",
  67. };
  68.  
  69. extern    FILE    *tty;
  70. extern    long    hdrtype;
  71. extern    long    chdrtype;
  72. extern    int    version;
  73. extern    int    swapflg;
  74. extern    BOOL    debug;
  75. extern    BOOL    numeric;
  76. extern    BOOL    verbose;
  77. extern    BOOL    xflag;
  78. extern    BOOL    nflag;
  79. extern    BOOL    ignoreerr;
  80. extern    BOOL    signedcksum;
  81. extern    BOOL    nowarn;
  82. extern    BOOL    nullout;
  83. extern    BOOL    modebits;
  84.  
  85. extern    Ulong    tsize;
  86.  
  87. extern    char    *bigbuf;
  88. extern    int    bigsize;
  89.  
  90. LOCAL    Ulong    checksum    __PR((TCB * ptb));
  91. LOCAL    Ulong    bar_checksum    __PR((TCB * ptb));
  92. LOCAL    BOOL    isstmagic    __PR((char* s));
  93. LOCAL    BOOL    isxmagic    __PR((TCB *ptb));
  94. LOCAL    BOOL    ismagic        __PR((char* s));
  95. LOCAL    BOOL    isgnumagic    __PR((char* s));
  96. LOCAL    BOOL    strxneql    __PR((char* s1, char* s2, int l));
  97. LOCAL    BOOL    ustmagcheck    __PR((TCB * ptb));
  98. LOCAL    void    print_hdrtype    __PR((int type));
  99. LOCAL    int    get_hdrtype    __PR((TCB * ptb, BOOL isrecurse));
  100. EXPORT    int    get_tcb        __PR((TCB * ptb));
  101. EXPORT    void    put_tcb        __PR((TCB * ptb, FINFO * info));
  102. EXPORT    void    write_tcb    __PR((TCB * ptb, FINFO * info));
  103. EXPORT    void    put_volhdr    __PR((char* name));
  104. EXPORT    BOOL    get_volhdr    __PR((FINFO * info, char* vhname));
  105. EXPORT    void    info_to_tcb    __PR((FINFO * info, TCB * ptb));
  106. LOCAL    void    info_to_star    __PR((FINFO * info, TCB * ptb));
  107. LOCAL    void    info_to_ustar    __PR((FINFO * info, TCB * ptb));
  108. LOCAL    void    info_to_xstar    __PR((FINFO * info, TCB * ptb));
  109. LOCAL    void    info_to_gnutar    __PR((FINFO * info, TCB * ptb));
  110. EXPORT    int    tcb_to_info    __PR((TCB * ptb, FINFO * info));
  111. LOCAL    void    tar_to_info    __PR((TCB * ptb, FINFO * info));
  112. LOCAL    void    star_to_info    __PR((TCB * ptb, FINFO * info));
  113. LOCAL    void    ustar_to_info    __PR((TCB * ptb, FINFO * info));
  114. LOCAL    void    xstar_to_info    __PR((TCB * ptb, FINFO * info));
  115. LOCAL    void    gnutar_to_info    __PR((TCB * ptb, FINFO * info));
  116. LOCAL    void    cpiotcb_to_info    __PR((TCB * ptb, FINFO * info));
  117. LOCAL    int    ustoxt        __PR((int ustype));
  118. EXPORT    BOOL    ia_change    __PR((TCB * ptb, FINFO * info));
  119. LOCAL    BOOL    checkeof    __PR((TCB * ptb));
  120. LOCAL    BOOL    eofblock    __PR((TCB * ptb));
  121. EXPORT    void    astoo_cpio    __PR((char* s, Ulong * l, int cnt));
  122. EXPORT    void    astoo        __PR((char* s, Ulong * l));
  123. EXPORT    void    otoa        __PR((char* s, Ulong l, int fieldw));
  124. EXPORT    void    astob        __PR((char* s, Ulong * l, int fieldw));
  125. EXPORT    void    btoa        __PR((char* s, Ulong l, int fieldw));
  126.  
  127. /*
  128.  * XXX Hier sollte eine tar/bar universelle Checksummenfunktion sein!
  129.  */
  130. #define    CHECKS    sizeof(ptb->ustar_dbuf.t_chksum)
  131. /*
  132.  * We know, that sizeof(TCP) is 512 and therefore has no
  133.  * reminder when dividing by 8
  134.  *
  135.  * CHECKS is known to be 8 too, use loop unrolling.
  136.  */
  137. #define    DO8(a)    a;a;a;a;a;a;a;a;
  138.  
  139. LOCAL Ulong
  140. checksum(ptb)
  141.     register    TCB    *ptb;
  142. {
  143.     register    int    i;
  144.     register    Ulong    sum = 0;
  145.     register    Uchar    *us;
  146.  
  147.     if (signedcksum) {
  148.         register    char    *ss;
  149.  
  150.         ss = (char *)ptb;
  151.         for (i=sizeof(*ptb)/8; --i >= 0;) {
  152.             DO8(sum += *ss++);
  153.         }
  154.         if (sum == 0L)        /* Block containing 512 nul's */
  155.             return(sum);
  156.  
  157.         ss=(char *)ptb->ustar_dbuf.t_chksum;
  158.         DO8(sum -= *ss++);
  159.         sum += CHECKS*' ';
  160.     } else {
  161.         us = (Uchar *)ptb;
  162.         for (i=sizeof(*ptb)/8; --i >= 0;) {
  163.             DO8(sum += *us++);
  164.         }
  165.         if (sum == 0L)        /* Block containing 512 nul's */
  166.             return(sum);
  167.  
  168.         us=(Uchar *)ptb->ustar_dbuf.t_chksum;
  169.         DO8(sum -= *us++);
  170.         sum += CHECKS*' ';
  171.     }
  172.     return sum;
  173. }
  174. #undef    CHECKS
  175.  
  176. #define    CHECKS    sizeof(ptb->bar_dbuf.t_chksum)
  177.  
  178. LOCAL Ulong
  179. bar_checksum(ptb)
  180.     register    TCB    *ptb;
  181. {
  182.     register    int    i;
  183.     register    Ulong    sum = 0;
  184.     register    Uchar    *us;
  185.  
  186.     if (signedcksum) {
  187.         register    char    *ss;
  188.  
  189.         ss = (char *)ptb;
  190.         for (i=sizeof(*ptb); --i >= 0;)
  191.             sum += *ss++;
  192.         if (sum == 0L)        /* Block containing 512 nul's */
  193.             return(sum);
  194.  
  195.         for (i=CHECKS, ss=(char *)ptb->bar_dbuf.t_chksum; --i >= 0;)
  196.             sum -= *ss++;
  197.         sum += CHECKS*' ';
  198.     } else {
  199.         us = (Uchar *)ptb;
  200.         for (i=sizeof(*ptb); --i >= 0;)
  201.             sum += *us++;
  202.         if (sum == 0L)        /* Block containing 512 nul's */
  203.             return(sum);
  204.  
  205.         for (i=CHECKS, us=(Uchar *)ptb->bar_dbuf.t_chksum; --i >= 0;)
  206.             sum -= *us++;
  207.         sum += CHECKS*' ';
  208.     }
  209.     return sum;
  210. }
  211. #undef    CHECKS
  212.  
  213. LOCAL BOOL
  214. isstmagic(s)
  215.     char    *s;
  216. {
  217.     return (strxneql(s, stmagic, STMAGLEN));
  218. }
  219.  
  220. LOCAL BOOL
  221. isxmagic(ptb)
  222.     TCB    *ptb;
  223. {
  224.     /*
  225.      * prefix[130] is is granted to be '\0' with 'xstar'.
  226.      */
  227.     if (ptb->xstar_dbuf.t_prefix[130] != '\0')
  228.         return (FALSE);
  229.     /*
  230.      * If atime[0] or ctime[0] is not an octal number it cannot be 'xstar'.
  231.      */
  232.     if (ptb->xstar_dbuf.t_atime[0] < '0' ||
  233.         ptb->xstar_dbuf.t_atime[0] > '7')
  234.         return (FALSE);
  235.     if (ptb->xstar_dbuf.t_ctime[0] < '0' ||
  236.         ptb->xstar_dbuf.t_ctime[0] > '7')
  237.         return (FALSE);
  238.  
  239.     /*
  240.      * We may need to remove this in future.
  241.      */
  242.     if (ptb->xstar_dbuf.t_atime[11] != ' ' ||
  243.         ptb->xstar_dbuf.t_ctime[11] != ' ')
  244.         return (FALSE);
  245.  
  246.     return (TRUE);
  247. }
  248.  
  249. LOCAL BOOL
  250. ismagic(s)
  251.     char    *s;
  252. {
  253.     return (strxneql(s, magic, TMAGLEN));
  254. }
  255.  
  256. LOCAL BOOL
  257. isgnumagic(s)
  258.     char    *s;
  259. {
  260.     return (strxneql(s, gmagic, GMAGLEN));
  261. }
  262.  
  263. LOCAL BOOL
  264. strxneql(s1, s2, l)
  265.     register char    *s1;
  266.     register char    *s2;
  267.     register int    l;
  268. {
  269.     while (--l >= 0)
  270.         if (*s1++ != *s2++)
  271.             return (FALSE);
  272.     return (TRUE);
  273. }
  274.  
  275. LOCAL BOOL
  276. ustmagcheck(ptb)
  277.     TCB    *ptb;
  278. {
  279.     if (ismagic(ptb->xstar_dbuf.t_magic) &&
  280.                 strxneql(ptb->xstar_dbuf.t_version, "00", 2))
  281.         return (TRUE);
  282.     return (FALSE);
  283. }
  284.  
  285. LOCAL void
  286. print_hdrtype(type)
  287.     int    type;
  288. {
  289.     BOOL    isswapped = H_ISSWAPPED(type);
  290.  
  291.     if (H_TYPE(type) > H_MAX_ARCH)
  292.         type = H_UNDEF;
  293.     type = H_TYPE(type);
  294.  
  295.     error("%s%s archive.\n", isswapped?"swapped ":"", hdrtxt[type]);
  296. }
  297.  
  298. LOCAL int
  299. get_hdrtype(ptb, isrecurse)
  300.     TCB    *ptb;
  301.     BOOL    isrecurse;
  302. {
  303.     Ulong    check;
  304.     Ulong    ocheck;
  305.     int    ret = H_UNDEF;
  306.  
  307.     astoo(ptb->dbuf.t_chksum, &ocheck);
  308.     check = checksum(ptb);
  309.     if (ocheck != check)
  310.         goto nottar;
  311.  
  312.     if (isstmagic(ptb->dbuf.t_magic)) {    /* Check for 'tar\0' at end */
  313.         if (ustmagcheck(ptb))
  314.             ret = H_XSTAR;
  315.         else
  316.             ret = H_STAR;
  317.         if (debug) print_hdrtype(ret);
  318.         return (ret);
  319.     }
  320.     if (ustmagcheck(ptb)) {            /* 'ustar\000' POSIX magic */
  321.         if (isxmagic(ptb))
  322.             ret = H_XUSTAR;
  323.         else
  324.             ret = H_USTAR;
  325.         if (debug) print_hdrtype(ret);
  326.         return (ret);
  327.     }
  328.     if (isgnumagic(&ptb->dbuf.t_vers)) {    /* 'ustar  ' GNU magic */
  329.         ret = H_GNUTAR;
  330.         if (debug) print_hdrtype(ret);
  331.         return (ret);
  332.     }
  333.     if ((ptb->dbuf.t_mode[6] == ' ' && ptb->dbuf.t_mode[7] == '\0')) {
  334.         ret = H_OTAR;
  335.         if (debug) print_hdrtype(ret);
  336.         return (ret);
  337.     }
  338.     if (ptb->ustar_dbuf.t_typeflag == LF_VOLHDR ||
  339.                 ptb->ustar_dbuf.t_typeflag == LF_MULTIVOL) {
  340.         /*
  341.          * Gnu volume headers & multi volume headers
  342.          * are no real tar headers.
  343.          */
  344.         if (debug) error("gnutar buggy archive.\n");
  345.         ret = H_GNUTAR;
  346.         if (debug) print_hdrtype(ret);
  347.         return (ret);
  348.     }
  349.     /*
  350.      * The only thing we know here is:
  351.      * we found a header with a correct tar checksum.
  352.      */
  353.     ret = H_TAR;
  354.     if (debug) print_hdrtype(ret);
  355.     return (ret);
  356.  
  357. nottar:
  358.     if (ptb->bar_dbuf.bar_magic[0] == 'V') {
  359.         astoo(ptb->bar_dbuf.t_chksum, &ocheck);
  360.         check = bar_checksum(ptb);
  361.  
  362.         if (ocheck == check) {
  363.             ret = H_BAR;
  364.             if (debug) print_hdrtype(ret);
  365.             return (ret);
  366.         }
  367.     }
  368.     if (strxneql((char *)ptb, "070701", 6)) {
  369.         ret = H_CPIO_ASC;
  370.         if (debug) print_hdrtype(ret);
  371.         return (ret);
  372.     }
  373.     if (strxneql((char *)ptb, "070702", 6)) {
  374.         ret = H_CPIO_ACRC;
  375.         if (debug) print_hdrtype(ret);
  376.         return (ret);
  377.     }
  378.     if (strxneql((char *)ptb, "070707", 6)) {
  379.         ret = H_CPIO_CHR;
  380.         if (debug) print_hdrtype(ret);
  381.         return (ret);
  382.  
  383.     }
  384.     if (strxneql((char *)ptb, "\161\301", 2)) {
  385.         ret = H_CPIO_NBIN;
  386.         if (debug) print_hdrtype(ret);
  387.         return (ret);
  388.     }
  389.     if (strxneql((char *)ptb, "\161\302", 2)) {
  390.         ret = H_CPIO_CRC;
  391.         if (debug) print_hdrtype(ret);
  392.         return (ret);
  393.     }
  394.     if (strxneql((char *)ptb, "\161\307", 2)) {
  395.         ret = H_CPIO_BIN;
  396.         if (debug) print_hdrtype(ret);
  397.         return (ret);
  398.     }
  399.     if (debug) error("no tar archive??\n");
  400.  
  401.     if (!isrecurse) {
  402.         int    rret;
  403.         swabbytes((char *)ptb, TBLOCK);
  404.         rret = get_hdrtype(ptb, TRUE);
  405.         swabbytes((char *)ptb, TBLOCK);
  406.         rret = H_SWAPPED(rret);
  407.         if (debug) print_hdrtype(rret);
  408.         return (rret);
  409.     }
  410.  
  411.     if (debug) print_hdrtype(ret);
  412.     return (ret);
  413. }
  414.  
  415. EXPORT int
  416. get_tcb(ptb)
  417.     TCB    *ptb;
  418. {
  419.     Ulong    check;
  420.     Ulong    ocheck;
  421.     BOOL    eof;
  422.  
  423.     do {
  424.         /*
  425.          * bei der Option -i wird ein genulltes File
  426.          * fehlerhaft als EOF Block erkannt !
  427.          * wenn nicht t_magic gesetzt ist.
  428.          */
  429.         if (readblock((char *)ptb) == EOF) {
  430.             errmsgno(EX_BAD, "Hard EOF on input, first EOF block is missing.\n");
  431.             return (EOF);
  432.         }
  433.         /*
  434.          * First tar control block
  435.          */
  436.         if (swapflg < 0) {
  437.             BOOL    swapped;
  438.  
  439.             hdrtype = get_hdrtype(ptb, FALSE);
  440.             swapped = H_ISSWAPPED(hdrtype);
  441.             if (chdrtype != H_UNDEF &&
  442.                     swapped != H_ISSWAPPED(chdrtype)) {
  443.  
  444.                 swapped = H_ISSWAPPED(chdrtype);
  445.             }
  446.             if (swapped) {
  447.                 swapflg = 1;
  448.                 swabbytes((char *)ptb, TBLOCK);    /* copy of TCB*/
  449.                 swabbytes(bigbuf, bigsize);    /* io buffer */
  450.             } else {
  451.                 swapflg = 0;
  452.             }
  453.             /*
  454.              * wake up fifo (first block ist swapped)
  455.              */
  456.             buf_resume();
  457.             if (H_TYPE(hdrtype) == H_BAR) {
  458.                 comerrno(EX_BAD, "Can't handle bar archives (yet).\n");
  459.             }
  460.             if (H_TYPE(hdrtype) >= H_CPIO) {
  461. /* XXX JS Test */if (H_TYPE(hdrtype) == H_CPIO_CHR) {
  462. /* XXX JS Test */FINFO info;
  463. /* XXX JS Test */tcb_to_info(ptb, &info);
  464. /* XXX JS Test */}
  465.                 comerrno(EX_BAD, "Can't handle cpio archives (yet).\n");
  466.             }
  467.             if (H_TYPE(hdrtype) == H_UNDEF) {
  468.                 char    *p = (char *)ptb;
  469.  
  470.                 if (p[0] == '\037') {
  471.                     if ((p[1] == '\037') ||    /* Packed         */
  472.                         (p[1] == '\213') ||    /* Gzip compressed   */
  473.                         (p[1] == '\235') ||    /* LZW compressed    */
  474.                         (p[1] == '\236') ||    /* Freezed          */
  475.                         (p[1] == '\240'))    /* SCO LZH compressed*/
  476.                     comerrno(EX_BAD, "Archive is compressed, try to use the -z option.\n");
  477.                 }
  478.                 if (p[0] == 'B' && p[1] == 'Z' && p[2] == 'h')
  479.                     comerrno(EX_BAD, "Archive is bzip2 compressed, try to use the -bz option.\n");
  480.                 if (!ignoreerr) {
  481.                     comerrno(EX_BAD,
  482.                     "Unknown archive type (neither tar, nor bar/cpio).\n");
  483.                 }
  484.             }
  485.             if (chdrtype != H_UNDEF && chdrtype != hdrtype) {
  486.                 errmsgno(EX_BAD, "Found: ");
  487.                 print_hdrtype(hdrtype);
  488.                 errmsgno(EX_BAD, "Warning: extracting as ");
  489.                 print_hdrtype(chdrtype);
  490.                 hdrtype = chdrtype;
  491.             }
  492.             setprops(hdrtype);
  493.         }
  494.         if ((eof = ptb->dbuf.t_name[0] == '\0' && checkeof(ptb))) {
  495.             if (!ignoreerr)
  496.                 return (EOF);
  497.         }
  498.         /*
  499.          * XXX Hier mu▀ eine Universalchecksummenⁿberprⁿfung hin
  500.          */
  501.         astoo(ptb->dbuf.t_chksum, &ocheck);
  502.         check = checksum(ptb);
  503.         /*
  504.          * check == 0 : genullter Block.
  505.          */
  506.         if (check != 0 && ocheck == check) {
  507.             char    *tmagic = ptb->ustar_dbuf.t_magic;
  508.  
  509.             switch (H_TYPE(hdrtype)) {
  510.  
  511.             case H_XUSTAR:
  512.                 if (ismagic(tmagic) && isxmagic(ptb))
  513.                     return (0);
  514.             case H_XSTAR:
  515.                 if (ismagic(tmagic) &&
  516.                     isstmagic(ptb->xstar_dbuf.t_xmagic))
  517.                     return (0);
  518.                 break;
  519.             case H_USTAR:
  520.                 if (ismagic(tmagic))
  521.                     return (0);
  522.                 break;
  523.             case H_GNUTAR:
  524.                 if (isgnumagic(tmagic))
  525.                     return (0);
  526.                 break;
  527.             case H_STAR: 
  528.                 tmagic = ptb->star_dbuf.t_magic;
  529.                 if (ptb->dbuf.t_vers < STVERSION ||
  530.                     isstmagic(tmagic))
  531.                 return (0);
  532.                 break;
  533.             default:
  534.             case H_TAR:
  535.             case H_OTAR:
  536.                 return (0);
  537.             }
  538.             errmsgno(EX_BAD, "Wrong magic at: %d: '%.8s'.\n",
  539.                             tblocks(), tmagic);
  540.             /*
  541.              * Allow buggy gnu Volheaders & Multivolheaders to work
  542.              */
  543.             if (H_TYPE(hdrtype) == H_GNUTAR)
  544.                 return (0);
  545.  
  546.         } else if (eof) {
  547.             errmsgno(EX_BAD, "EOF Block at: %d ignored.\n",
  548.                             tblocks());
  549.         } else {
  550.             errmsgno(EX_BAD, "Checksum error at: %d: 0%lo should be 0%lo.\n",
  551.                             tblocks(),
  552.                             ocheck, check);
  553.         }
  554.     } while (ignoreerr);
  555.     prstats();
  556.     exit(EX_BAD);
  557.     /* NOTREACHED */
  558.     return (EOF);        /* Keep lint happy */
  559. }
  560.  
  561. EXPORT void
  562. put_tcb(ptb, info)
  563.     TCB    *ptb;
  564.     register FINFO    *info;
  565. {
  566.     TCB    tb;
  567.     int    x1 = 0;
  568.     int    x2 = 0;
  569.  
  570.     if (info->f_flags & (F_LONGNAME|F_LONGLINK))
  571.         x1++;
  572.  
  573. /*XXX start alter code und Test */
  574.     if (( (info->f_flags & F_ADDSLASH) ? 1:0 +
  575.         info->f_namelen > props.pr_maxsname &&
  576.         (ptb->dbuf.t_prefix[0] == '\0' || H_TYPE(hdrtype) == H_GNUTAR)) ||
  577.             info->f_lnamelen > props.pr_maxslname)
  578.         x2++;
  579.  
  580.     if (x1 != x2) {
  581. error("type: %ld name: %s x1 %d x2 %d namelen: %ld prefix: %s lnamelen: %ld\n",
  582. info->f_filetype, info->f_name, x1, x2,
  583. info->f_namelen, ptb->dbuf.t_prefix, info->f_lnamelen);
  584.  
  585.     }
  586. /*XXX ende alter code und Test */
  587.  
  588.     if (x1 || x2) {
  589.         if ((info->f_flags & F_TCB_BUF) != 0) {    /* TCB is on buffer */
  590.             movebytes(ptb, &tb, TBLOCK);
  591.             ptb = &tb;
  592.             info->f_flags &= ~F_TCB_BUF;
  593.         }
  594.         write_longnames(info);
  595.     }
  596.     write_tcb(ptb, info);
  597. }
  598.  
  599. EXPORT void
  600. write_tcb(ptb, info)
  601.     TCB    *ptb;
  602.     register FINFO    *info;
  603. {
  604.     if (tsize > 0) {
  605.         TCB    tb;
  606.         long    left;
  607.         Ulong    size = info->f_rsize;
  608.  
  609.         left = tsize - tblocks();
  610.  
  611.         if (is_link(info))
  612.             size = 0L;
  613.                         /* file + tcb + EOF */
  614.         if (left < (long)(tarblocks(size)+1+2)) {
  615.             if ((info->f_flags & F_TCB_BUF) != 0) {
  616.                 movebytes(ptb, &tb, TBLOCK);
  617.                 ptb = &tb;
  618.                 info->f_flags &= ~F_TCB_BUF;
  619.             }
  620.             nexttape();
  621.         }
  622.     }
  623.     if (!nullout) {                /* 17 (> 16) Bit !!! */
  624.         if (props.pr_fillc == '0')
  625.             otoa(ptb->dbuf.t_chksum, checksum(ptb) & 0x1FFFF, 7);
  626.         else
  627.             otoa(ptb->dbuf.t_chksum, checksum(ptb) & 0x1FFFF, 6);
  628.     }
  629.     if ((info->f_flags & F_TCB_BUF) != 0)    /* TCB is on buffer */
  630.         put_block();
  631.     else
  632.         writeblock((char *)ptb);
  633. }
  634.  
  635. EXPORT void
  636. put_volhdr(name)
  637.     char    *name;
  638. {
  639.     FINFO    finfo;
  640.     TCB    tb;
  641.     struct timeval tv;
  642.  
  643.     if (name == 0)
  644.         return;
  645.     if ((props.pr_flags & PR_VOLHDR) == 0)
  646.         return;
  647.  
  648.     gettimeofday(&tv, (struct timezone *)0);
  649.  
  650.     fillbytes((char *)&finfo, sizeof (FINFO), '\0');
  651.     fillbytes((char *)&tb, TBLOCK, '\0');
  652.     finfo.f_name = name;
  653.     finfo.f_namelen = strlen(name);
  654.     finfo.f_xftype = XT_VOLHDR;
  655.     finfo.f_mtime = tv.tv_sec;
  656.     finfo.f_tcb = &tb;
  657.  
  658.     if (!name_to_tcb(&finfo, &tb))    /* Name too long */
  659.         return;
  660.  
  661.     info_to_tcb(&finfo, &tb);
  662.     put_tcb(&tb, &finfo);
  663.     vprint(&finfo);
  664. }
  665.  
  666. EXPORT BOOL
  667. get_volhdr(info, vhname)
  668.     FINFO    *info;
  669.     char    *vhname;
  670. {
  671.     error("Volhdr: %s\n", info->f_name);
  672.  
  673.     if (vhname) {
  674.         return (streql(info->f_name, vhname));
  675.     } else { 
  676.         return (TRUE);
  677.     }
  678. }
  679.  
  680. EXPORT void
  681. info_to_tcb(info, ptb)
  682.     register FINFO    *info;
  683.     register TCB    *ptb;
  684. {
  685.     if (nullout)
  686.         return;
  687.  
  688.     if (props.pr_fillc == '0') {
  689.         if (modebits)
  690.             otoa(ptb->dbuf.t_mode, (info->f_mode|info->f_type) & 0xFFFF, 7);
  691.         else
  692.             otoa(ptb->dbuf.t_mode, info->f_mode & 0xFFFF, 7);
  693.         otoa(ptb->dbuf.t_uid, info->f_uid & 0xFFFF, 7);
  694.         otoa(ptb->dbuf.t_gid, info->f_gid & 0xFFFF, 7);
  695.     } else {
  696.         if (modebits)
  697.             otoa(ptb->dbuf.t_mode, (info->f_mode|info->f_type) & 0xFFFF, 6);
  698.         else
  699.             otoa(ptb->dbuf.t_mode, info->f_mode & 0xFFFF, 6);
  700.         otoa(ptb->dbuf.t_uid, info->f_uid & 0xFFFF, 6);
  701.         otoa(ptb->dbuf.t_gid, info->f_gid & 0xFFFF, 6);
  702.     }
  703.     otoa(ptb->dbuf.t_size, info->f_rsize, 11);
  704.     otoa(ptb->dbuf.t_mtime, (Ulong)info->f_mtime, 11);
  705.     ptb->dbuf.t_linkflag = XTTOUS(info->f_xftype);
  706.  
  707.     if (H_TYPE(hdrtype) == H_USTAR) {
  708.         info_to_ustar(info, ptb);
  709.     } else if (H_TYPE(hdrtype) == H_XSTAR) {
  710.         info_to_xstar(info, ptb);
  711.     } else if (H_TYPE(hdrtype) == H_XUSTAR) {
  712.         info_to_xstar(info, ptb);
  713.     } else if (H_TYPE(hdrtype) == H_GNUTAR) {
  714.         info_to_gnutar(info, ptb);
  715.     } else if (H_TYPE(hdrtype) == H_STAR) {
  716.         info_to_star(info, ptb);
  717.     }
  718. }
  719.  
  720. LOCAL void
  721. info_to_star(info, ptb)
  722.     register FINFO    *info;
  723.     register TCB    *ptb;
  724. {
  725.     ptb->dbuf.t_vers = STVERSION;
  726.     otoa(ptb->dbuf.t_filetype, info->f_filetype & 0xFFFF, 6);    /* XXX -> 7 ??? */
  727.     otoa(ptb->dbuf.t_type, info->f_type & 0xFFFF, 11);
  728.     otoa(ptb->dbuf.t_rdev, info->f_rdev, 11);
  729. #ifdef    DEV_MINOR_NONCONTIG
  730.     ptb->dbuf.t_devminorbits = '@';
  731. #else
  732.     ptb->dbuf.t_devminorbits = '@' + minorbits;
  733. #endif
  734.  
  735.     otoa(ptb->dbuf.t_atime, (Ulong)info->f_atime, 11);
  736.     otoa(ptb->dbuf.t_ctime, (Ulong)info->f_ctime, 11);
  737. /*    strcpy(ptb->dbuf.t_magic, stmagic);*/
  738.     ptb->dbuf.t_magic[0] = 't';
  739.     ptb->dbuf.t_magic[1] = 'a';
  740.     ptb->dbuf.t_magic[2] = 'r';
  741.     if (!numeric) {
  742.         nameuid(ptb->dbuf.t_uname, STUNMLEN, info->f_uid);
  743.         namegid(ptb->dbuf.t_gname, STGNMLEN, info->f_gid);
  744.         if (*ptb->dbuf.t_uname) {
  745.             info->f_uname = ptb->dbuf.t_uname;
  746.             info->f_umaxlen = STUNMLEN;
  747.         }
  748.         if (*ptb->dbuf.t_gname) {
  749.             info->f_gname = ptb->dbuf.t_gname;
  750.             info->f_gmaxlen = STGNMLEN;
  751.         }
  752.     }
  753.  
  754.     if (is_sparse(info))
  755.         otoa(ptb->xstar_in_dbuf.t_realsize, info->f_size, 11);
  756. }
  757.  
  758. LOCAL void
  759. info_to_ustar(info, ptb)
  760.     register FINFO    *info;
  761.     register TCB    *ptb;
  762. {
  763. /*XXX solaris hat illegalerweise mehr als 12 Bit in t_mode !!!
  764.  *    otoa(ptb->dbuf.t_mode, info->f_mode|info->f_type & 0xFFFF, 6);    XXX -> 7 ???
  765. */
  766. /*    strcpy(ptb->ustar_dbuf.t_magic, magic);*/
  767.     ptb->ustar_dbuf.t_magic[0] = 'u';
  768.     ptb->ustar_dbuf.t_magic[1] = 's';
  769.     ptb->ustar_dbuf.t_magic[2] = 't';
  770.     ptb->ustar_dbuf.t_magic[3] = 'a';
  771.     ptb->ustar_dbuf.t_magic[4] = 'r';
  772. /*    strncpy(ptb->ustar_dbuf.t_version, TVERSION, TVERSLEN);*/
  773.     /*
  774.      * strncpy is slow: use handcrafted replacement.
  775.      */
  776.     ptb->ustar_dbuf.t_version[0] = '0';
  777.     ptb->ustar_dbuf.t_version[1] = '0';
  778.  
  779.     if (!numeric) {
  780.         nameuid(ptb->ustar_dbuf.t_uname, TUNMLEN, info->f_uid);
  781.         namegid(ptb->ustar_dbuf.t_gname, TGNMLEN, info->f_gid);
  782.         if (*ptb->ustar_dbuf.t_uname) {
  783.             info->f_uname = ptb->ustar_dbuf.t_uname;
  784.             info->f_umaxlen = TUNMLEN;
  785.         }
  786.         if (*ptb->ustar_dbuf.t_gname) {
  787.             info->f_gname = ptb->ustar_dbuf.t_gname;
  788.             info->f_gmaxlen = TGNMLEN;
  789.         }
  790.     }
  791.     otoa(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 7);
  792. #if    DEV_MINOR_BITS > 21
  793.     if (info->f_rdevmin > 07777777) {
  794.         extern    BOOL    hpdev;
  795.  
  796.         if (!is_special(info)) {
  797.             /*
  798.              * Until we know how to deal with this, we reduce
  799.              * the number of files that get non POSIX headers.
  800.              */
  801.             info->f_rdevmin = 0;
  802.             goto doposix;
  803.         }
  804.         if ((info->f_rdevmin <= 077777777) && hpdev) {
  805.             char    c;
  806.  
  807.             /*
  808.              * Implement the method from HP-UX that allows 24 bit
  809.              * for the device minor number. Note that this method
  810.              * violates the POSIX specs.
  811.              */
  812.             c = ptb->ustar_dbuf.t_prefix[0];
  813.             otoa(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 8);
  814.             ptb->ustar_dbuf.t_prefix[0] = c;
  815.         } else {
  816.             btoa(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
  817.         }
  818.     } else
  819. #endif
  820.         {
  821. #if    DEV_MINOR_BITS > 21
  822. doposix:
  823. #endif
  824.         otoa(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 7);
  825.     }
  826. }
  827.  
  828. LOCAL void
  829. info_to_xstar(info, ptb)
  830.     register FINFO    *info;
  831.     register TCB    *ptb;
  832. {
  833.     info_to_ustar(info, ptb);
  834.     otoa(ptb->xstar_dbuf.t_atime, (Ulong)info->f_atime, 11);
  835.     otoa(ptb->xstar_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
  836.  
  837.     /*
  838.      * Help recognition in isxmagic(), make sure that prefix[130] is null.
  839.      */
  840.     ptb->xstar_dbuf.t_prefix[130] = '\0';
  841.  
  842.     if (H_TYPE(hdrtype) == H_XSTAR) {
  843. /*        strcpy(ptb->xstar_dbuf.t_xmagic, stmagic);*/
  844.         ptb->xstar_dbuf.t_xmagic[0] = 't';
  845.         ptb->xstar_dbuf.t_xmagic[1] = 'a';
  846.         ptb->xstar_dbuf.t_xmagic[2] = 'r';
  847.     }
  848.     if (is_sparse(info))
  849.         otoa(ptb->xstar_in_dbuf.t_realsize, info->f_size, 11);
  850. }
  851.  
  852. LOCAL void
  853. info_to_gnutar(info, ptb)
  854.     register FINFO    *info;
  855.     register TCB    *ptb;
  856. {
  857.     strcpy(ptb->gnu_dbuf.t_magic, gmagic);
  858.  
  859.     if (!numeric) {
  860.         nameuid(ptb->ustar_dbuf.t_uname, TUNMLEN, info->f_uid);
  861.         namegid(ptb->ustar_dbuf.t_gname, TGNMLEN, info->f_gid);
  862.         if (*ptb->ustar_dbuf.t_uname) {
  863.             info->f_uname = ptb->ustar_dbuf.t_uname;
  864.             info->f_umaxlen = TUNMLEN;
  865.         }
  866.         if (*ptb->ustar_dbuf.t_gname) {
  867.             info->f_gname = ptb->ustar_dbuf.t_gname;
  868.             info->f_gmaxlen = TGNMLEN;
  869.         }
  870.     }
  871.     if (info->f_xftype == XT_CHR || info->f_xftype == XT_BLK) {
  872.         otoa(ptb->ustar_dbuf.t_devmajor, info->f_rdevmaj, 6);    /* XXX -> 7 ??? */
  873.         otoa(ptb->ustar_dbuf.t_devminor, info->f_rdevmin, 6);    /* XXX -> 7 ??? */
  874.     }
  875.  
  876.     /*
  877.      * XXX GNU tar only fill this if doing a gnudump.
  878.      */
  879.     otoa(ptb->gnu_dbuf.t_atime, (Ulong)info->f_atime, 11);
  880.     otoa(ptb->gnu_dbuf.t_ctime, (Ulong)info->f_ctime, 11);
  881.  
  882.     if (is_sparse(info))
  883.         otoa(ptb->gnu_in_dbuf.t_realsize, info->f_size, 11);
  884. }
  885.  
  886. EXPORT int
  887. tcb_to_info(ptb, info)
  888.     register TCB    *ptb;
  889.     register FINFO    *info;
  890. {
  891.     int    ret = 0;
  892.     char    xname;
  893.     char    xlink;
  894.     Ulong    ul;
  895. static    BOOL    posixwarn = FALSE;
  896. static    BOOL    namewarn = FALSE;
  897.  
  898.     /*
  899.      * F_HAS_NAME is only used from list.c when the -listnew option is
  900.      * present. Keep f_lname and f_name, don't read LF_LONGLINK/LF_LONGNAME
  901.      * in this case.
  902.      */
  903.     if ((info->f_flags & F_HAS_NAME) == 0)
  904.         info->f_lname = ptb->dbuf.t_linkname;
  905.     info->f_uname = info->f_gname = NULL;
  906.     info->f_umaxlen = info->f_gmaxlen = 0L;
  907.     info->f_xftype = 0;
  908.     info->f_offset = 0;
  909.     info->f_flags &= F_HAS_NAME;
  910.  
  911. /* XXX JS Test */if (H_TYPE(hdrtype) >= H_CPIO) {
  912. /* XXX JS Test */cpiotcb_to_info(ptb, info);
  913. /* XXX JS Test */list_file(info);
  914. /* XXX JS Test */return (ret);
  915. /* XXX JS Test */}
  916.  
  917.     /*
  918.      * Handle very long names
  919.      */
  920.     if ((info->f_flags & F_HAS_NAME) == 0 &&
  921.                     props.pr_nflags & PR_LONG_NAMES) {
  922.         while (ptb->dbuf.t_linkflag == LF_LONGLINK ||
  923.                     ptb->dbuf.t_linkflag == LF_LONGNAME)
  924.             ret = tcb_to_longname(ptb, info);
  925.     }
  926.  
  927.     if (ptb->dbuf.t_name[NAMSIZ] == '\0') {
  928.         if (!nowarn && !namewarn) {
  929.             errmsgno(EX_BAD,
  930.             "Warning: Archive violates POSIX 1003.1 (100 char filename is null terminated).\n");
  931.             namewarn = TRUE;
  932.         }
  933.         ptb->dbuf.t_name[NAMSIZ] = ' ';
  934.     }
  935.     astoo(ptb->dbuf.t_mode, &info->f_mode);
  936.     if (info->f_mode & ~07777) {
  937.         if (!nowarn && !modebits && H_TYPE(hdrtype) == H_USTAR && !posixwarn) {
  938.             errmsgno(EX_BAD,
  939.             "Warning: Archive violates POSIX 1003.1 (too many bits in mode field).\n");
  940.             posixwarn = TRUE;
  941.         }
  942.         info->f_mode &= 07777;
  943.     }
  944.     astoo(ptb->dbuf.t_uid, &info->f_uid);
  945.     astoo(ptb->dbuf.t_gid, &info->f_gid);
  946.     astoo(ptb->dbuf.t_size, &info->f_size);
  947.     info->f_rsize = 0L;
  948. /*XXX    if (ptb->dbuf.t_linkflag < LNKTYPE)*/    /* Alte star Version!!! */
  949.     if (ptb->dbuf.t_linkflag != LNKTYPE &&
  950.                     ptb->dbuf.t_linkflag != DIRTYPE) {
  951.         /* XXX
  952.          * XXX Ist das die richtige Stelle um f_rsize zu setzen ??
  953.          */
  954.         info->f_rsize = info->f_size;
  955.     }
  956.     astoo(ptb->dbuf.t_mtime, &ul);
  957.     info->f_mtime = (time_t)ul;
  958.  
  959.     info->f_ansec = info->f_mnsec = info->f_cnsec = 0L;
  960.  
  961.  
  962.     switch (H_TYPE(hdrtype)) {
  963.  
  964.     default:
  965.     case H_TAR:
  966.     case H_OTAR:
  967.         tar_to_info(ptb, info);
  968.         break;
  969.     case H_USTAR:
  970.         ustar_to_info(ptb, info);
  971.         break;
  972.     case H_XSTAR:
  973.     case H_XUSTAR:
  974.         xstar_to_info(ptb, info);
  975.         break;
  976.     case H_GNUTAR:
  977.         gnutar_to_info(ptb, info);
  978.         break;
  979.     case H_STAR:
  980.         star_to_info(ptb, info);
  981.         break;
  982.     }
  983.  
  984.     /*
  985.      * Hack for list module (option -newest) ...
  986.      * Save and restore t_name[NAMSIZ] & t_linkname[NAMSIZ]
  987.      */
  988.     xname = ptb->dbuf.t_name[NAMSIZ];
  989.     ptb->dbuf.t_name[NAMSIZ] = '\0';    /* allow 100 chars in name */
  990.     xlink = ptb->dbuf.t_linkname[NAMSIZ];
  991.     ptb->dbuf.t_linkname[NAMSIZ] = '\0';/* allow 100 chars in linkname */
  992.  
  993.     /*
  994.      * Handle long name in posix split form now.
  995.      */
  996.     tcb_to_name(ptb, info);
  997.  
  998.     ptb->dbuf.t_name[NAMSIZ] = xname;    /* restore remembered value */
  999.     ptb->dbuf.t_linkname[NAMSIZ] = xlink;    /* restore remembered value */
  1000.  
  1001.     return (ret);
  1002. }
  1003.  
  1004. LOCAL void
  1005. tar_to_info(ptb, info)
  1006.     register TCB    *ptb;
  1007.     register FINFO    *info;
  1008. {
  1009.     register int    typeflag = ptb->ustar_dbuf.t_typeflag;
  1010.  
  1011.     if (ptb->dbuf.t_name[strlen(ptb->dbuf.t_name) - 1] == '/') {
  1012.         typeflag = DIRTYPE;
  1013.         info->f_filetype = F_DIR;
  1014.         info->f_rsize = 0L;    /* XXX hier?? siehe oben */
  1015.     } else if (typeflag == SYMTYPE) {
  1016.         info->f_filetype = F_SLINK;
  1017.     } else if (typeflag != DIRTYPE) {
  1018.         info->f_filetype = F_FILE;
  1019.     }
  1020.     info->f_xftype = USTOXT(typeflag);
  1021.     info->f_type = XTTOIF(info->f_xftype);
  1022.     info->f_rdevmaj = info->f_rdevmin = info->f_rdev = 0;
  1023.     info->f_ctime = info->f_atime = info->f_mtime;
  1024. }
  1025.  
  1026. LOCAL void
  1027. star_to_info(ptb, info)
  1028.     register TCB    *ptb;
  1029.     register FINFO    *info;
  1030. {
  1031.     Ulong    id;
  1032.     int    mbits;
  1033.  
  1034.     version = ptb->dbuf.t_vers;
  1035.     if (ptb->dbuf.t_vers < STVERSION) {
  1036.         tar_to_info(ptb, info);
  1037.         return;
  1038.     }
  1039.     astoo(ptb->dbuf.t_filetype, &info->f_filetype);
  1040.     astoo(ptb->dbuf.t_type, &info->f_type);
  1041.     /*
  1042.      * star Erweiterungen sind wieder ANSI kompatibel, d.h. linkflag
  1043.      * hΣlt den echten Dateityp (LONKLINK, LONGNAME, SPARSE ...)
  1044.      */
  1045.     if(ptb->dbuf.t_linkflag < '1')
  1046.         info->f_xftype = IFTOXT(info->f_type);
  1047.     else
  1048.         info->f_xftype = USTOXT(ptb->ustar_dbuf.t_typeflag);
  1049.  
  1050.     astoo(ptb->dbuf.t_rdev, &info->f_rdev);
  1051.     mbits = ptb->dbuf.t_devminorbits - '@';
  1052.     if (mbits == 0) {
  1053.         static    BOOL    dwarned = FALSE;
  1054.         if (!dwarned) {
  1055.             errmsgno(EX_BAD,
  1056. #ifdef    DEV_MINOR_NONCONTIG
  1057.             "Warning: Minor device numbers are non contiguous, devices may not be extracted correctly.\n");
  1058. #else
  1059.             "Warning: The archiving system used non contiguous minor numbers, cannot extract devices correctly.\n");
  1060. #endif
  1061.             dwarned = TRUE;
  1062.         }
  1063.         /*
  1064.          * Let us hope that both, the archiving and the extracting system
  1065.          * use the same major()/minor() mapping.
  1066.          */
  1067.         info->f_rdevmaj    = major(info->f_rdev);
  1068.         info->f_rdevmin    = minor(info->f_rdev);
  1069.     } else {
  1070.         /*
  1071.          * Convert from remote major()/minor() mapping to
  1072.          * local major()/minor() mapping.
  1073.          */
  1074.         if (mbits < 0)        /* Old star format */
  1075.             mbits = 8;
  1076.         info->f_rdevmaj    = _dev_major(mbits, info->f_rdev);
  1077.         info->f_rdevmin    = _dev_minor(mbits, info->f_rdev);
  1078.         info->f_rdev = makedev(info->f_rdevmaj, info->f_rdevmin);
  1079.     }
  1080.  
  1081.     astoo(ptb->dbuf.t_atime, &id);
  1082.     info->f_atime = (time_t)id;
  1083.     astoo(ptb->dbuf.t_ctime, &id);
  1084.     info->f_ctime = (time_t)id;
  1085.  
  1086.     if (!numeric && uidname(ptb->dbuf.t_uname, STUNMLEN, &id))
  1087.         info->f_uid = id;
  1088.     if (!numeric && gidname(ptb->dbuf.t_gname, STGNMLEN, &id))
  1089.         info->f_gid = id;
  1090.     if (*ptb->dbuf.t_uname) {
  1091.         info->f_uname = ptb->dbuf.t_uname;
  1092.         info->f_umaxlen = STUNMLEN;
  1093.     }
  1094.     if (*ptb->dbuf.t_gname) {
  1095.         info->f_gname = ptb->dbuf.t_gname;
  1096.         info->f_gmaxlen = STGNMLEN;
  1097.     }
  1098.  
  1099.     if (is_sparse(info))
  1100.         astoo(ptb->xstar_in_dbuf.t_realsize, &info->f_size);
  1101.     if (is_multivol(info))
  1102.         astoo(ptb->xstar_in_dbuf.t_offset, &info->f_offset);
  1103. }
  1104.  
  1105. LOCAL void
  1106. ustar_to_info(ptb, info)
  1107.     register TCB    *ptb;
  1108.     register FINFO    *info;
  1109. {
  1110.     Ulong    id;
  1111.     char    c;
  1112.  
  1113.     info->f_xftype = USTOXT(ptb->ustar_dbuf.t_typeflag);
  1114.     info->f_filetype = XTTOST(info->f_xftype);
  1115.     info->f_type = XTTOIF(info->f_xftype);
  1116.  
  1117.     if (!numeric && uidname(ptb->ustar_dbuf.t_uname, TUNMLEN, &id))
  1118.         info->f_uid = id;
  1119.     if (!numeric && gidname(ptb->ustar_dbuf.t_gname, TGNMLEN, &id))
  1120.         info->f_gid = id;
  1121.     if (*ptb->ustar_dbuf.t_uname) {
  1122.         info->f_uname = ptb->ustar_dbuf.t_uname;
  1123.         info->f_umaxlen = TUNMLEN;
  1124.     }
  1125.     if (*ptb->ustar_dbuf.t_gname) {
  1126.         info->f_gname = ptb->ustar_dbuf.t_gname;
  1127.         info->f_gmaxlen = TGNMLEN;
  1128.     }
  1129.  
  1130.     astoo(ptb->ustar_dbuf.t_devmajor, &info->f_rdevmaj);
  1131.     if (ptb->ustar_dbuf.t_devminor[0] & 0x80) {
  1132.         astob(ptb->ustar_dbuf.t_devminor, &info->f_rdevmin, 7);
  1133.     } else {
  1134.         /*
  1135.          * The 'tar' that comes with HP-UX writes illegal tar archives.
  1136.          * It includes 8 characters in the minor field and allows
  1137.          * to archive 24 bits for the minor device which are used by HP-UX.
  1138.          * As we like to be able to read these archives, we need to convert
  1139.          * the number carefully by temporarily writing a NULL to the next
  1140.          * character and restoring the right content afterwards.
  1141.          */
  1142.         c = ptb->ustar_dbuf.t_prefix[0];
  1143.         ptb->ustar_dbuf.t_prefix[0] = '\0';
  1144.         astoo(ptb->ustar_dbuf.t_devminor, &info->f_rdevmin);
  1145.         ptb->ustar_dbuf.t_prefix[0] = c;
  1146.     }
  1147.  
  1148.     info->f_rdev = makedev(info->f_rdevmaj, info->f_rdevmin);
  1149.  
  1150.     /*
  1151.      * ANSI Tar hat keine atime & ctime im Header!
  1152.      */
  1153.     info->f_ctime = info->f_atime = info->f_mtime;
  1154. }
  1155.  
  1156. LOCAL void
  1157. xstar_to_info(ptb, info)
  1158.     register TCB    *ptb;
  1159.     register FINFO    *info;
  1160. {
  1161.     Ulong    ul;
  1162.  
  1163.     ustar_to_info(ptb, info);
  1164.  
  1165.     astoo(ptb->xstar_dbuf.t_atime, &ul);
  1166.     info->f_atime = (time_t)ul;
  1167.     astoo(ptb->xstar_dbuf.t_ctime, &ul);
  1168.     info->f_ctime = (time_t)ul;
  1169.  
  1170.     if (is_sparse(info))
  1171.         astoo(ptb->xstar_in_dbuf.t_realsize, &info->f_size);
  1172.     if (is_multivol(info))
  1173.         astoo(ptb->xstar_in_dbuf.t_offset, &info->f_offset);
  1174. }
  1175.  
  1176. LOCAL void
  1177. gnutar_to_info(ptb, info)
  1178.     register TCB    *ptb;
  1179.     register FINFO    *info;
  1180. {
  1181.     Ulong    ul;
  1182.  
  1183.     ustar_to_info(ptb, info);
  1184.  
  1185.     astoo(ptb->gnu_dbuf.t_atime, &ul);
  1186.     info->f_atime = (time_t)ul;
  1187.  
  1188.     if (info->f_atime == 0 && ptb->gnu_dbuf.t_atime[0] == '\0')
  1189.         info->f_atime = info->f_mtime;
  1190.  
  1191.     astoo(ptb->gnu_dbuf.t_ctime, &ul);
  1192.     info->f_ctime = (time_t)ul;
  1193.  
  1194.     if (info->f_ctime == 0 && ptb->gnu_dbuf.t_ctime[0] == '\0')
  1195.         info->f_ctime = info->f_mtime;
  1196.  
  1197.     if (is_sparse(info))
  1198.         astoo(ptb->gnu_in_dbuf.t_realsize, &info->f_size);
  1199.     if (is_multivol(info))
  1200.         astoo(ptb->gnu_dbuf.t_offset, &info->f_offset);
  1201. }
  1202.  
  1203. /*
  1204.  * XXX vorerst nur zum Test!
  1205.  */
  1206. LOCAL void
  1207. cpiotcb_to_info(ptb, info)
  1208.     register TCB    *ptb;
  1209.     register FINFO    *info;
  1210. {
  1211.     Ulong    ul;
  1212.  
  1213.     astoo_cpio(&((char *)ptb)[6], &info->f_dev, 6);
  1214.     astoo_cpio(&((char *)ptb)[12], &info->f_ino, 6);
  1215. error("ino: %ld\n", info->f_ino);
  1216.     astoo_cpio(&((char *)ptb)[18], &info->f_mode, 6);
  1217. error("mode: %lo\n", info->f_mode);
  1218.     info->f_type = info->f_mode & S_IFMT;
  1219.     info->f_mode = info->f_mode & 07777;
  1220.     info->f_xftype = IFTOXT(info->f_type);
  1221.     info->f_filetype = XTTOST(info->f_xftype);
  1222.     astoo_cpio(&((char *)ptb)[24], &info->f_uid, 6);
  1223.     astoo_cpio(&((char *)ptb)[30], &info->f_gid, 6);
  1224.     astoo_cpio(&((char *)ptb)[36], &info->f_nlink, 6);
  1225.     astoo_cpio(&((char *)ptb)[42], &info->f_rdev, 6);
  1226.  
  1227.     astoo_cpio(&((char *)ptb)[48], &ul, 11);
  1228.     info->f_atime = (time_t)ul;
  1229.  
  1230.     astoo_cpio(&((char *)ptb)[59], &info->f_namelen, 6);
  1231.  
  1232.     astoo_cpio(&((char *)ptb)[65], &info->f_size, 11);
  1233. info->f_rsize = info->f_size;
  1234.     info->f_name = &((char *)ptb)[76];
  1235. }
  1236.  
  1237. LOCAL int
  1238. ustoxt(ustype)
  1239.     char    ustype;
  1240. {
  1241.     /*
  1242.      * Map ANSI types
  1243.      */
  1244.     if (ustype >= REGTYPE && ustype <= CONTTYPE)
  1245.         return _USTOXT(ustype);
  1246.  
  1247.     /*
  1248.      * Map Gnu tar & Star types ANSI: "local enhancements"
  1249.      */
  1250.     if ((props.pr_flags & (PR_LOCAL_STAR|PR_LOCAL_GNU)) &&
  1251.                     ustype >= 'A' && ustype <= 'Z')
  1252.         return _GTTOXT(ustype);
  1253.  
  1254.     /*
  1255.      * treat unknown types as regular files conforming to standard
  1256.      */
  1257.     return (XT_FILE);
  1258. }
  1259.  
  1260. EXPORT BOOL
  1261. ia_change(ptb, info)
  1262.     TCB    *ptb;
  1263.     FINFO    *info;
  1264. {
  1265.     char    buf[NAMSIZ+1];    /* XXX nur 100 chars ?? */
  1266.     char    ans;
  1267.     int    len;
  1268.  
  1269.     if (verbose)
  1270.         list_file(info);
  1271.     else
  1272.         vprint(info);
  1273.     if (nflag)
  1274.         return (FALSE);
  1275.     printf("get/put ? Y(es)/N(o)/C(hange name) :");flush();
  1276.     fgetline(tty, buf, 2);
  1277.     if ((ans = toupper(buf[0])) == 'Y')
  1278.         return (TRUE);
  1279.     else if (ans == 'C') {
  1280.         for(;;) {
  1281.             printf("Enter new name:");
  1282.             flush();
  1283.             if ((len = fgetline(tty, buf, sizeof buf)) == 0)
  1284.                 continue;
  1285.             if (len > sizeof(buf) - 1)
  1286.                 errmsgno(EX_BAD, "Name too long.\n");
  1287.             else
  1288.                 break;
  1289.         }
  1290.         strcpy(info->f_name, buf);    /* XXX nur 100 chars ?? */
  1291.         if (xflag && newer(info))
  1292.             return (FALSE);
  1293.         return (TRUE);
  1294.     }
  1295.     return (FALSE);
  1296. }
  1297.  
  1298. LOCAL BOOL
  1299. checkeof(ptb)
  1300.     TCB    *ptb;
  1301. {
  1302.     if (!eofblock(ptb))
  1303.         return (FALSE);
  1304.     if (debug)
  1305.         errmsgno(EX_BAD, "First  EOF Block OK\n");
  1306.     markeof();
  1307.  
  1308.     if (readblock((char *)ptb) == EOF) {
  1309.         errmsgno(EX_BAD, "Incorrect EOF, second EOF block is missing.\n");
  1310.         return (TRUE);
  1311.     }
  1312.     if (!eofblock(ptb)) {
  1313.         if (!nowarn)
  1314.             errmsgno(EX_BAD, "WARNING: Partial (single block) EOF detected.\n");
  1315.         return (FALSE);
  1316.     }
  1317.     if (debug)
  1318.         errmsgno(EX_BAD, "Second EOF Block OK\n");
  1319.     return (TRUE);
  1320. }
  1321.  
  1322. LOCAL BOOL
  1323. eofblock(ptb)
  1324.     TCB    *ptb;
  1325. {
  1326.     register short    i;
  1327.     register char    *s = (char *) ptb;
  1328.  
  1329.     if (props.pr_nflags & PR_DUMB_EOF)
  1330.         return (ptb->dbuf.t_name[0] == '\0');
  1331.  
  1332.     for (i=0; i < TBLOCK; i++)
  1333.         if (*s++ != '\0')
  1334.             return (FALSE);
  1335.     return (TRUE);
  1336. }
  1337.  
  1338. EXPORT void /*char **/
  1339. astoo_cpio(s,l, cnt)
  1340.     register char    *s;
  1341.          Ulong    *l;
  1342.     register int    cnt;
  1343. {
  1344.     register Ulong    ret = 0L;
  1345.     register char    c;
  1346.     register int    t;
  1347.     
  1348.     for(;cnt > 0; cnt--) {
  1349.         c = *s++;
  1350.         if(isoctal(c))
  1351.             t = c - '0';
  1352.         else
  1353.             break;
  1354.         ret *= 8;
  1355.         ret += t;
  1356.     }
  1357.     *l = ret;
  1358.     /*return(s);*/
  1359. }
  1360.  
  1361. EXPORT void /*char **/
  1362. astoo(s,l)
  1363.     register char    *s;
  1364.          Ulong    *l;
  1365. {
  1366.     register Ulong    ret = 0L;
  1367.     register char    c;
  1368.     register int    t;
  1369.     
  1370.     while(*s == ' ')
  1371.         s++;
  1372.  
  1373.     for(;;) {
  1374.         c = *s++;
  1375.         if(isoctal(c))
  1376.             t = c - '0';
  1377.         else
  1378.             break;
  1379.         ret *= 8;
  1380.         ret += t;
  1381.     }
  1382.     *l = ret;
  1383.     /*return(s);*/
  1384. }
  1385.  
  1386. EXPORT void
  1387. otoa(s, l, fieldw)
  1388.          char    *s;
  1389.     register Ulong    l;
  1390.     register int    fieldw;
  1391. {
  1392.     register char    *p    = &s[fieldw+1];
  1393.     register char    fill    = props.pr_fillc;
  1394.  
  1395.     /*
  1396.      * Bei 12 Byte Feldern wⁿrde hier das NΣchste Feld ⁿberschrieben, wenn
  1397.      * entgegen der normalen Reihenfolge geschrieben wird!
  1398.      * Da der TCB sowieso vorher genullt wird ist es aber kein Problem
  1399.      * das bei 8 Bytes Feldern notwendige Nullbyte wegzulassen.
  1400.      */
  1401. /*XXX    *p = '\0';*/
  1402.     /*
  1403.      * Das Zeichen nach einer Zahl.
  1404.      * XXX Soll hier besser ein NULL Byte bei POSIX Tar hin?
  1405.      * XXX Wuerde das Probleme mit einer automatischen Erkennung geben?
  1406.      */
  1407.     *--p = ' ';
  1408. /*???    *--p = '\0';*/
  1409.  
  1410.     do {
  1411.         *--p = (l%8) + '0';    /* Compiler optimiert */
  1412.         fieldw--;
  1413.     } while ((l /= 8) > 0);
  1414.  
  1415.     switch (fieldw) {
  1416.     case 11:    *--p = fill;
  1417.     case 10:    *--p = fill;
  1418.     case 9:        *--p = fill;
  1419.     case 8:        *--p = fill;
  1420.     case 7:        *--p = fill;
  1421.     case 6:        *--p = fill;
  1422.     case 5:        *--p = fill;
  1423.     case 4:        *--p = fill;
  1424.     case 3:        *--p = fill;
  1425.     case 2:        *--p = fill;
  1426.     case 1:        *--p = fill;
  1427.     }
  1428. }
  1429.  
  1430. EXPORT void /*char **/
  1431. astob(s, l, fieldw)
  1432.     register char    *s;
  1433.          Ulong    *l;
  1434.     register int    fieldw;
  1435. {
  1436.     register Ulong    ret = 0L;
  1437.     register Uchar    c;
  1438.     
  1439.     c = *s++ & 0x7F;
  1440.     ret = c * 256;
  1441.  
  1442.     while (--fieldw >= 0) {
  1443.         c = *s++;
  1444.         ret *= 256;
  1445.         ret += c;
  1446.     }
  1447.     *l = ret;
  1448.     /*return(s);*/
  1449. }
  1450.  
  1451. EXPORT void
  1452. btoa(s, l, fieldw)
  1453.          char    *s;
  1454.     register Ulong    l;
  1455.     register int    fieldw;
  1456. {
  1457.     register char    *p    = &s[fieldw+1];
  1458.  
  1459.     do {
  1460.         *--p = l%256;    /* Compiler optimiert */
  1461.         fieldw--;
  1462.     } while ((l /= 256) > 0);
  1463.  
  1464.     s[0] |= 0x80;
  1465. }
  1466.