home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / gnu / utils / bug / 1550 < prev    next >
Encoding:
Text File  |  1992-09-10  |  11.1 KB  |  365 lines

  1. Newsgroups: gnu.utils.bug
  2. Path: sparky!uunet!cis.ohio-state.edu!mozart.informatik.rwth-aachen.de!norbert
  3. From: norbert@mozart.informatik.rwth-aachen.de (Norbert Kiesel)
  4. Subject: tar-1.11 bugs (with fixes)
  5. Message-ID: <9209101702.AA10675@rwthi3.informatik.rwth-aachen.de>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: GNUs Not Usenet
  8. Distribution: gnu
  9. Date: Thu, 10 Sep 1992 21:02:20 GMT
  10. Approved: bug-gnu-utils@prep.ai.mit.edu
  11. Lines: 352
  12.  
  13. Hello,
  14. there are bugs within tar-1.11 which make it quite useless: both the
  15. creation and the extracting of tar files fails (and dumps core)
  16. because tar isn't aware of the current file name. The variable
  17. current_file_name either points into a data block which is filled with
  18. the contents of the files (extraction) or points to nowhere (creation
  19. with verbose flag).
  20.  
  21. I've changed (i.e hacked :-) the program to avoid this errors (patch
  22. below). However, I think the maintainers of tar should have a close
  23. look upon the usage of the global variables and clean this code!
  24.  
  25.  
  26.         so long
  27.  
  28.             Norbert
  29.  
  30.  
  31. *******************************************************************************
  32. * Norbert Kiesel    Institut f. Informatik III     NN       NN    KK   KK *
  33. * RWTH Aachen           Ahornstr. 55                 NNN      NN    KK  KK  *
  34. * West Germany        D-5100 Aachen                NN N     NN    KK KK   *
  35. *                       +49 241 80-7266               NN  N    NN    KKKK    *
  36. *                                         NN   N   NN    KKKK    *
  37. * EUNET:    norbert@rwthi3.uucp                      NN    N  NN    KK KK   *
  38. * USENET:   ...!mcvax!unido!rwthi3!norbert           NN     N NN    KK  KK  *
  39. * INTERNET: norbert@rwthi3.informatik.rwth-aachen.de   NN      NNN    KK   KK *
  40. *******************************************************************************
  41.  
  42. --- list.c~    Tue Sep  8 22:22:38 1992
  43. +++ list.c    Thu Sep 10 18:47:49 1992
  44. @@ -529,6 +529,8 @@
  45.          fprintf(msg_file,"rec %10d: ",baserec + (ar_record - ar_block));
  46.      /* annofile(msg_file, (char *)NULL); */
  47.      
  48. +    current_file_name = head->header.arch_name;
  49. +    
  50.      if (f_verbose <= 1) {
  51.          /* Just the fax, mam. */
  52.          char *name;
  53. --- extract.c~    Tue Sep  8 22:09:11 1992
  54. +++ extract.c    Thu Sep 10 18:26:17 1992
  55. @@ -147,7 +147,9 @@
  56.  /*    int end_nulls; */
  57.      char **longp;
  58.      char *bp;
  59. +    char *name;
  60.      
  61. +    
  62.      saverec(&head);            /* Make sure it sticks around */
  63.      userec(head);            /* And go past it in the archive */
  64.      decode_header(head, &hstat, &head_standard, 1);    /* Snarf fields */
  65. @@ -183,11 +185,15 @@
  66.           }
  67.       }
  68.  
  69. -     switch (head->header.linkflag) {
  70. +    namelen = strlen(skipcrud + current_file_name);
  71. +    name = (char *) malloc((sizeof(char)) * namelen);
  72. +    strcpy(name, skipcrud+current_file_name);
  73. +    
  74. +    switch (head->header.linkflag) {
  75.  
  76. -     default:
  77. +    default:
  78.           msg("Unknown file type '%c' for %s, extracted as normal file",
  79. -             head->header.linkflag, skipcrud+current_file_name);
  80. +             head->header.linkflag, name);
  81.           /* FALL THRU */
  82.  
  83.       /* 
  84. @@ -266,8 +272,8 @@
  85.            * Appears to be a file.
  86.            * See if it's really a directory.
  87.            */
  88. -         namelen = strlen(skipcrud+current_file_name)-1;
  89. -         if (current_file_name[skipcrud+namelen] == '/')
  90. +         namelen = strlen(name)-1;
  91. +         if (name[namelen] == '/')
  92.               goto really_dir;
  93.  
  94.           /* FIXME, deal with protection issues */
  95. @@ -319,16 +325,14 @@
  96.               /*
  97.                * With 3-arg open(), we can do this up right.
  98.                */
  99. -             fd = open(skipcrud + current_file_name,
  100. -                   openflag, hstat.st_mode);
  101. +             fd = open(name, openflag, hstat.st_mode);
  102.   #endif
  103.           }
  104.  
  105.           if (fd < 0) {
  106. -             if (make_dirs(skipcrud + current_file_name))
  107. +             if (make_dirs(name))
  108.                   goto again_file;
  109. -             msg_perror("Could not create file %s",
  110. -                    skipcrud + current_file_name);
  111. +             msg_perror("Could not create file %s", name);
  112.               if (head->header.isextended)
  113.                   skip_extended_headers();
  114.               skip_file((long)hstat.st_size);
  115. @@ -337,8 +341,6 @@
  116.  
  117.       extract_file:
  118.           if (head->header.linkflag == LF_SPARSE) {
  119. -             char    *name;
  120. -             int    namelen;
  121.  
  122.               /*
  123.                * Kludge alert.  NAME is assigned to header.name
  124. @@ -348,9 +350,7 @@
  125.                * that happen to contain the filename will look
  126.                * REAL interesting unless we do this.
  127.                */
  128. -             namelen = strlen(skipcrud + current_file_name);
  129. -             name = (char *) malloc((sizeof(char)) * namelen);
  130. -             bcopy(skipcrud+current_file_name, name, namelen);
  131. +             namelen = strlen(name);
  132.               size = hstat.st_size;
  133.               extract_sparse_file(fd, &size, hstat.st_size, name);
  134.           }            
  135. @@ -410,10 +410,10 @@
  136.                */
  137.               if(check<0)
  138.                   msg_perror("couldn't write to file %s",
  139. -                        skipcrud + current_file_name);
  140. +                        name);
  141.               else
  142.                 msg("could only write %d of %d bytes to file %s",
  143. -                   written,check,skipcrud + current_file_name);
  144. +                   written,check,name);
  145.               skip_file((long)(size - written));
  146.               break;    /* Still do the close, mod time, chmod, etc */
  147.           }
  148. @@ -450,8 +450,7 @@
  149.           }*/
  150.           check = close(fd);
  151.           if (check < 0) {
  152. -             msg_perror("Error while closing %s",
  153. -                    skipcrud + current_file_name);
  154. +             msg_perror("Error while closing %s", name);
  155.           }
  156.  
  157.  
  158. @@ -464,11 +463,9 @@
  159.            * user; if running as root, we extract as the original owner.
  160.            */
  161.           if (we_are_root || f_do_chown) {
  162. -             if (chown(skipcrud + current_file_name,
  163. -                   hstat.st_uid, hstat.st_gid) < 0) {
  164. +             if (chown(name, hstat.st_uid, hstat.st_gid) < 0) {
  165.                 msg_perror("cannot chown file %s to uid %d gid %d",
  166. -                      skipcrud + current_file_name,
  167. -                      hstat.st_uid,hstat.st_gid);
  168. +                      name, hstat.st_uid,hstat.st_gid);
  169.               }
  170.           }
  171.  
  172. @@ -485,9 +482,8 @@
  173.                  acc_upd_times[0]=hstat.st_atime;
  174.              else acc_upd_times[0] = now;             /* Accessed now */
  175.              acc_upd_times[1] = hstat.st_mtime; /* Mod'd */
  176. -            if (utime(skipcrud + current_file_name,
  177. -                  acc_upd_times) < 0) {
  178. -              msg_perror("couldn't change access and modification times of %s",skipcrud + current_file_name);
  179. +            if (utime(name, acc_upd_times) < 0) {
  180. +              msg_perror("couldn't change access and modification times of %s",name);
  181.              }
  182.          }
  183.          /* We do the utime before the chmod because some versions of
  184. @@ -509,11 +505,9 @@
  185.           */
  186.          if ((!f_keep)
  187.              || (hstat.st_mode & (S_ISUID|S_ISGID|S_ISVTX))) {
  188. -          if (chmod(skipcrud + current_file_name,
  189. -                notumask & (int)hstat.st_mode) < 0) {
  190. +          if (chmod(name, notumask & (int)hstat.st_mode) < 0) {
  191.              msg_perror("cannot change mode of file %s to %ld",
  192. -                   skipcrud + current_file_name,
  193. -                   notumask & (int)hstat.st_mode);
  194. +                   name, notumask & (int)hstat.st_mode);
  195.              }
  196.          }
  197.  
  198. @@ -525,22 +519,21 @@
  199.      {
  200.          struct stat st1,st2;
  201.  
  202. -        check = link (current_link_name, skipcrud + current_file_name);
  203. +        check = link (current_link_name, name);
  204.  
  205.          if (check == 0)
  206.              break;
  207. -        if (make_dirs(skipcrud + current_file_name))
  208. +        if (make_dirs(name))
  209.              goto again_link;
  210.          if(f_gnudump && errno==EEXIST)
  211.              break;
  212.          if(stat(current_link_name, &st1) == 0
  213. -           && stat(current_file_name + skipcrud, &st2)==0
  214. +           && stat(name, &st2)==0
  215.             && st1.st_dev==st2.st_dev
  216.             && st1.st_ino==st2.st_ino)
  217.              break;
  218.          msg_perror("Could not link %s to %s",
  219. -               skipcrud + current_file_name,
  220. -               current_link_name);
  221. +               name, current_link_name);
  222.      }
  223.          break;
  224.  
  225. @@ -547,12 +540,11 @@
  226.  #ifdef S_ISLNK
  227.      case LF_SYMLINK:
  228.      again_symlink:
  229. -         check = symlink(current_link_name,
  230. -                 skipcrud + current_file_name);
  231. +         check = symlink(current_link_name, name);
  232.          /* FIXME, don't worry uid, gid, etc... */
  233.          if (check == 0)
  234.              break;
  235. -        if (make_dirs(current_file_name + skipcrud))
  236. +        if (make_dirs(name))
  237.              goto again_symlink;
  238.          msg_perror("Could not create symlink to %s",
  239.                 current_link_name);
  240. @@ -571,13 +563,11 @@
  241.  #endif
  242.  #if defined(S_IFCHR) || defined(S_IFBLK)
  243.      make_node:
  244. -        check = mknod(current_file_name + skipcrud,
  245. -                  (int) hstat.st_mode, (int) hstat.st_rdev);
  246. +        check = mknod(name, (int) hstat.st_mode, (int) hstat.st_rdev);
  247.          if (check != 0) {
  248. -            if (make_dirs(skipcrud + current_file_name))
  249. +            if (make_dirs(name))
  250.                  goto make_node;
  251. -            msg_perror("Could not make %s",
  252. -                   current_file_name + skipcrud);
  253. +            msg_perror("Could not make %s", name);
  254.              break;
  255.          };
  256.          goto set_filestat;
  257. @@ -587,13 +577,11 @@
  258.      /* If local system doesn't support FIFOs, use default case */
  259.      case LF_FIFO:
  260.      make_fifo:
  261. -        check = mkfifo(current_file_name + skipcrud,
  262. -                   (int) hstat.st_mode);
  263. +        check = mkfifo(name, (int) hstat.st_mode);
  264.          if (check != 0) {
  265. -          if (make_dirs(current_file_name + skipcrud))
  266. +          if (make_dirs(name))
  267.              goto make_fifo;
  268. -          msg_perror("Could not make %s",
  269. -                 skipcrud + current_file_name);
  270. +          msg_perror("Could not make %s", name);
  271.            break;
  272.          };
  273.           goto set_filestat;
  274. @@ -601,12 +589,11 @@
  275.  
  276.      case LF_DIR:
  277.      case LF_DUMPDIR:
  278. -         namelen = strlen(current_file_name) + skipcrud - 1;
  279. +         namelen = strlen(name) - 1;
  280.      really_dir:
  281.          /* Check for trailing /, and zap as many as we find. */
  282. -        while (namelen
  283. -               && current_file_name[skipcrud+namelen] == '/')
  284. -          current_file_name[skipcrud+namelen--] = '\0';
  285. +        while (namelen && name[namelen] == '/')
  286. +          name[namelen--] = '\0';
  287.          if(f_gnudump) {        /* Read the entry and delete files
  288.                         that aren't listed in the archive */
  289.              gnu_restore(skipcrud);
  290. @@ -616,23 +603,22 @@
  291.  
  292.      
  293.      again_dir:
  294. -        check = mkdir(skipcrud+current_file_name,
  295. +        check = mkdir(name,
  296.                    (we_are_root ? 0 : 0300) | (int)hstat.st_mode);
  297.          if (check != 0) {
  298.              struct stat st1;
  299.  
  300. -            if (make_dirs(skipcrud+current_file_name))
  301. +            if (make_dirs(name))
  302.                  goto again_dir;
  303.              /* If we're trying to create '.', let it be. */
  304. -            if (current_file_name[skipcrud+namelen] == '.' && 
  305. -                (namelen==0 ||
  306. -                 current_file_name[skipcrud+namelen-1]=='/'))
  307. +            if (name[namelen] == '.' && 
  308. +                (namelen==0 || name[namelen-1]=='/'))
  309.                  goto check_perms;
  310.              if(   errno==EEXIST
  311. -                && stat(skipcrud+current_file_name,&st1)==0
  312. +                && stat(name,&st1)==0
  313.                  && (S_ISDIR(st1.st_mode)))
  314.                  break;
  315. -            msg_perror("Could not create directory %s",skipcrud+current_file_name);
  316. +            msg_perror("Could not create directory %s",name);
  317.              break;
  318.          }
  319.          
  320. @@ -640,14 +626,14 @@
  321.          if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode)) {
  322.              hstat.st_mode |= 0300;
  323.              msg("Added write and execute permission to directory %s",
  324. -              skipcrud+current_file_name);
  325. +              name);
  326.          }
  327.  
  328.          if (f_modified)
  329.            goto set_filestat;
  330.          tmp = (struct saved_dir_info *) malloc (sizeof (struct saved_dir_info));
  331. -        tmp->path = malloc (strlen (skipcrud + current_file_name) + 1);
  332. -        strcpy (tmp->path, skipcrud + current_file_name);
  333. +        tmp->path = malloc (strlen (name) + 1);
  334. +        strcpy (tmp->path, name);
  335.          tmp->mode = hstat.st_mode;
  336.          tmp->atime = hstat.st_atime;
  337.          tmp->mtime = hstat.st_mtime;
  338. @@ -655,7 +641,7 @@
  339.          saved_dir_info_head = tmp;
  340.      case LF_VOLHDR:
  341.          if(f_verbose) {
  342. -            printf("Reading %s\n", current_file_name);
  343. +            printf("Reading %s\n", name);
  344.          }
  345.          break;
  346.  
  347. @@ -664,7 +650,7 @@
  348.          break;
  349.  
  350.      case LF_MULTIVOL:
  351. -        msg("Can't extract '%s'--file is continued from another volume\n",current_file_name);
  352. +        msg("Can't extract '%s'--file is continued from another volume\n",name);
  353.          skip_file((long)hstat.st_size);
  354.          break;
  355.  
  356. @@ -677,6 +663,7 @@
  357.      
  358.      /* We don't need to save it any longer. */
  359.      saverec((union record **) 0);    /* Unsave it */
  360. +    free(name);
  361.  }
  362.  
  363.  /*
  364.  
  365.