/[tar]/tar/src/create.c
ViewVC logotype

Diff of /tar/src/create.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.65 by gray, Sat Oct 4 18:14:32 2003 UTC revision 1.66 by gray, Thu Nov 13 22:27:09 2003 UTC
# Line 353  write_eot (void) Line 353  write_eot (void)
353    set_next_block_after (pointer);    set_next_block_after (pointer);
354  }  }
355    
356  /* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block.  */  /* Write a "private" header */
357    static union block *
358    start_private_header (const char *name, size_t size)
359    {
360      time_t t;
361      union block *header = find_next_block ();
362      
363      memset (header->buffer, 0, sizeof (union block));
364    
365      strncpy (header->header.name, name, NAME_FIELD_SIZE);
366      header->header.name[NAME_FIELD_SIZE - 1] = '\0';
367      OFF_TO_CHARS (size, header->header.size);
368    
369      time (&t);
370      TIME_TO_CHARS (t, header->header.mtime);
371      MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
372      UID_TO_CHARS (getuid (), header->header.uid);
373      GID_TO_CHARS (getgid (), header->header.gid);
374      MAJOR_TO_CHARS (0, header->header.devmajor);
375      MAJOR_TO_CHARS (0, header->header.devminor);
376      strncpy (header->header.magic, TMAGIC, TMAGLEN);
377      strncpy (header->header.version, TVERSION, TVERSLEN);
378      return header;
379    }
380    
381  /* FIXME: Cross recursion between start_header and write_long!  */  /* Create a new header and store there at most NAME_FIELD_SIZE bytes of
382       the file name */
383    
384  static union block *start_header (const char *, struct tar_stat_info *);  static union block *
385    write_short_name (struct tar_stat_info *st)
386    {
387      union block *header = find_next_block ();
388      memset (header->buffer, 0, sizeof (union block));
389      
390      strncpy (header->header.name, st->file_name, NAME_FIELD_SIZE);
391      header->header.name[NAME_FIELD_SIZE - 1] = '\0';
392      return header;
393    }
394    
395    /* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block.  */
396  static void  static void
397  write_long (const char *p, char type)  write_gnu_long_link (const char *p, char type)
398  {  {
399    size_t size = strlen (p) + 1;    size_t size = strlen (p) + 1;
400    size_t bufsize;    size_t bufsize;
401    union block *header;    union block *header;
   struct tar_stat_info foo;  
   
   memset (&foo, 0, sizeof foo);  
   foo.stat.st_size = size;  
402    
403    header = start_header ("././@LongLink", &foo);    header = start_private_header ("././@LongLink", size);
404    header->header.typeflag = type;    header->header.typeflag = type;
405    finish_header (header, -1);    finish_header (header, -1);
406    
# Line 392  write_long (const char *p, char type) Line 422  write_long (const char *p, char type)
422    set_next_block_after (header + (size - 1) / BLOCKSIZE);    set_next_block_after (header + (size - 1) / BLOCKSIZE);
423  }  }
424    
425    static size_t
426    split_long_name (const char *name, size_t length)
427    {
428      size_t i;
429    
430      if (length > PREFIX_FIELD_SIZE)
431        length = PREFIX_FIELD_SIZE+2;
432      for (i = length - 1; i > 0; i--)
433        if (ISSLASH (name[i]))
434          break;
435      return i;
436    }
437    
438    static union block *
439    write_ustar_long_name (const char *name)
440    {
441      size_t length = strlen (name);
442      size_t i;
443      union block *header;
444    
445      if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
446        {
447          WARN ((0, 0, _("%s: file name is too long (max %d); not dumped"),
448                 quotearg_colon (name),
449                 PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
450          return NULL;
451        }
452      
453      i = split_long_name (name, length);
454      if (i == 0)
455        {
456          WARN ((0, 0,
457                 _("%s: file name is too long (cannot be split); not dumped"),
458                 quotearg_colon (name),
459                 PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
460          return NULL;
461        }
462    
463      header = find_next_block ();
464      memset (header->buffer, 0, sizeof (header->buffer));
465      memcpy (header->header.prefix, name, i);
466      memcpy (header->header.name, name + i + 1, length - i);
467      
468      return header;
469    }
470    
471  /* Write a long link name, depending on the current archive format */  /* Write a long link name, depending on the current archive format */
472  static void  static void
473  write_long_link (struct tar_stat_info *st)  write_long_link (struct tar_stat_info *st)
474  {  {
475    if (archive_format == POSIX_FORMAT)    switch (archive_format)
476      xheader_store ("linkpath", st);      {
477    else      case POSIX_FORMAT:
478      write_long (st->link_name, GNUTYPE_LONGNAME);        xheader_store ("linkpath", st);
479          break;
480    
481        case V7_FORMAT:                     /* old V7 tar format */
482        case USTAR_FORMAT:
483        case STAR_FORMAT:
484          WARN ((0, 0,
485                 _("%s: link name is too long; not dumped"),
486                 quotearg_colon (st->link_name)));
487                break;
488          
489        case OLDGNU_FORMAT:
490        case GNU_FORMAT:
491          write_gnu_long_link (st->link_name, GNUTYPE_LONGLINK);
492          break;
493    
494        default:
495          abort(); /*FIXME*/
496        }
497  }  }
498    
499  /* NOTE: Cross recursion between start_header and write_extended  */  static union block *
500    write_long_name (struct tar_stat_info *st)
501    {
502      switch (archive_format)
503        {
504        case POSIX_FORMAT:
505          xheader_store ("path", st);
506          break;
507    
508        case V7_FORMAT:                  
509        case USTAR_FORMAT:
510        case STAR_FORMAT:
511          return write_ustar_long_name (st->file_name);
512          
513        case OLDGNU_FORMAT:
514        case GNU_FORMAT:
515          write_gnu_long_link (st->file_name, GNUTYPE_LONGNAME);
516          break;
517    
518        default:
519          abort(); /*FIXME*/
520        }
521      return write_short_name (st);
522    }
523    
524  static union block *  static union block *
525  write_extended (union block *old_header, char type)  write_extended (union block *old_header, char type)
# Line 413  write_extended (union block *old_header, Line 530  write_extended (union block *old_header,
530    char *p;    char *p;
531    
532    if (extended_header.buffer || extended_header.stk == NULL)    if (extended_header.buffer || extended_header.stk == NULL)
533      return old_header; /* Prevent recursion */      return old_header;
534        
535    xheader_finish (&extended_header);    xheader_finish (&extended_header);
536    size = extended_header.size;    size = extended_header.size;
   memset (&foo, 0, sizeof foo);  
   foo.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;  
   time (&foo.stat.st_ctime);  
   foo.stat.st_atime = foo.stat.st_ctime;  
   foo.stat.st_mtime = foo.stat.st_ctime;  
   foo.stat.st_size = size;  
537    
538    memcpy (hp.buffer, old_header, sizeof (hp));    memcpy (hp.buffer, old_header, sizeof (hp));
539        
540    header = start_header ("././@PaxHeader", &foo);    header = start_private_header ("././@PaxHeader", size);
541    header->header.typeflag = type;    header->header.typeflag = type;
542    
543    finish_header (header, -1);    finish_header (header, -1);
# Line 449  write_extended (union block *old_header, Line 560  write_extended (union block *old_header,
560        set_next_block_after (header);        set_next_block_after (header);
561      }      }
562    while (size > 0);    while (size > 0);
563      
564    xheader_destroy (&extended_header);    xheader_destroy (&extended_header);
565    header = find_next_block ();    header = find_next_block ();
566    memcpy (header, &hp.buffer, sizeof (hp.buffer));    memcpy (header, &hp.buffer, sizeof (hp.buffer));
567    return header;    return header;
568  }  }
569    
570    static union block *
571    write_header_name (struct tar_stat_info *st)
572    {
573      if (NAME_FIELD_SIZE <= strlen (st->file_name))
574        return write_long_name (st);
575      else
576        return write_short_name (st);
577    }
578    
579    
580  /* Header handling.  */  /* Header handling.  */
581    
# Line 468  start_header (const char *name, struct t Line 588  start_header (const char *name, struct t
588    union block *header;    union block *header;
589    
590    name = safer_name_suffix (name, 0);    name = safer_name_suffix (name, 0);
591      if (name[0] == '.' && name[1] == 0) /*FIXME!!!*/
592        return NULL;
593    assign_string (&st->file_name, name);    assign_string (&st->file_name, name);
594      
595    if (sizeof header->header.name <= strlen (name))    header = write_header_name (st);
596      {    if (!header)
597        if (archive_format == POSIX_FORMAT)      return NULL;
         xheader_store ("path", st);  
       else  
         write_long (name, GNUTYPE_LONGNAME);  
     }  
     
   header = find_next_block ();  
   memset (header->buffer, 0, sizeof (union block));  
598    
599    assign_string (&current_stat_info.file_name, name);    assign_string (&current_stat_info.file_name, name);
600    
   strncpy (header->header.name, name, NAME_FIELD_SIZE);  
   header->header.name[NAME_FIELD_SIZE - 1] = '\0';  
     
601    /* Override some stat fields, if requested to do so.  */    /* Override some stat fields, if requested to do so.  */
602    
603    if (owner_option != (uid_t) -1)    if (owner_option != (uid_t) -1)
# Line 519  start_header (const char *name, struct t Line 631  start_header (const char *name, struct t
631       above, thus making GNU tar both a universal donor and a universal       above, thus making GNU tar both a universal donor and a universal
632       acceptor for Paul's test.  */       acceptor for Paul's test.  */
633    
634    if (archive_format == V7_FORMAT)    if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT)
635      MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);      MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);
636    else    else
637      MODE_TO_CHARS (st->stat.st_mode, header->header.mode);      MODE_TO_CHARS (st->stat.st_mode, header->header.mode);
# Line 589  start_header (const char *name, struct t Line 701  start_header (const char *name, struct t
701        break;        break;
702    
703      case POSIX_FORMAT:      case POSIX_FORMAT:
704      case GNU_FORMAT:      case USTAR_FORMAT:
705        case GNU_FORMAT:   /*FIXME?*/
706        strncpy (header->header.magic, TMAGIC, TMAGLEN);        strncpy (header->header.magic, TMAGIC, TMAGLEN);
707        strncpy (header->header.version, TVERSION, TVERSLEN);        strncpy (header->header.version, TVERSION, TVERSLEN);
708        break;        break;
# Line 1114  dump_file (char *p, int top_level, dev_t Line 1227  dump_file (char *p, int top_level, dev_t
1227               files, we'd better put the / on the name.  */               files, we'd better put the / on the name.  */
1228    
1229            header = start_header (namebuf, &current_stat_info);            header = start_header (namebuf, &current_stat_info);
1230              if (!header)
1231                return;
1232              
1233            if (incremental_option)            if (incremental_option)
1234              header->header.typeflag = GNUTYPE_DUMPDIR;              header->header.typeflag = GNUTYPE_DUMPDIR;
1235            else /* if (standard_option) */            else /* if (standard_option) */
# Line 1248  dump_file (char *p, int top_level, dev_t Line 1363  dump_file (char *p, int top_level, dev_t
1363    
1364                current_stat_info.stat.st_size = 0;                current_stat_info.stat.st_size = 0;
1365                header = start_header (p, &current_stat_info);                header = start_header (p, &current_stat_info);
1366                  if (!header)
1367                    return;
1368                strncpy (header->header.linkname, link_name, NAME_FIELD_SIZE);                strncpy (header->header.linkname, link_name, NAME_FIELD_SIZE);
1369    
1370                /* Force null termination.  */                /* Force null termination.  */
# Line 1324  dump_file (char *p, int top_level, dev_t Line 1441  dump_file (char *p, int top_level, dev_t
1441    
1442                    block_ordinal = current_block_ordinal ();                    block_ordinal = current_block_ordinal ();
1443                    header = start_header (p, &current_stat_info);                    header = start_header (p, &current_stat_info);
1444                      if (!header)
1445                        return;
1446                    header->header.typeflag = GNUTYPE_SPARSE;                    header->header.typeflag = GNUTYPE_SPARSE;
1447                    header_moved = 1;                    header_moved = 1;
1448    
# Line 1395  dump_file (char *p, int top_level, dev_t Line 1514  dump_file (char *p, int top_level, dev_t
1514              {              {
1515                block_ordinal = current_block_ordinal ();                block_ordinal = current_block_ordinal ();
1516                header = start_header (p, &current_stat_info);                header = start_header (p, &current_stat_info);
1517                  if (!header)
1518                    return;
1519              }              }
1520    
1521            /* Mark contiguous files, if we support them.  */            /* Mark contiguous files, if we support them.  */
1522    
1523            if (archive_format != V7_FORMAT && S_ISCTG (current_stat_info.stat.st_mode))            if (archive_format != V7_FORMAT
1524                  && S_ISCTG (current_stat_info.stat.st_mode))
1525              header->header.typeflag = CONTTYPE;              header->header.typeflag = CONTTYPE;
1526    
1527            isextended = header->oldgnu_header.isextended;            if (archive_format == GNU_FORMAT || archive_format == OLDGNU_FORMAT)
1528                isextended = header->oldgnu_header.isextended;
1529              else
1530                isextended = 0;
1531              if (isextended)
1532                abort();
1533            save_typeflag = header->header.typeflag;            save_typeflag = header->header.typeflag;
1534            finish_header (header, block_ordinal);            finish_header (header, block_ordinal);
1535            if (isextended)            if (isextended)
# Line 1578  dump_file (char *p, int top_level, dev_t Line 1705  dump_file (char *p, int top_level, dev_t
1705            block_ordinal = current_block_ordinal ();            block_ordinal = current_block_ordinal ();
1706            current_stat_info.stat.st_size = 0;   /* force 0 size on symlink */            current_stat_info.stat.st_size = 0;   /* force 0 size on symlink */
1707            header = start_header (p, &current_stat_info);            header = start_header (p, &current_stat_info);
1708              if (!header)
1709                return;
1710            strncpy (header->header.linkname, buffer, NAME_FIELD_SIZE);            strncpy (header->header.linkname, buffer, NAME_FIELD_SIZE);
1711            header->header.linkname[NAME_FIELD_SIZE - 1] = '\0';            header->header.linkname[NAME_FIELD_SIZE - 1] = '\0';
1712            header->header.typeflag = SYMTYPE;            header->header.typeflag = SYMTYPE;
# Line 1618  dump_file (char *p, int top_level, dev_t Line 1747  dump_file (char *p, int top_level, dev_t
1747    block_ordinal = current_block_ordinal ();    block_ordinal = current_block_ordinal ();
1748    current_stat_info.stat.st_size = 0;   /* force 0 size */    current_stat_info.stat.st_size = 0;   /* force 0 size */
1749    header = start_header (p, &current_stat_info);    header = start_header (p, &current_stat_info);
1750      if (!header)
1751        return;
1752    header->header.typeflag = type;    header->header.typeflag = type;
1753    
1754    if (type != FIFOTYPE)    if (type != FIFOTYPE)

Legend:
Removed from v.1.65  
changed lines
  Added in v.1.66

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26