]> Dogcows Code - chaz/tar/blob - src/xheader.c
(xhdr_tab): Reserved GNU keywords (commented out for the time being)
[chaz/tar] / src / xheader.c
1 /* This file is part of GNU Tar
2
3 Copyright (C) 2003 Free Software Foundation, Inc.
4
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
8 version.
9
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.
14
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. */
18
19 #include "system.h"
20
21 #include <grp.h>
22 #include <hash.h>
23 #include <pwd.h>
24 #include <quotearg.h>
25
26 #include "common.h"
27
28 #define obstack_chunk_alloc xmalloc
29 #define obstack_chunk_free free
30 #include <obstack.h>
31
32 /* Forward declarations */
33 static void dummy_coder (struct tar_stat_info *st, char *keyword,
34 struct xheader *xhdr);
35 static void dummy_decoder (struct tar_stat_info *st, char *keyword, char *arg);
36
37 static void atime_coder (struct tar_stat_info *st, char *keyword,
38 struct xheader *xhdr);
39 static void atime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
40
41 static void gid_coder (struct tar_stat_info *st, char *keyword,
42 struct xheader *xhdr);
43 static void gid_decoder (struct tar_stat_info *st, char *keyword, char *arg);
44
45 static void gname_coder (struct tar_stat_info *st, char *keyword,
46 struct xheader *xhdr);
47 static void gname_decoder (struct tar_stat_info *st, char *keyword, char *arg);
48
49 static void linkpath_coder (struct tar_stat_info *st, char *keyword,
50 struct xheader *xhdr);
51 static void linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg);
52
53 static void mtime_coder (struct tar_stat_info *st, char *keyword,
54 struct xheader *xhdr);
55 static void mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
56
57 static void ctime_coder (struct tar_stat_info *st, char *keyword,
58 struct xheader *xhdr);
59 static void ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
60
61 static void path_coder (struct tar_stat_info *st, char *keyword,
62 struct xheader *xhdr);
63 static void path_decoder (struct tar_stat_info *st, char *keyword, char *arg);
64
65 static void size_coder (struct tar_stat_info *st, char *keyword,
66 struct xheader *xhdr);
67 static void size_decoder (struct tar_stat_info *st, char *keyword, char *arg);
68
69 static void uid_coder (struct tar_stat_info *st, char *keyword,
70 struct xheader *xhdr);
71 static void uid_decoder (struct tar_stat_info *st, char *keyword, char *arg);
72
73 static void uname_coder (struct tar_stat_info *st, char *keyword,
74 struct xheader *xhdr);
75 static void uname_decoder (struct tar_stat_info *st, char *keyword, char *arg);
76
77 /* General Interface */
78
79 struct xhdr_tab
80 {
81 char *keyword;
82 void (*coder) (struct tar_stat_info *st, char *keyword, struct xheader *xhdr);
83 void (*decoder) (struct tar_stat_info *st, char *keyword, char *arg);
84 };
85
86 struct xhdr_tab xhdr_tab[] = {
87 { "atime", atime_coder, atime_decoder },
88 { "comment", dummy_coder, dummy_decoder },
89 { "charset", dummy_coder, dummy_decoder },
90 { "ctime", ctime_coder, ctime_decoder },
91 { "gid", gid_coder, gid_decoder },
92 { "gname", gname_coder, gname_decoder },
93 { "linkpath", linkpath_coder, linkpath_decoder },
94 { "mtime", mtime_coder, mtime_decoder },
95 { "path", path_coder, path_decoder },
96 { "size", size_coder, size_decoder },
97 { "uid", uid_coder, uid_decoder },
98 { "uname", uname_coder, uname_decoder },
99 #if 0 /* GNU private keywords (not yet implemented) */
100 /* Sparse file handling */
101 { "GNU.sparse.offset", sparse_offset_coder, sparse_offset_decoder },
102 { "GNU.sparse.numbytes", sparse_numbytes_coder, sparse_numbytes_decoder },
103
104 /* The next directory entry actually contains the names of files that were
105 in the directory at the time the dump was made. Supersedes
106 GNUTYPE_DUMPDIR header type */
107 { "GNU.dumpdir", dumpdir_coder, dumpdir_decoder },
108
109 /* Keeps the tape/volume header. May be present only in the global headers.
110 Equivalent to GNUTYPE_VOLHDR */
111 { "GNU.volume.header", volume_header_coder, volume_header_decoder },
112
113 /* These may be present in a first global header of the archive. They
114 provide the same functionality as GNUTYPE_MULTIVOL header.
115 The GNU.volume.size keeps the real_s_sizeleft value (which is
116 otherwise kept in the size field of a multivolume header).
117 The GNU.volume.offset keeps the offset of the start of this
118 volume (otherwise kept in oldgnu_header.offset */
119 { "GNU.volume.size", volume_size_coder, volume_size_decoder },
120 { "GNU.volume.offset", volume_offset_coder, volume_offset_decoder },
121 #endif
122 { NULL },
123 };
124
125 static struct xhdr_tab *
126 locate_handler (char *keyword)
127 {
128 struct xhdr_tab *p;
129
130 for (p = xhdr_tab; p->keyword; p++)
131 if (strcmp (p->keyword, keyword) == 0)
132 return p;
133 return NULL;
134 }
135
136 static int
137 decode_record (char **p, struct tar_stat_info *st)
138 {
139 size_t len;
140 char *keyword, *eqp;
141 char *start = *p;
142 struct xhdr_tab *t;
143
144 if (**p == 0)
145 return 1;
146
147 len = strtoul (*p, p, 10);
148 if (**p != ' ')
149 {
150 ERROR ((0, 0, _("Malformed extended headed")));
151 return 1;
152 }
153
154 keyword = ++*p;
155 for (;*p < start + len; ++*p)
156 if (**p == '=')
157 break;
158
159 if (**p != '=')
160 {
161 ERROR ((0, 0, _("Malformed extended headed")));
162 return 1;
163 }
164
165 eqp = *p;
166 **p = 0;
167 t = locate_handler (keyword);
168 if (t)
169 {
170 char endc;
171 char *value;
172
173 value = ++*p;
174
175 endc = start[len-1];
176 start[len-1] = 0;
177 t->decoder (st, keyword, value);
178 start[len-1] = endc;
179 }
180 *eqp = '=';
181 *p = &start[len];
182 return 0;
183 }
184
185 void
186 xheader_decode (struct tar_stat_info *st)
187 {
188 char *p, *endp;
189
190 p = extended_header.buffer;
191 endp = &extended_header.buffer[extended_header.size-1];
192
193 while (p < endp)
194 if (decode_record (&p, st))
195 break;
196 }
197
198 void
199 xheader_store (char *keyword, struct tar_stat_info *st)
200 {
201 struct xhdr_tab *t;
202
203 if (extended_header.buffer)
204 return;
205 t = locate_handler (keyword);
206 if (!t)
207 return;
208 if (!extended_header.stk)
209 {
210 extended_header.stk = xmalloc (sizeof (*extended_header.stk));
211 obstack_init (extended_header.stk);
212 }
213 t->coder (st, keyword, &extended_header);
214 }
215
216 void
217 xheader_read (union block *p, size_t size)
218 {
219 size_t i, j;
220 size_t nblocks;
221
222 free (extended_header.buffer);
223 extended_header.size = size;
224 nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
225 extended_header.buffer = xmalloc (size + 1);
226
227 set_next_block_after (p);
228 for (i = j = 0; i < nblocks; i++)
229 {
230 size_t len;
231
232 p = find_next_block ();
233 len = size;
234 if (len > BLOCKSIZE)
235 len = BLOCKSIZE;
236 memcpy (&extended_header.buffer[j], p->buffer, len);
237 set_next_block_after (p);
238
239 j += len;
240 size -= len;
241 }
242 }
243
244 size_t
245 format_uintmax (uintmax_t val, char *buf, size_t s)
246 {
247 if (!buf)
248 {
249 s = 0;
250 do
251 s++;
252 while ((val /= 10) != 0);
253 }
254 else
255 {
256 char *p = buf + s - 1;
257
258 do
259 {
260 *p-- = val % 10 + '0';
261 }
262 while ((val /= 10) != 0);
263
264 while (p >= buf)
265 *p-- = '0';
266 }
267 return s;
268 }
269
270 void
271 xheader_print (struct xheader *xhdr, char *keyword, char *value)
272 {
273 size_t len = strlen (keyword) + strlen (value) + 3; /* ' ' + '=' + '\n' */
274 size_t p, n = 0;
275 char nbuf[100];
276
277 do
278 {
279 p = n;
280 n = format_uintmax (len + p, NULL, 0);
281 }
282 while (n != p);
283
284 format_uintmax (len + n, nbuf, n);
285 obstack_grow (xhdr->stk, nbuf, n);
286 obstack_1grow (xhdr->stk, ' ');
287 obstack_grow (xhdr->stk, keyword, strlen (keyword));
288 obstack_1grow (xhdr->stk, '=');
289 obstack_grow (xhdr->stk, value, strlen (value));
290 obstack_1grow (xhdr->stk, '\n');
291 }
292
293 void
294 xheader_finish (struct xheader *xhdr)
295 {
296 obstack_1grow (xhdr->stk, 0);
297 xhdr->buffer = obstack_finish (xhdr->stk);
298 xhdr->size = strlen (xhdr->buffer);
299 }
300
301 void
302 xheader_destroy (struct xheader *xhdr)
303 {
304 if (xhdr->stk)
305 {
306 obstack_free (xhdr->stk, NULL);
307 free (xhdr->stk);
308 xhdr->stk = NULL;
309 }
310 else
311 free (xhdr->buffer);
312 xhdr->buffer = 0;
313 xhdr->size = 0;
314 }
315
316 \f
317 /* Implementations */
318 static void
319 code_string (char *string, char *keyword, struct xheader *xhdr)
320 {
321 xheader_print (xhdr, keyword, string);
322 }
323
324 static void
325 code_time (time_t t, char *keyword, struct xheader *xhdr)
326 {
327 char sbuf[100];
328 size_t s = format_uintmax (t, NULL, 0);
329 format_uintmax (t, sbuf, s);
330 sbuf[s++] = '.';
331 format_uintmax (0, sbuf + s, 9);
332 sbuf[s+9] = 0;
333 xheader_print (xhdr, keyword, sbuf);
334 }
335
336 static void
337 code_num (uintmax_t value, char *keyword, struct xheader *xhdr)
338 {
339 char sbuf[100];
340 size_t s = format_uintmax (value, NULL, 0);
341 format_uintmax (value, sbuf, s);
342 sbuf[s] = 0;
343 xheader_print (xhdr, keyword, sbuf);
344 }
345
346 static void
347 dummy_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
348 {
349 }
350
351 static void
352 dummy_decoder (struct tar_stat_info *st, char *keyword, char *arg)
353 {
354 }
355
356 static void
357 atime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
358 {
359 code_time (st->stat.st_atime, keyword, xhdr);
360 }
361
362 static void
363 atime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
364 {
365 st->stat.st_atime = strtoul (arg, NULL, 0);
366 }
367
368 static void
369 gid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
370 {
371 code_num (st->stat.st_gid, keyword, xhdr);
372 }
373
374 static void
375 gid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
376 {
377 st->stat.st_gid = strtoul (arg, NULL, 0);
378 }
379
380 static void
381 gname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
382 {
383 code_string (st->gname, keyword, xhdr);
384 }
385
386 static void
387 gname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
388 {
389 assign_string (&st->gname, arg);
390 }
391
392 static void
393 linkpath_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
394 {
395 code_string (st->link_name, keyword, xhdr);
396 }
397
398 static void
399 linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg)
400 {
401 assign_string (&st->link_name, arg);
402 }
403
404 static void
405 ctime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
406 {
407 code_time (st->stat.st_ctime, keyword, xhdr);
408 }
409
410 static void
411 ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
412 {
413 st->stat.st_ctime = strtoul (arg, NULL, 0);
414 }
415
416 static void
417 mtime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
418 {
419 code_time (st->stat.st_mtime, keyword, xhdr);
420 }
421
422 static void
423 mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
424 {
425 st->stat.st_mtime = strtoul (arg, NULL, 0);
426 }
427
428 static void
429 path_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
430 {
431 code_string (st->file_name, keyword, xhdr);
432 }
433
434 static void
435 path_decoder (struct tar_stat_info *st, char *keyword, char *arg)
436 {
437 assign_string (&st->orig_file_name, arg);
438 assign_string (&st->file_name, arg);
439 st->had_trailing_slash = strip_trailing_slashes (st->file_name);
440 }
441
442 static void
443 size_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
444 {
445 code_num (st->stat.st_size, keyword, xhdr);
446 }
447
448 static void
449 size_decoder (struct tar_stat_info *st, char *keyword, char *arg)
450 {
451 st->stat.st_size = strtoul (arg, NULL, 0);
452 }
453
454 static void
455 uid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
456 {
457 code_num (st->stat.st_uid, keyword, xhdr);
458 }
459
460 static void
461 uid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
462 {
463 st->stat.st_uid = strtoul (arg, NULL, 0);
464 }
465
466 static void
467 uname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
468 {
469 code_string (st->uname, keyword, xhdr);
470 }
471
472 static void
473 uname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
474 {
475 assign_string (&st->uname, arg);
476 }
477
This page took 0.060269 seconds and 5 git commands to generate.