home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / APPEND.C next >
C/C++ Source or Header  |  1990-11-12  |  4KB  |  178 lines

  1. /* $Source: /u/mark/src/pax/RCS/append.c,v $
  2.  *
  3.  * $Revision: 2.0.0.5 $
  4.  *
  5.  * append.c - append to a tape archive.
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    Routines to allow appending of archives
  10.  *
  11.  * AUTHORS
  12.  *
  13.  *         Mark H. Colburn, Open Systems Architects, Inc. (mark@minnetech.mn.org)
  14.  *
  15.  * COPYRIGHT
  16.  *
  17.  *    Copyright (c) 1989 Mark H. Colburn.  All rights reserved.
  18.  *
  19.  *    Redistribution and use in source and binary forms are permitted
  20.  *    provided that the above copyright notice and this paragraph are
  21.  *    duplicated in all such forms and that any documentation,
  22.  *    advertising materials, and other materials related to such
  23.  *    distribution and use acknowledge that the software was developed
  24.  *    by Mark H. Colburn.
  25.  *
  26.  *    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  27.  *    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  28.  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  29.  *
  30.  * $Log:    append.c,v $
  31.  * Revision 2.0.0.5  89/10/30  19:51:53  mark
  32.  * patch1: Added some additional support for MS-DOS
  33.  *
  34.  * Revision 2.0.0.4  89/10/30  07:42:36  mark
  35.  * Added <sys/mtio.h> for MSDOS
  36.  *
  37.  * Revision 2.0.0.3  89/10/13  02:34:15  mark
  38.  * Beta Test Freeze
  39.  *
  40.  */
  41.  
  42. #ifndef lint
  43. static char        *ident = "$Id: append.c,v 2.0.0.5 89/10/30 19:51:53 mark Exp Locker: mark $";
  44. static char        *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  45. #endif /* ! lint */
  46.  
  47.  
  48. /* Headers */
  49.  
  50. #include "pax.h"
  51. #ifdef MTIOCTOP
  52. #include <sys/mtio.h>
  53. #endif
  54.  
  55.  
  56. #ifdef ___STDC__
  57.  
  58. static int        back_space(int n);
  59.  
  60. #else /* __STDC__ */
  61.  
  62. static int        back_space();
  63.  
  64. #endif /* __STDC__ */
  65.  
  66.  
  67. /* append_archive - main loop for appending to a tar archive
  68.  *
  69.  * DESCRIPTION
  70.  *
  71.  *    Append_archive reads an archive until the end of the archive is
  72.  *    reached once the archive is reached, the buffers are reset and the
  73.  *    create_archive function is called to handle the actual writing of
  74.  *    the appended archive data.  This is quite similar to the
  75.  *    read_archive function, however, it does not do all the processing.
  76.  */
  77.  
  78. #ifdef __STDC__
  79.  
  80. void
  81. append_archive(void)
  82.  
  83. #else
  84.  
  85. void
  86. append_archive()
  87.  
  88. #endif
  89. {
  90.     Stat                sb;
  91.     char                name[PATH_MAX + 1];
  92.     int                 blk;
  93.     OFFSET              btotal = 0;
  94.     OFFSET        skp;
  95.  
  96.     DBUG_ENTER("append_archive");
  97.     name[0] = '\0';
  98.     while (get_header(name, &sb) == 0) {
  99.     skp = (ar_format == TAR)
  100.         ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE))
  101.         : buf_skip((OFFSET) sb.sb_size);
  102.     if (buf_skip(skp) < 0) {
  103.         warn(name, "File data is corrupt");
  104.     }
  105.     /* the tar file header is written out in on BLOCKSIZE block */
  106.     btotal += skp + BLOCKSIZE;
  107.     }
  108.     /* we have now gotten to the end of the archive... */
  109.  
  110.     /* backspace to the end of the last archive */
  111.     if (ar_format == TAR) {
  112.         blk = (OFFSET) (bufend - bufstart - (btotal % blocksize)) / BLOCKSIZE;
  113.         blk = back_space(blk);
  114.         if (blk < 0) {
  115.             warn("can't backspace", "append archive may be no good");
  116.     }
  117.     }
  118.  
  119.     /* reset the buffer now that we have read the entire archive */
  120.     bufend = bufidx = bufstart;
  121.     create_archive();
  122.     DBUG_VOID_RETURN;
  123. }
  124.  
  125.  
  126. /*
  127.  * backspace - backspace a certain number of records on a file
  128.  *
  129.  * RETURNS
  130.  *
  131.  *    The number of bytes backed up, or -1 if an error occured.
  132.  *
  133.  * CAVEATS
  134.  *
  135.  *    A tar append without a warning message does not mean sucess, to be
  136.  *    sure, do a tar tv to see if your device can support backspacing.
  137.  */
  138.  
  139. #ifdef __STDC__
  140.  
  141. static int
  142. back_space(int n)
  143.  
  144. #else
  145.  
  146. static int
  147. back_space(n)
  148.     int                 n;
  149.  
  150. #endif
  151. {
  152.     OFFSET              pos;
  153.  
  154. #ifdef MTIOCTOP
  155.     struct mtop         mt;
  156.  
  157.     mt.mt_op = MTBSR;
  158.     mt.mt_count = n;
  159.     if (ioctl(archivefd, MTIOCTOP, &mt) < 0) {
  160.     if (errno == EIO) {    /* try again */
  161.         if (ioctl(archivefd, MTIOCTOP, &mt) < 0) {
  162.         warn(strerror(),
  163.              "probably can't backspace on device");
  164.         return (-1);
  165.         }
  166.     }
  167.     } else {
  168.     return (n);
  169.     }
  170. #endif /* MTIOCTOP */
  171.     pos = LSEEK(archivefd, (OFFSET) - n * BLOCKSIZE, 1);
  172.     if (pos == (OFFSET) -1) {
  173.     warn(strerror(), "probably can't backspace on device");
  174.     return (-1);
  175.     }
  176.     return (n);
  177. }
  178.