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

Diff of /tar/src/xheader.c

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

revision 1.3 by gray, Wed Sep 3 00:03:32 2003 UTC revision 1.4 by eggert, Wed Sep 3 06:22:34 2003 UTC
# Line 1  Line 1 
1  /* This file is part of GNU Tar  /* POSIX extended and STAR headers.
2    
3     Copyright (C) 2003 Free Software Foundation, Inc.     Copyright (C) 2003 Free Software Foundation, Inc.
4    
# Line 29  Line 29 
29  #define obstack_chunk_free free  #define obstack_chunk_free free
30  #include <obstack.h>  #include <obstack.h>
31    
 /* Forward declarations */  
 static void dummy_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void dummy_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void atime_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void atime_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void gid_coder (struct tar_stat_info *st, char *keyword,  
                        struct xheader *xhdr);  
 static void gid_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void gname_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void gname_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void linkpath_coder (struct tar_stat_info *st, char *keyword,  
                             struct xheader *xhdr);  
 static void linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg);    
   
 static void mtime_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void ctime_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
       
 static void path_coder (struct tar_stat_info *st, char *keyword,  
                         struct xheader *xhdr);  
 static void path_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void size_coder (struct tar_stat_info *st, char *keyword,  
                         struct xheader *xhdr);  
 static void size_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void uid_coder (struct tar_stat_info *st, char *keyword,  
                        struct xheader *xhdr);  
 static void uid_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
 static void uname_coder (struct tar_stat_info *st, char *keyword,  
                          struct xheader *xhdr);  
 static void uname_decoder (struct tar_stat_info *st, char *keyword, char *arg);  
   
32  /* General Interface */  /* General Interface */
33    
34  struct xhdr_tab  struct xhdr_tab
35  {  {
36    char *keyword;    char const *keyword;
37    void (*coder) (struct tar_stat_info *st, char *keyword, struct xheader *xhdr);    void (*coder) (struct tar_stat_info const *, char const *, struct xheader *);
38    void (*decoder) (struct tar_stat_info *st, char *keyword, char *arg);    void (*decoder) (struct tar_stat_info *, char const *);
39  };  };
40    
41  struct xhdr_tab xhdr_tab[] = {  static struct xhdr_tab const xhdr_tab[];
   { "atime",    atime_coder,    atime_decoder },  
   { "comment",  dummy_coder,    dummy_decoder },  
   { "charset",  dummy_coder,    dummy_decoder },  
   { "ctime",    ctime_coder,    ctime_decoder },  
   { "gid",      gid_coder,      gid_decoder },  
   { "gname",    gname_coder,    gname_decoder },  
   { "linkpath", linkpath_coder, linkpath_decoder },  
   { "mtime",    mtime_coder,    mtime_decoder },  
   { "path",     path_coder,     path_decoder },  
   { "size",     size_coder,     size_decoder },  
   { "uid",      uid_coder,      uid_decoder },  
   { "uname",    uname_coder,    uname_decoder },  
 #if 0 /* GNU private keywords (not yet implemented) */  
   /* Sparse file handling */  
   { "GNU.sparse.offset",     sparse_offset_coder, sparse_offset_decoder },  
   { "GNU.sparse.numbytes",   sparse_numbytes_coder, sparse_numbytes_decoder },  
     
   /* The next directory entry actually contains the names of files that were  
      in the directory at the time the dump was made. Supersedes  
      GNUTYPE_DUMPDIR header type */  
   { "GNU.dumpdir",  dumpdir_coder, dumpdir_decoder },  
     
   /* Keeps the tape/volume header. May be present only in the global headers.  
      Equivalent to GNUTYPE_VOLHDR */  
   { "GNU.volume.header", volume_header_coder, volume_header_decoder },  
42    
43    /* These may be present in a first global header of the archive. They  static struct xhdr_tab const *
44       provide the same functionality as GNUTYPE_MULTIVOL header.  locate_handler (char const *keyword)
      The GNU.volume.size keeps the real_s_sizeleft value (which is  
      otherwise kept in the size field of a multivolume header).  
      The GNU.volume.offset keeps the offset of the start of this  
      volume (otherwise kept in oldgnu_header.offset */  
   { "GNU.volume.size", volume_size_coder, volume_size_decoder },  
   { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder },  
 #endif  
   { NULL },  
 };  
   
 static struct xhdr_tab *  
 locate_handler (char *keyword)  
45  {  {
46    struct xhdr_tab *p;    struct xhdr_tab const *p;
47    
48    for (p = xhdr_tab; p->keyword; p++)    for (p = xhdr_tab; p->keyword; p++)
49      if (strcmp (p->keyword, keyword) == 0)      if (strcmp (p->keyword, keyword) == 0)
# Line 133  locate_handler (char *keyword) Line 51  locate_handler (char *keyword)
51    return NULL;    return NULL;
52  }  }
53    
54  static int  static bool
55  decode_record (char **p, struct tar_stat_info *st)  decode_record (char **p, struct tar_stat_info *st)
56  {  {
57    size_t len;    size_t len;
58    char *keyword, *eqp;    char const *keyword;
59      char *eqp;
60    char *start = *p;    char *start = *p;
61    struct xhdr_tab *t;    struct xhdr_tab const *t;
62    
63    if (**p == 0)    if (**p == 0)
64      return 1;      return true;
65      
66    len = strtoul (*p, p, 10);    len = strtoul (*p, p, 10);
67    if (**p != ' ')    if (**p != ' ')
68      {      {
69        ERROR ((0, 0, _("Malformed extended headed")));        ERROR ((0, 0, _("Malformed extended header")));
70        return 1;        return true;
71      }      }
72      
73    keyword = ++*p;    keyword = ++*p;
74    for (;*p < start + len; ++*p)    for (;*p < start + len; ++*p)
75      if (**p == '=')      if (**p == '=')
# Line 158  decode_record (char **p, struct tar_stat Line 77  decode_record (char **p, struct tar_stat
77    
78    if (**p != '=')    if (**p != '=')
79      {      {
80        ERROR ((0, 0, _("Malformed extended headed")));        ERROR ((0, 0, _("Malformed extended header")));
81        return 1;        return true;
82      }      }
83    
84    eqp = *p;    eqp = *p;
# Line 171  decode_record (char **p, struct tar_stat Line 90  decode_record (char **p, struct tar_stat
90        char *value;        char *value;
91    
92        value = ++*p;        value = ++*p;
93          
94        endc = start[len-1];        endc = start[len-1];
95        start[len-1] = 0;        start[len-1] = 0;
96        t->decoder (st, keyword, value);        t->decoder (st, value);
97        start[len-1] = endc;        start[len-1] = endc;
98      }      }
99    *eqp = '=';    *eqp = '=';
100    *p = &start[len];    *p = &start[len];
101    return 0;    return false;
102  }  }
103    
104  void  void
105  xheader_decode (struct tar_stat_info *st)  xheader_decode (struct tar_stat_info *st)
106  {  {
107    char *p, *endp;    char *p = extended_header.buffer;
108      char *endp = &extended_header.buffer[extended_header.size-1];
   p = extended_header.buffer;  
   endp = &extended_header.buffer[extended_header.size-1];  
109    
110    while (p < endp)    while (p < endp)
111      if (decode_record (&p, st))      if (decode_record (&p, st))
# Line 196  xheader_decode (struct tar_stat_info *st Line 113  xheader_decode (struct tar_stat_info *st
113  }  }
114    
115  void  void
116  xheader_store (char *keyword, struct tar_stat_info *st)  xheader_store (char const *keyword, struct tar_stat_info const *st)
117  {  {
118    struct xhdr_tab *t;    struct xhdr_tab const *t;
119    
120    if (extended_header.buffer)    if (extended_header.buffer)
121      return;      return;
# Line 207  xheader_store (char *keyword, struct tar Line 124  xheader_store (char *keyword, struct tar
124      return;      return;
125    if (!extended_header.stk)    if (!extended_header.stk)
126      {      {
127        extended_header.stk = xmalloc (sizeof (*extended_header.stk));        extended_header.stk = xmalloc (sizeof *extended_header.stk);
128        obstack_init (extended_header.stk);        obstack_init (extended_header.stk);
129      }      }
130    t->coder (st, keyword, &extended_header);    t->coder (st, keyword, &extended_header);
# Line 218  xheader_read (union block *p, size_t siz Line 135  xheader_read (union block *p, size_t siz
135  {  {
136    size_t i, j;    size_t i, j;
137    size_t nblocks;    size_t nblocks;
138      
139    free (extended_header.buffer);    free (extended_header.buffer);
140    extended_header.size = size;    extended_header.size = size;
141    nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;    nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
# Line 228  xheader_read (union block *p, size_t siz Line 145  xheader_read (union block *p, size_t siz
145    for (i = j = 0; i < nblocks; i++)    for (i = j = 0; i < nblocks; i++)
146      {      {
147        size_t len;        size_t len;
148          
149        p = find_next_block ();        p = find_next_block ();
150        len = size;        len = size;
151        if (len > BLOCKSIZE)        if (len > BLOCKSIZE)
# Line 241  xheader_read (union block *p, size_t siz Line 158  xheader_read (union block *p, size_t siz
158      }      }
159  }  }
160    
161  size_t  static size_t
162  format_uintmax (uintmax_t val, char *buf, size_t s)  format_uintmax (uintmax_t val, char *buf, size_t s)
163  {  {
164    if (!buf)    if (!buf)
# Line 254  format_uintmax (uintmax_t val, char *buf Line 171  format_uintmax (uintmax_t val, char *buf
171    else    else
172      {      {
173        char *p = buf + s - 1;        char *p = buf + s - 1;
174      
175        do        do
176          {          {
177            *p-- = val % 10 + '0';            *p-- = val % 10 + '0';
# Line 267  format_uintmax (uintmax_t val, char *buf Line 184  format_uintmax (uintmax_t val, char *buf
184    return s;    return s;
185  }  }
186    
187  void  static void
188  xheader_print (struct xheader *xhdr, char *keyword, char *value)  xheader_print (struct xheader *xhdr, char const *keyword, char const *value)
189  {  {
190    size_t len = strlen (keyword) + strlen (value) + 3; /* ' ' + '=' + '\n' */    size_t len = strlen (keyword) + strlen (value) + 3; /* ' ' + '=' + '\n' */
191    size_t p, n = 0;    size_t p, n = 0;
192    char nbuf[100];    char nbuf[100];
193      
194    do    do
195      {      {
196        p = n;        p = n;
# Line 304  xheader_destroy (struct xheader *xhdr) Line 221  xheader_destroy (struct xheader *xhdr)
221    if (xhdr->stk)    if (xhdr->stk)
222      {      {
223        obstack_free (xhdr->stk, NULL);        obstack_free (xhdr->stk, NULL);
224        free  (xhdr->stk);        free (xhdr->stk);
225        xhdr->stk = NULL;        xhdr->stk = NULL;
226      }      }
227    else    else
# Line 316  xheader_destroy (struct xheader *xhdr) Line 233  xheader_destroy (struct xheader *xhdr)
233    
234  /* Implementations */  /* Implementations */
235  static void  static void
236  code_string (char *string, char *keyword, struct xheader *xhdr)  code_string (char const *string, char const *keyword, struct xheader *xhdr)
237  {  {
238    xheader_print (xhdr, keyword, string);    xheader_print (xhdr, keyword, string);
239  }  }
240    
241  static void  static void
242  code_time (time_t t, char *keyword, struct xheader *xhdr)  code_time (time_t t, char const *keyword, struct xheader *xhdr)
243  {  {
244    char sbuf[100];    char sbuf[100];
245    size_t s = format_uintmax (t, NULL, 0);    size_t s = format_uintmax (t, NULL, 0);
# Line 334  code_time (time_t t, char *keyword, stru Line 251  code_time (time_t t, char *keyword, stru
251  }  }
252    
253  static void  static void
254  code_num (uintmax_t value, char *keyword, struct xheader *xhdr)  code_num (uintmax_t value, char const *keyword, struct xheader *xhdr)
255  {  {
256    char sbuf[100];    char sbuf[100];
257    size_t s = format_uintmax (value, NULL, 0);    size_t s = format_uintmax (value, NULL, 0);
258    format_uintmax (value, sbuf, s);    format_uintmax (value, sbuf, s);
259    sbuf[s] = 0;    sbuf[s] = 0;
# Line 344  code_num (uintmax_t value, char *keyword Line 261  code_num (uintmax_t value, char *keyword
261  }  }
262    
263  static void  static void
264  dummy_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  dummy_coder (struct tar_stat_info const *st, char const *keyword,
265                 struct xheader *xhdr)
266  {  {
267  }  }
268    
269  static void  static void
270  dummy_decoder (struct tar_stat_info *st, char *keyword, char *arg)  dummy_decoder (struct tar_stat_info *st, char const *arg)
271  {  {
272  }  }
273    
274  static void  static void
275  atime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  atime_coder (struct tar_stat_info const *st, char const *keyword,
276                 struct xheader *xhdr)
277  {  {
278    code_time (st->stat.st_atime, keyword, xhdr);    code_time (st->stat.st_atime, keyword, xhdr);
279  }  }
280    
281  static void  static void
282  atime_decoder (struct tar_stat_info *st, char *keyword, char *arg)  atime_decoder (struct tar_stat_info *st, char const *arg)
283  {  {
284    st->stat.st_atime = strtoul (arg, NULL, 0);    st->stat.st_atime = strtoul (arg, NULL, 0);
285  }  }
286    
287  static void  static void
288  gid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  gid_coder (struct tar_stat_info const *st, char const *keyword,
289               struct xheader *xhdr)
290  {  {
291    code_num (st->stat.st_gid, keyword, xhdr);    code_num (st->stat.st_gid, keyword, xhdr);
292  }  }
293    
294  static void  static void
295  gid_decoder (struct tar_stat_info *st, char *keyword, char *arg)  gid_decoder (struct tar_stat_info *st, char const *arg)
296  {  {
297    st->stat.st_gid = strtoul (arg, NULL, 0);    st->stat.st_gid = strtoul (arg, NULL, 0);
298  }  }
299    
300  static void  static void
301  gname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  gname_coder (struct tar_stat_info const *st, char const *keyword,
302                 struct xheader *xhdr)
303  {  {
304    code_string (st->gname, keyword, xhdr);    code_string (st->gname, keyword, xhdr);
305  }  }
306    
307  static void  static void
308  gname_decoder (struct tar_stat_info *st, char *keyword, char *arg)  gname_decoder (struct tar_stat_info *st, char const *arg)
309  {  {
310    assign_string (&st->gname, arg);    assign_string (&st->gname, arg);
311  }  }
312    
313  static void  static void
314  linkpath_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  linkpath_coder (struct tar_stat_info const *st, char const *keyword,
315                    struct xheader *xhdr)
316  {  {
317    code_string (st->link_name, keyword, xhdr);    code_string (st->link_name, keyword, xhdr);
318  }  }
319    
320  static void  static void
321  linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg)  linkpath_decoder (struct tar_stat_info *st, char const *arg)
322  {  {
323    assign_string (&st->link_name, arg);    assign_string (&st->link_name, arg);
324  }  }
325    
326  static void  static void
327  ctime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  ctime_coder (struct tar_stat_info const *st, char const *keyword,
328                 struct xheader *xhdr)
329  {  {
330    code_time (st->stat.st_ctime, keyword, xhdr);    code_time (st->stat.st_ctime, keyword, xhdr);
331  }  }
332    
333  static void  static void
334  ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg)  ctime_decoder (struct tar_stat_info *st, char const *arg)
335  {  {
336    st->stat.st_ctime = strtoul (arg, NULL, 0);    st->stat.st_ctime = strtoul (arg, NULL, 0);
337  }  }
338    
339  static void  static void
340  mtime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  mtime_coder (struct tar_stat_info const *st, char const *keyword,
341                 struct xheader *xhdr)
342  {  {
343    code_time (st->stat.st_mtime, keyword, xhdr);    code_time (st->stat.st_mtime, keyword, xhdr);
344  }  }
345    
346  static void  static void
347  mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg)  mtime_decoder (struct tar_stat_info *st, char const *arg)
348  {  {
349    st->stat.st_mtime = strtoul (arg, NULL, 0);    st->stat.st_mtime = strtoul (arg, NULL, 0);
350  }  }
351    
352  static void  static void
353  path_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  path_coder (struct tar_stat_info const *st, char const *keyword,
354                struct xheader *xhdr)
355  {  {
356    code_string (st->file_name, keyword, xhdr);    code_string (st->file_name, keyword, xhdr);
357  }  }
358    
359  static void  static void
360  path_decoder (struct tar_stat_info *st, char *keyword, char *arg)  path_decoder (struct tar_stat_info *st, char const *arg)
361  {  {
362    assign_string (&st->orig_file_name, arg);    assign_string (&st->orig_file_name, arg);
363    assign_string (&st->file_name, arg);    assign_string (&st->file_name, arg);
# Line 440  path_decoder (struct tar_stat_info *st, Line 365  path_decoder (struct tar_stat_info *st,
365  }  }
366    
367  static void  static void
368  size_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  size_coder (struct tar_stat_info const *st, char const *keyword,
369                struct xheader *xhdr)
370  {  {
371    code_num (st->stat.st_size, keyword, xhdr);    code_num (st->stat.st_size, keyword, xhdr);
372  }  }
373    
374  static void  static void
375  size_decoder (struct tar_stat_info *st, char *keyword, char *arg)  size_decoder (struct tar_stat_info *st, char const *arg)
376  {  {
377    st->stat.st_size = strtoul (arg, NULL, 0);    st->stat.st_size = strtoul (arg, NULL, 0);
378  }  }
379    
380  static void  static void
381  uid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  uid_coder (struct tar_stat_info const *st, char const *keyword,
382               struct xheader *xhdr)
383  {  {
384    code_num (st->stat.st_uid, keyword, xhdr);    code_num (st->stat.st_uid, keyword, xhdr);
385  }  }
386    
387  static void  static void
388  uid_decoder (struct tar_stat_info *st, char *keyword, char *arg)  uid_decoder (struct tar_stat_info *st, char const *arg)
389  {  {
390    st->stat.st_uid = strtoul (arg, NULL, 0);    st->stat.st_uid = strtoul (arg, NULL, 0);
391  }  }
392    
393  static void  static void
394  uname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)  uname_coder (struct tar_stat_info const *st, char const *keyword,
395                 struct xheader *xhdr)
396  {  {
397    code_string (st->uname, keyword, xhdr);    code_string (st->uname, keyword, xhdr);
398  }  }
399    
400  static void  static void
401  uname_decoder (struct tar_stat_info *st, char *keyword, char *arg)  uname_decoder (struct tar_stat_info *st, char const *arg)
402  {  {
403    assign_string (&st->uname, arg);    assign_string (&st->uname, arg);
404  }  }
405      
406    static struct xhdr_tab const xhdr_tab[] = {
407      { "atime",    atime_coder,    atime_decoder   },
408      { "comment",  dummy_coder,    dummy_decoder   },
409      { "charset",  dummy_coder,    dummy_decoder   },
410      { "ctime",    ctime_coder,    ctime_decoder   },
411      { "gid",      gid_coder,      gid_decoder     },
412      { "gname",    gname_coder,    gname_decoder   },
413      { "linkpath", linkpath_coder, linkpath_decoder},
414      { "mtime",    mtime_coder,    mtime_decoder   },
415      { "path",     path_coder,     path_decoder    },
416      { "size",     size_coder,     size_decoder    },
417      { "uid",      uid_coder,      uid_decoder     },
418      { "uname",    uname_coder,    uname_decoder   },
419    
420    #if 0 /* GNU private keywords (not yet implemented) */
421      /* Sparse file handling */
422      { "GNU.sparse.offset",     sparse_offset_coder, sparse_offset_decoder },
423      { "GNU.sparse.numbytes",   sparse_numbytes_coder, sparse_numbytes_decoder },
424    
425      /* The next directory entry actually contains the names of files
426         that were in the directory at the time the dump was made.
427         Supersedes GNUTYPE_DUMPDIR header type.  */
428      { "GNU.dumpdir",  dumpdir_coder, dumpdir_decoder },
429    
430      /* Keeps the tape/volume header. May be present only in the global headers.
431         Equivalent to GNUTYPE_VOLHDR.  */
432      { "GNU.volume.header", volume_header_coder, volume_header_decoder },
433    
434      /* These may be present in a first global header of the archive.
435         They provide the same functionality as GNUTYPE_MULTIVOL header.
436         The GNU.volume.size keeps the real_s_sizeleft value, which is
437         otherwise kept in the size field of a multivolume header.  The
438         GNU.volume.offset keeps the offset of the start of this volume,
439         otherwise kept in oldgnu_header.offset.  */
440      { "GNU.volume.size", volume_size_coder, volume_size_decoder },
441      { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder },
442    #endif
443    
444      { NULL, NULL, NULL }
445    };

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

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