]> Dogcows Code - chaz/tar/blob - src/xheader.c
Implemented coder functions.
[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 { NULL },
100 };
101
102 static struct xhdr_tab *
103 locate_handler (char *keyword)
104 {
105 struct xhdr_tab *p;
106
107 for (p = xhdr_tab; p->keyword; p++)
108 if (strcmp (p->keyword, keyword) == 0)
109 return p;
110 return NULL;
111 }
112
113 static int
114 decode_record (char **p, struct tar_stat_info *st)
115 {
116 size_t len;
117 char *keyword, *eqp;
118 char *start = *p;
119 struct xhdr_tab *t;
120
121 if (**p == 0)
122 return 1;
123
124 len = strtoul (*p, p, 10);
125 if (**p != ' ')
126 {
127 ERROR ((0, 0, _("Malformed extended headed")));
128 return 1;
129 }
130
131 keyword = ++*p;
132 for (;*p < start + len; ++*p)
133 if (**p == '=')
134 break;
135
136 if (**p != '=')
137 {
138 ERROR ((0, 0, _("Malformed extended headed")));
139 return 1;
140 }
141
142 eqp = *p;
143 **p = 0;
144 t = locate_handler (keyword);
145 if (t)
146 {
147 char endc;
148 char *value;
149
150 value = ++*p;
151
152 endc = start[len-1];
153 start[len-1] = 0;
154 t->decoder (st, keyword, value);
155 start[len-1] = endc;
156 }
157 *eqp = '=';
158 *p = &start[len];
159 return 0;
160 }
161
162 void
163 xheader_decode (struct tar_stat_info *st)
164 {
165 char *p, *endp;
166
167 p = extended_header.buffer;
168 endp = &extended_header.buffer[extended_header.size-1];
169
170 while (p < endp)
171 if (decode_record (&p, st))
172 break;
173 }
174
175 void
176 xheader_store (char *keyword, struct tar_stat_info *st)
177 {
178 struct xhdr_tab *t;
179
180 if (extended_header.buffer)
181 return;
182 t = locate_handler (keyword);
183 if (!t)
184 return;
185 if (!extended_header.stk)
186 {
187 extended_header.stk = xmalloc (sizeof (*extended_header.stk));
188 obstack_init (extended_header.stk);
189 }
190 t->coder (st, keyword, &extended_header);
191 }
192
193 void
194 xheader_read (union block *p, size_t size)
195 {
196 size_t i, j;
197 size_t nblocks;
198
199 free (extended_header.buffer);
200 extended_header.size = size;
201 nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
202 extended_header.buffer = xmalloc (size + 1);
203
204 set_next_block_after (p);
205 for (i = j = 0; i < nblocks; i++)
206 {
207 size_t len;
208
209 p = find_next_block ();
210 len = size;
211 if (len > BLOCKSIZE)
212 len = BLOCKSIZE;
213 memcpy (&extended_header.buffer[j], p->buffer, len);
214 set_next_block_after (p);
215
216 j += len;
217 size -= len;
218 }
219 }
220
221 size_t
222 format_uintmax (uintmax_t val, char *buf, size_t s)
223 {
224 if (!buf)
225 {
226 s = 0;
227 do
228 s++;
229 while ((val /= 10) != 0);
230 }
231 else
232 {
233 char *p = buf + s - 1;
234
235 do
236 {
237 *p-- = val % 10 + '0';
238 }
239 while ((val /= 10) != 0);
240
241 while (p >= buf)
242 *p-- = '0';
243 }
244 return s;
245 }
246
247 void
248 xheader_print (struct xheader *xhdr, char *keyword, char *value)
249 {
250 size_t len = strlen (keyword) + strlen (value) + 3; /* ' ' + '=' + '\n' */
251 size_t p, n = 0;
252 char nbuf[100];
253
254 do
255 {
256 p = n;
257 n = format_uintmax (len + p, NULL, 0);
258 }
259 while (n != p);
260
261 format_uintmax (len + n, nbuf, n);
262 obstack_grow (xhdr->stk, nbuf, n);
263 obstack_1grow (xhdr->stk, ' ');
264 obstack_grow (xhdr->stk, keyword, strlen (keyword));
265 obstack_1grow (xhdr->stk, '=');
266 obstack_grow (xhdr->stk, value, strlen (value));
267 obstack_1grow (xhdr->stk, '\n');
268 }
269
270 void
271 xheader_finish (struct xheader *xhdr)
272 {
273 obstack_1grow (xhdr->stk, 0);
274 xhdr->buffer = obstack_finish (xhdr->stk);
275 xhdr->size = strlen (xhdr->buffer);
276 }
277
278 void
279 xheader_destroy (struct xheader *xhdr)
280 {
281 if (xhdr->stk)
282 {
283 obstack_free (xhdr->stk, NULL);
284 free (xhdr->stk);
285 xhdr->stk = NULL;
286 }
287 else
288 free (xhdr->buffer);
289 xhdr->buffer = 0;
290 xhdr->size = 0;
291 }
292
293 \f
294 /* Implementations */
295 static void
296 code_string (char *string, char *keyword, struct xheader *xhdr)
297 {
298 xheader_print (xhdr, keyword, string);
299 }
300
301 static void
302 code_time (time_t t, char *keyword, struct xheader *xhdr)
303 {
304 char sbuf[100];
305 size_t s = format_uintmax (t, NULL, 0);
306 format_uintmax (t, sbuf, s);
307 sbuf[s++] = '.';
308 format_uintmax (0, sbuf + s, 9);
309 sbuf[s+9] = 0;
310 xheader_print (xhdr, keyword, sbuf);
311 }
312
313 static void
314 code_num (uintmax_t value, char *keyword, struct xheader *xhdr)
315 {
316 char sbuf[100];
317 size_t s = format_uintmax (value, NULL, 0);
318 format_uintmax (value, sbuf, s);
319 sbuf[s] = 0;
320 xheader_print (xhdr, keyword, sbuf);
321 }
322
323 static void
324 dummy_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
325 {
326 }
327
328 static void
329 dummy_decoder (struct tar_stat_info *st, char *keyword, char *arg)
330 {
331 }
332
333 static void
334 atime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
335 {
336 code_time (st->stat.st_atime, keyword, xhdr);
337 }
338
339 static void
340 atime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
341 {
342 st->stat.st_atime = strtoul (arg, NULL, 0);
343 }
344
345 static void
346 gid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
347 {
348 code_num (st->stat.st_gid, keyword, xhdr);
349 }
350
351 static void
352 gid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
353 {
354 st->stat.st_gid = strtoul (arg, NULL, 0);
355 }
356
357 static void
358 gname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
359 {
360 code_string (st->gname, keyword, xhdr);
361 }
362
363 static void
364 gname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
365 {
366 assign_string (&st->gname, arg);
367 }
368
369 static void
370 linkpath_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
371 {
372 code_string (st->link_name, keyword, xhdr);
373 }
374
375 static void
376 linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg)
377 {
378 assign_string (&st->link_name, arg);
379 }
380
381 static void
382 ctime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
383 {
384 code_time (st->stat.st_ctime, keyword, xhdr);
385 }
386
387 static void
388 ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
389 {
390 st->stat.st_ctime = strtoul (arg, NULL, 0);
391 }
392
393 static void
394 mtime_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
395 {
396 code_time (st->stat.st_mtime, keyword, xhdr);
397 }
398
399 static void
400 mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
401 {
402 st->stat.st_mtime = strtoul (arg, NULL, 0);
403 }
404
405 static void
406 path_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
407 {
408 code_string (st->orig_file_name, keyword, xhdr);
409 }
410
411 static void
412 path_decoder (struct tar_stat_info *st, char *keyword, char *arg)
413 {
414 assign_string (&st->orig_file_name, arg);
415 assign_string (&st->file_name, arg);
416 st->had_trailing_slash = strip_trailing_slashes (st->file_name);
417 }
418
419 static void
420 size_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
421 {
422 code_num (st->stat.st_size, keyword, xhdr);
423 }
424
425 static void
426 size_decoder (struct tar_stat_info *st, char *keyword, char *arg)
427 {
428 st->stat.st_size = strtoul (arg, NULL, 0);
429 }
430
431 static void
432 uid_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
433 {
434 code_num (st->stat.st_uid, keyword, xhdr);
435 }
436
437 static void
438 uid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
439 {
440 st->stat.st_uid = strtoul (arg, NULL, 0);
441 }
442
443 static void
444 uname_coder (struct tar_stat_info *st, char *keyword, struct xheader *xhdr)
445 {
446 code_string (st->uname, keyword, xhdr);
447 }
448
449 static void
450 uname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
451 {
452 assign_string (&st->uname, arg);
453 }
454
This page took 0.053628 seconds and 5 git commands to generate.