home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / g / gtak212.zip / 1.10 / ak_dir.c next >
C/C++ Source or Header  |  1992-10-29  |  6KB  |  226 lines

  1. /*****************************************************************************
  2.  * $Id: ak_dir.c,v 1.3 1992/10/29 10:26:35 ak Exp $
  3.  *****************************************************************************
  4.  * $Log: ak_dir.c,v $
  5.  * Revision 1.3  1992/10/29  10:26:35  ak
  6.  * *** empty log message ***
  7.  *
  8.  * Revision 1.2  1992/09/12  15:57:09  ak
  9.  * - Usenet patches for GNU TAR 1.10
  10.  * - Bugfixes and patches of Kai Uwe Rommel:
  11.  *         filename conversion for FAT
  12.  *         EMX 0.8e
  13.  *         -0..1 alias for a: b:
  14.  *         -2..7 alias for +++TAPE$x
  15.  *
  16.  * Revision 1.1  1992/09/02  20:07:32  ak
  17.  * Initial revision
  18.  *
  19.  *****************************************************************************/
  20.  
  21. static char *rcsid = "$Id: ak_dir.c,v 1.3 1992/10/29 10:26:35 ak Exp $";
  22.  
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include "tar.h"
  29. #include "port.h"
  30. #include "rmt.h"
  31.  
  32. extern union record *head;        /* Points to current tape header */
  33. extern struct stat hstat;        /* Stat struct corresponding */
  34. extern int head_standard;        /* Tape header is in ANSI format */
  35.  
  36. /*
  37.  * Random archive access.
  38.  */
  39. void
  40. seek_exec(do_something, name, vol, voloff, rec, skip)
  41.     void (*do_something)();
  42.     char *name;
  43.     int vol;
  44.     long voloff, rec, skip;
  45. {
  46.     long r;
  47.     static int error_flag;
  48.     extern int volno;
  49.     extern long baserec;
  50.     static long lastseek = - 1, lastend;
  51.  
  52.     if (f_multivol) {
  53.         if (vol != volno) {
  54.             /* next volume */
  55.             close_archive(1);
  56.             sprintf(ar_file + strlen(ar_file) - 3, "%03d", vol);
  57.             open_archive(1);
  58.             ar_last = ar_record = ar_block;
  59.             baserec = 0;
  60.             volno = vol;
  61.         }
  62.     }
  63.  
  64.     if (voloff + rec != lastseek) {
  65.         lastseek = voloff + rec;
  66.         msg("Seek to physical block %ld", voloff + rec);
  67.         r = rmtlseek(archive, (voloff + rec) * RECORDSIZE, 
  68.                  _isrmt(archive) ? 3 : 0);
  69.         ar_last = ar_record = ar_block;
  70.         baserec = rec;
  71.  
  72.         if (r < 0) {
  73.             if (vol)
  74.               msg_perror("Seek error on %s, volume %d record %ld",
  75.                      ar_file, vol, rec);
  76.             else
  77.               msg_perror("Seek error on %s, record %ld",
  78.                      ar_file, rec);
  79.             if (++error_flag > 10) {
  80.                 msg("Too many errors, quitting.");
  81.                 exit(EX_BADARCH);
  82.             }
  83.             return;
  84.         }
  85.     }
  86.     else
  87.           skip -= lastend;
  88.  
  89.     /* skip alignment blocks */
  90.     if (skip) {
  91.         long record_skip = skip % blocking;
  92.         long block_skip = skip - record_skip;
  93.               /* msg("Skip over %ld logical blocks", skip); */
  94.         if (block_skip) {
  95.             r = rmtlseek(archive, block_skip * RECORDSIZE, 1);
  96.             baserec += block_skip;
  97.         }
  98.         while (record_skip--)
  99.             userec(findrec());
  100.     }
  101.  
  102.     if (read_header() == 1) {
  103.         /* We should decode next field (mode) first... */
  104.         /* Ensure incoming names are null terminated. */
  105.         head->header.name[NAMSIZ-1] = '\0';
  106.  
  107.         /* Handle the archive member */
  108.         (*do_something)();
  109.         lastend = baserec - rec + ar_record - ar_block;
  110.     } else {
  111.         if (vol)
  112.             msg("File %s volume %d record %ld has invalid header, wrong map file?",
  113.                 name, vol, rec);
  114.         else
  115.             msg("File %s record %ld has invalid header, wrong map file?",
  116.                 name, rec);
  117.         if (++error_flag > 10) {
  118.             msg("Too many errors, quitting.");
  119.             exit(EX_BADARCH);
  120.         }
  121.     }
  122. }
  123.  
  124. /*
  125.  * Main loop for random access.
  126.  */
  127. void
  128. seek_and(do_something)
  129.     void (*do_something)();
  130. {
  131.     extern FILE *map_file;
  132.     struct name *nlp;
  133.     char    line[60 + FILENAME_MAX];
  134.     long    voloff, offset, skip;
  135.     char    *p;
  136.     int    len, volume;
  137. #if 0
  138.     struct Volmap {
  139.         long        base;    /* physical base record no */
  140.         short        ctrl;    /* no of inserted control records */
  141.         short        num;    /* volume no */
  142.         struct Volmap    *prev;    /* previous volume */
  143.     } *volmap, *q;
  144. #endif
  145.     name_gather();            /* Gather all the names */
  146.     open_archive(1);        /* Open for reading */
  147.  
  148.     volume = voloff = 0;
  149.     rewind(map_file);
  150.     while (fgets(line, 60 + FILENAME_MAX, map_file)) {
  151.         char *name = line + strlen(line);
  152.         char *key  = strtok(line, " \t");
  153.         char *arg  = key ? strtok(NULL, ": \t\r\n") : NULL;
  154.         char *mode = arg ? strtok(NULL, " \t") : NULL;
  155.         char *q;
  156.         offset = arg ? strtol(arg, &q, 0) : 0;
  157.         skip = (q && *q == '+') ? strtol(q+1, &q, 0) : 0;
  158.         if (strncmp(key, "vol", 3) == 0) {
  159.             /* base address of tape file */
  160.             voloff = offset;
  161.             continue;
  162.         }
  163.         if (key[0] == 'V') {
  164.             /* tape number */
  165.             volume = atoi(key+1);
  166.             continue;
  167.         }
  168.         if (strcmp(key, "blk") == 0) {
  169.             extern long tapeblock;
  170.             voloff = 0;
  171.             offset = offset * tapeblock / RECORDSIZE;
  172.         } else if (strncmp(key, "rec", 3) != 0)
  173.             continue;
  174.         if (mode[0] == 'M')
  175.             continue;
  176.  
  177.         /* get file name from record line -- skip "(..)" descr */
  178.         while (isspace(*(name-1)))
  179.             --name;
  180.         if (mode[0] == 'A' && *(name-1) == ')')
  181.             while (*--name != '(')
  182.                 ;
  183.         while (isspace(*(name-1)))
  184.             --name;
  185.         *name = '\0';
  186.         while (!isspace(*(name-1)))
  187.             --name;
  188.         len = strlen(name);
  189.  
  190.         /* look if name is mentioned in command line */
  191.         for (nlp = namelist; nlp; nlp = nlp->next) {
  192.             /* fast check for first character */
  193.             if (nlp->firstch && nlp->name[0] != name[0])
  194.                 continue;
  195.  
  196.             /* regular expression? */
  197.             if (nlp->regexp) {
  198.                 if (wildmat(name, nlp->name))
  199.                     goto match;
  200.                 continue;
  201.             }
  202.  
  203.             /* plain name */
  204.             if (nlp->length <= len
  205.              && (name[nlp->length] == '\0'
  206.               || name[nlp->length] == '/')
  207. #ifdef MSDOS
  208.              && strnicmp(name, nlp->name, nlp->length) == 0)
  209. #else
  210.              && strncmp(name, nlp->name, nlp->length) == 0)
  211. #endif
  212.                  goto match;
  213.             continue;
  214.  
  215.         match:    seek_exec(do_something, name, volume, voloff, offset, skip);
  216.             if (mode[0] != 'A')
  217.                 nlp->found = 1;
  218.         }
  219.     }
  220.  
  221.     close_archive(1);
  222.     names_notfound();        /* Print names not found */
  223. }
  224.  
  225.  
  226.