home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / djsrc106.arj / DJTARX.C < prev    next >
C/C++ Source or Header  |  1992-04-18  |  6KB  |  281 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys/stat.h>
  4. #include <string.h>
  5. #include <errno.h>
  6.  
  7. #include "oread.h"
  8.  
  9. void Fatal(char *msg)
  10. {
  11.   fprintf(stderr, "Fatal! %s!\n", msg);
  12.   exit(1);
  13. }
  14.  
  15. /*------------------------------------------------------------------------*/
  16.  
  17. typedef struct CE {
  18.   struct CE *next;
  19.   char *from;
  20.   char *to;
  21. } CE;
  22.  
  23. #define HASHSIZE 2048
  24. #define HASHMASK 2047
  25. #define HASHBITS 11
  26. CE *htab[HASHSIZE];
  27.  
  28. unsigned long hash(unsigned char *cp)
  29. {
  30.   unsigned long rv = 0;
  31.   while (*cp)
  32.     rv += *cp++;
  33.   while (rv > HASHMASK)
  34.     rv = (rv & HASHMASK) + (rv >> HASHBITS);
  35.   return rv;
  36. }
  37.  
  38. void store_entry(char *from, char *to)
  39. {
  40.   unsigned long h = hash(from);
  41.   CE *ce = (CE *)malloc(sizeof(CE));
  42.   if (ce == 0)
  43.     Fatal("Out of memory");
  44.   ce->from = strdup(from);
  45.   ce->to = strdup(to);
  46.   ce->next = htab[h];
  47.   htab[h] = ce;
  48. }
  49.  
  50. char *get_entry(char *from)
  51. {
  52.   CE *ce;
  53.   for (ce = htab[hash(from)]; ce; ce=ce->next)
  54.   {
  55.     if (strcmp(ce->from, from) == 0)
  56.       return ce->to;
  57.   }
  58.   return from;
  59. }
  60.  
  61. void DoNameChanges(char *fname)
  62. {
  63.   FILE *f = fopen(fname, "r");
  64.   char from[100], to[100];
  65.   char line[250];
  66.   if (f == 0)
  67.   {
  68.     perror(fname);
  69.     exit(1);
  70.   }
  71.   while (1)
  72.   {
  73.     fgets(line, 250, f);
  74.     if (feof(f))
  75.       break;
  76.     to[0] = 0;
  77.     sscanf(line, "%s %s", from, to);
  78.     if (to[0])
  79.       store_entry(from, to);
  80.   }
  81.   fclose(f);
  82. }
  83.  
  84. /*------------------------------------------------------------------------*/
  85.  
  86. FILE *change_file;
  87.  
  88. main(int argc, char **argv)
  89. {
  90.   int i = 1;
  91.   if (argc < 2)
  92.   {
  93.     fprintf(stderr, "djtarx [-n changeFile] tarfile . . .\n");
  94.     exit(1);
  95.   }
  96.   while ((argc > i) && (argv[i][0] == '-'))
  97.   {
  98.     switch (argv[i][1])
  99.     {
  100.       case 'n':
  101.         DoNameChanges(argv[i+1]);
  102.         i++;
  103.         break;
  104.     }
  105.     i++;
  106.   }
  107.   for (; i < argc; i++)
  108.     tarread(argv[i]);
  109.   change_file = fopen("/tarchange.lst", "w");
  110.   dump_changes();
  111.   fclose(change_file);
  112. }
  113.  
  114. /*------------------------------------------------------------------------*/
  115.  
  116. typedef struct CHANGE {
  117.   struct CHANGE *next;
  118.   char *old;
  119.   char *new;
  120.   int isdir; /* 0=file, 1=dir, 2=skip */
  121. } CHANGE;
  122.  
  123. CHANGE *change_root = 0;
  124.  
  125. dump_changes()
  126. {
  127.   CHANGE *c;
  128.   for (c=change_root; c; c=c->next)
  129.     fprintf(change_file, "%s -> %s\n", c->old, c->new);
  130. }
  131.  
  132. int change(char *fname, char *problem, int isadir)
  133. {
  134.   CHANGE *ch;
  135.   char new[200];
  136.   char *pos;
  137.  
  138.   for (ch=change_root; ch; ch = ch->next)
  139.     if ((strncmp(fname, ch->old, strlen(ch->old)) == 0) && ch->isdir)
  140.     {
  141.       if (ch->isdir == 2)
  142.       {
  143.         printf("  [ skipping %s ]\n", fname);
  144.         return 0;
  145.       }
  146. /*      printf("  [ changing %s to ", fname); */
  147.       sprintf(new, "%s%s", ch->new, fname+strlen(ch->old));
  148.       strcpy(fname, new);
  149. /*      printf("%s ]\n", fname); */
  150.       return 1;
  151.     }
  152.   printf("  %s %s\n  new name : ", problem, fname);
  153.   gets(new);
  154.   if ((strcmp(new, "") == 0) && (isadir == 2))
  155.     return 0;
  156.   if (isadir) isadir=1;
  157.   ch = (CHANGE *)malloc(sizeof(CHANGE));
  158.   if (ch == 0)
  159.     Fatal("Out of memory");
  160.   ch->next = change_root;
  161.   change_root = ch;
  162.   ch->old = strdup(fname);
  163.   pos = strrchr(fname, '/');
  164.   if (pos && (strchr(new, '/') == 0))
  165.   {
  166.     ch->new = (char *)malloc(strlen(new) + (pos-fname) + 2);
  167.     if (ch->new == 0)
  168.       Fatal("Out of memory");
  169.     *pos = 0;
  170.     sprintf(ch->new, "%s/%s", fname, new);
  171.   }
  172.   else
  173.     ch->new = strdup(new);
  174.   ch->isdir = isadir;
  175.   strcpy(fname, ch->new);
  176.   if (new[0] == 0)
  177.   {
  178.     ch->isdir = 2;
  179.     return 0;
  180.   }
  181.   return 1;
  182. }
  183.  
  184. /*------------------------------------------------------------------------*/
  185.  
  186. typedef struct {
  187.   char name[100];
  188.   char operm[8];
  189.   char ouid[8];
  190.   char ogid[8];
  191.   char osize[11];
  192.   char otime[12];
  193.   char ocsum[8];
  194.   char flags[1];
  195.   char filler[356];
  196. } TARREC;
  197.  
  198. char buf[512];
  199.  
  200. tarread(char *fname)
  201. {
  202.   TARREC header;
  203.   int r;
  204.   void *f;
  205.   long perm, uid, gid, size, time, csum;
  206.   int dsize;
  207.   char *changed_name;
  208.   long posn=0;
  209.   f = oread_open(fname);
  210.  
  211.   while (1)
  212.   {
  213.     oread_read(f, &header);
  214.     if (header.name[0] == 0)
  215.       break;
  216.     sscanf(header.operm, "%lo", &perm);
  217.     sscanf(header.ouid, "%lo", &uid);
  218.     sscanf(header.ogid, "%lo", &gid);
  219.     sscanf(header.osize, "%lo", &size);
  220.     sscanf(header.otime, "%lo", &time);
  221.     changed_name = get_entry(header.name);
  222.     printf("%08lx %6lo %12ld %s", posn, perm, size, changed_name);
  223.     if (header.flags[1] == 0x32)
  224.       printf(" -> %s", header.filler);
  225.     printf("\n");
  226.     posn += 512 + (size+511) & ~511;
  227. /*    printf("%6lo %02x %12ld %s\n", perm, header.flags[0], size, changed_name); */
  228.     if (changed_name[strlen(changed_name)-1] == '/')
  229.     {
  230.       changed_name[strlen(changed_name)-1] = 0;
  231.       do {
  232.         printf("Making directory %s\n", changed_name);
  233.         r = mkdir(changed_name
  234. #ifdef GNUDOS
  235.     ,0
  236. #endif
  237.         );
  238.         if (r && (errno==EACCES))
  239.         {
  240.           change(changed_name, "Duplicate directory name", 2);
  241.           break;
  242.         }
  243.         if (r)
  244.           r = change(changed_name, "Unable to create directory", 1);
  245.       } while (r);
  246.     }
  247.     else
  248.     {
  249.     open_file:
  250.       r = open(changed_name, O_WRONLY|O_BINARY|O_CREAT|O_EXCL,
  251.         S_IWRITE|S_IREAD);
  252.       if (r < 0)
  253.         if (change(changed_name, "Cannot exclusively open file", 0))
  254.           goto open_file;
  255.         else
  256.         {
  257.           oread_skip(f, (size+511) & ~511);
  258.         }
  259.       else
  260.       {
  261.         while (size)
  262.         {
  263.           if (size < 512)
  264.             dsize = size;
  265.           else
  266.             dsize = 512;
  267.           oread_read(f, buf);
  268.           if (write(r, buf, dsize) < dsize)
  269.           {
  270.             printf("Out of disk space\n");
  271.             exit(1);
  272.           }
  273.           size -= dsize;
  274.         }
  275.         close(r);
  276.       }
  277.     }
  278.   }
  279.   oread_close(f);
  280. }
  281.