]>
Dogcows Code - chaz/tar/blob - src/xheader.c
1 /* POSIX extended and STAR headers.
3 Copyright (C) 2003 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26 #define obstack_chunk_alloc xmalloc
27 #define obstack_chunk_free free
30 /* General Interface */
35 void (*coder
) (struct tar_stat_info
const *, char const *, struct xheader
*);
36 void (*decoder
) (struct tar_stat_info
*, char const *);
39 /* This declaration must specify the number of elements in xhdr_tab,
40 because ISO C99 section 6.9.2 prohibits a tentative definition that
41 has both internal linkage and incomplete type. */
42 static struct xhdr_tab
const xhdr_tab
[13];
44 static struct xhdr_tab
const *
45 locate_handler (char const *keyword
)
47 struct xhdr_tab
const *p
;
49 for (p
= xhdr_tab
; p
->keyword
; p
++)
50 if (strcmp (p
->keyword
, keyword
) == 0)
55 /* Decodes a single extended header record. Advances P to the next
57 Returns true on success, false otherwise. */
59 decode_record (char **p
, struct tar_stat_info
*st
)
65 struct xhdr_tab
const *t
;
70 len
= strtoul (*p
, p
, 10);
73 ERROR ((0, 0, _("Malformed extended header: missing whitespace after the length")));
78 for (;*p
< start
+ len
; ++*p
)
84 ERROR ((0, 0, _("Malformed extended header: missing equal sign")));
90 t
= locate_handler (keyword
);
100 t
->decoder (st
, value
);
109 xheader_decode (struct tar_stat_info
*st
)
111 char *p
= extended_header
.buffer
+ BLOCKSIZE
;
112 char *endp
= &extended_header
.buffer
[extended_header
.size
-1];
115 if (!decode_record (&p
, st
))
120 xheader_store (char const *keyword
, struct tar_stat_info
const *st
)
122 struct xhdr_tab
const *t
;
124 if (extended_header
.buffer
)
126 t
= locate_handler (keyword
);
129 if (!extended_header
.stk
)
131 extended_header
.stk
= xmalloc (sizeof *extended_header
.stk
);
132 obstack_init (extended_header
.stk
);
134 t
->coder (st
, keyword
, &extended_header
);
138 xheader_read (union block
*p
, size_t size
)
143 free (extended_header
.buffer
);
145 extended_header
.size
= size
;
146 nblocks
= (size
+ BLOCKSIZE
- 1) / BLOCKSIZE
;
147 extended_header
.buffer
= xmalloc (size
+ 1);
156 memcpy (&extended_header
.buffer
[j
], p
->buffer
, len
);
157 set_next_block_after (p
);
159 p
= find_next_block ();
168 format_uintmax (uintmax_t val
, char *buf
, size_t s
)
175 while ((val
/= 10) != 0);
179 char *p
= buf
+ s
- 1;
183 *p
-- = val
% 10 + '0';
185 while ((val
/= 10) != 0);
194 xheader_print (struct xheader
*xhdr
, char const *keyword
, char const *value
)
196 size_t len
= strlen (keyword
) + strlen (value
) + 3; /* ' ' + '=' + '\n' */
203 n
= format_uintmax (len
+ p
, NULL
, 0);
207 format_uintmax (len
+ n
, nbuf
, n
);
208 obstack_grow (xhdr
->stk
, nbuf
, n
);
209 obstack_1grow (xhdr
->stk
, ' ');
210 obstack_grow (xhdr
->stk
, keyword
, strlen (keyword
));
211 obstack_1grow (xhdr
->stk
, '=');
212 obstack_grow (xhdr
->stk
, value
, strlen (value
));
213 obstack_1grow (xhdr
->stk
, '\n');
217 xheader_finish (struct xheader
*xhdr
)
219 obstack_1grow (xhdr
->stk
, 0);
220 xhdr
->buffer
= obstack_finish (xhdr
->stk
);
221 xhdr
->size
= strlen (xhdr
->buffer
);
225 xheader_destroy (struct xheader
*xhdr
)
229 obstack_free (xhdr
->stk
, NULL
);
240 /* Implementations */
242 code_string (char const *string
, char const *keyword
, struct xheader
*xhdr
)
244 xheader_print (xhdr
, keyword
, string
);
248 code_time (time_t t
, char const *keyword
, struct xheader
*xhdr
)
251 size_t s
= format_uintmax (t
, NULL
, 0);
252 format_uintmax (t
, sbuf
, s
);
254 format_uintmax (0, sbuf
+ s
, 9);
256 xheader_print (xhdr
, keyword
, sbuf
);
260 code_num (uintmax_t value
, char const *keyword
, struct xheader
*xhdr
)
263 size_t s
= format_uintmax (value
, NULL
, 0);
264 format_uintmax (value
, sbuf
, s
);
266 xheader_print (xhdr
, keyword
, sbuf
);
270 dummy_coder (struct tar_stat_info
const *st
, char const *keyword
,
271 struct xheader
*xhdr
)
276 dummy_decoder (struct tar_stat_info
*st
, char const *arg
)
281 atime_coder (struct tar_stat_info
const *st
, char const *keyword
,
282 struct xheader
*xhdr
)
284 code_time (st
->stat
.st_atime
, keyword
, xhdr
);
288 atime_decoder (struct tar_stat_info
*st
, char const *arg
)
290 st
->stat
.st_atime
= strtoul (arg
, NULL
, 0);
294 gid_coder (struct tar_stat_info
const *st
, char const *keyword
,
295 struct xheader
*xhdr
)
297 code_num (st
->stat
.st_gid
, keyword
, xhdr
);
301 gid_decoder (struct tar_stat_info
*st
, char const *arg
)
303 st
->stat
.st_gid
= strtoul (arg
, NULL
, 0);
307 gname_coder (struct tar_stat_info
const *st
, char const *keyword
,
308 struct xheader
*xhdr
)
310 code_string (st
->gname
, keyword
, xhdr
);
314 gname_decoder (struct tar_stat_info
*st
, char const *arg
)
316 assign_string (&st
->gname
, arg
);
320 linkpath_coder (struct tar_stat_info
const *st
, char const *keyword
,
321 struct xheader
*xhdr
)
323 code_string (st
->link_name
, keyword
, xhdr
);
327 linkpath_decoder (struct tar_stat_info
*st
, char const *arg
)
329 assign_string (&st
->link_name
, arg
);
333 ctime_coder (struct tar_stat_info
const *st
, char const *keyword
,
334 struct xheader
*xhdr
)
336 code_time (st
->stat
.st_ctime
, keyword
, xhdr
);
340 ctime_decoder (struct tar_stat_info
*st
, char const *arg
)
342 st
->stat
.st_ctime
= strtoul (arg
, NULL
, 0);
346 mtime_coder (struct tar_stat_info
const *st
, char const *keyword
,
347 struct xheader
*xhdr
)
349 code_time (st
->stat
.st_mtime
, keyword
, xhdr
);
353 mtime_decoder (struct tar_stat_info
*st
, char const *arg
)
355 st
->stat
.st_mtime
= strtoul (arg
, NULL
, 0);
359 path_coder (struct tar_stat_info
const *st
, char const *keyword
,
360 struct xheader
*xhdr
)
362 code_string (st
->file_name
, keyword
, xhdr
);
366 path_decoder (struct tar_stat_info
*st
, char const *arg
)
368 assign_string (&st
->orig_file_name
, arg
);
369 assign_string (&st
->file_name
, arg
);
370 st
->had_trailing_slash
= strip_trailing_slashes (st
->file_name
);
374 size_coder (struct tar_stat_info
const *st
, char const *keyword
,
375 struct xheader
*xhdr
)
377 code_num (st
->stat
.st_size
, keyword
, xhdr
);
381 size_decoder (struct tar_stat_info
*st
, char const *arg
)
383 st
->stat
.st_size
= strtoul (arg
, NULL
, 0);
387 uid_coder (struct tar_stat_info
const *st
, char const *keyword
,
388 struct xheader
*xhdr
)
390 code_num (st
->stat
.st_uid
, keyword
, xhdr
);
394 uid_decoder (struct tar_stat_info
*st
, char const *arg
)
396 st
->stat
.st_uid
= strtoul (arg
, NULL
, 0);
400 uname_coder (struct tar_stat_info
const *st
, char const *keyword
,
401 struct xheader
*xhdr
)
403 code_string (st
->uname
, keyword
, xhdr
);
407 uname_decoder (struct tar_stat_info
*st
, char const *arg
)
409 assign_string (&st
->uname
, arg
);
412 static struct xhdr_tab
const xhdr_tab
[] = {
413 { "atime", atime_coder
, atime_decoder
},
414 { "comment", dummy_coder
, dummy_decoder
},
415 { "charset", dummy_coder
, dummy_decoder
},
416 { "ctime", ctime_coder
, ctime_decoder
},
417 { "gid", gid_coder
, gid_decoder
},
418 { "gname", gname_coder
, gname_decoder
},
419 { "linkpath", linkpath_coder
, linkpath_decoder
},
420 { "mtime", mtime_coder
, mtime_decoder
},
421 { "path", path_coder
, path_decoder
},
422 { "size", size_coder
, size_decoder
},
423 { "uid", uid_coder
, uid_decoder
},
424 { "uname", uname_coder
, uname_decoder
},
426 /* The number of entries in xhdr_tab must agree with the array
427 bounds in xhdr_tab's forward declaration. */
429 #if 0 /* GNU private keywords (not yet implemented) */
430 /* Sparse file handling */
431 { "GNU.sparse.offset", sparse_offset_coder
, sparse_offset_decoder
},
432 { "GNU.sparse.numbytes", sparse_numbytes_coder
, sparse_numbytes_decoder
},
434 /* The next directory entry actually contains the names of files
435 that were in the directory at the time the dump was made.
436 Supersedes GNUTYPE_DUMPDIR header type. */
437 { "GNU.dumpdir", dumpdir_coder
, dumpdir_decoder
},
439 /* Keeps the tape/volume header. May be present only in the global headers.
440 Equivalent to GNUTYPE_VOLHDR. */
441 { "GNU.volume.header", volume_header_coder
, volume_header_decoder
},
443 /* These may be present in a first global header of the archive.
444 They provide the same functionality as GNUTYPE_MULTIVOL header.
445 The GNU.volume.size keeps the real_s_sizeleft value, which is
446 otherwise kept in the size field of a multivolume header. The
447 GNU.volume.offset keeps the offset of the start of this volume,
448 otherwise kept in oldgnu_header.offset. */
449 { "GNU.volume.size", volume_size_coder
, volume_size_decoder
},
450 { "GNU.volume.offset", volume_offset_coder
, volume_offset_decoder
},
This page took 0.058829 seconds and 5 git commands to generate.