]> Dogcows Code - chaz/tar/blob - src/xheader.c
New file
[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 /* Forward declarations */
29 static void dummy_handler (struct tar_stat_info *st, char *keyword, char *arg);
30
31 static void atime_coder (struct tar_stat_info *st, char *keyword, char *arg);
32 static void atime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
33
34 static void gid_coder (struct tar_stat_info *st, char *keyword, char *arg);
35 static void gid_decoder (struct tar_stat_info *st, char *keyword, char *arg);
36
37 static void gname_coder (struct tar_stat_info *st, char *keyword, char *arg);
38 static void gname_decoder (struct tar_stat_info *st, char *keyword, char *arg);
39
40 static void linkpath_coder (struct tar_stat_info *st, char *keyword, char *arg);
41 static void linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg);
42
43 static void mtime_coder (struct tar_stat_info *st, char *keyword, char *arg);
44 static void mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
45
46 static void ctime_coder (struct tar_stat_info *st, char *keyword, char *arg);
47 static void ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg);
48
49 static void path_coder (struct tar_stat_info *st, char *keyword, char *arg);
50 static void path_decoder (struct tar_stat_info *st, char *keyword, char *arg);
51
52 static void size_coder (struct tar_stat_info *st, char *keyword, char *arg);
53 static void size_decoder (struct tar_stat_info *st, char *keyword, char *arg);
54
55 static void uid_coder (struct tar_stat_info *st, char *keyword, char *arg);
56 static void uid_decoder (struct tar_stat_info *st, char *keyword, char *arg);
57
58 static void uname_coder (struct tar_stat_info *st, char *keyword, char *arg);
59 static void uname_decoder (struct tar_stat_info *st, char *keyword, char *arg);
60
61 /* General Interface */
62
63 struct xhdr_tab
64 {
65 char *keyword;
66 void (*coder) (struct tar_stat_info *st, char *keyword, char *arg);
67 void (*decoder) (struct tar_stat_info *st, char *keyword, char *arg);
68 };
69
70 struct xhdr_tab xhdr_tab[] = {
71 { "atime", atime_coder, atime_decoder },
72 { "comment", dummy_handler, dummy_handler },
73 { "charset", dummy_handler, dummy_handler },
74 { "ctime", ctime_coder, ctime_decoder },
75 { "gid", gid_coder, gid_decoder },
76 { "gname", gname_coder, gname_decoder },
77 { "linkpath", linkpath_coder, linkpath_decoder },
78 { "mtime", mtime_coder, mtime_decoder },
79 { "path", path_coder, path_decoder },
80 { "size", size_coder, size_decoder },
81 { "uid", uid_coder, uid_decoder },
82 { "uname", uname_coder, uname_decoder },
83 { NULL },
84 };
85
86 static struct xhdr_tab *
87 locate_handler (char *keyword)
88 {
89 struct xhdr_tab *p;
90
91 for (p = xhdr_tab; p->keyword; p++)
92 if (strcmp (p->keyword, keyword) == 0)
93 return p;
94 return NULL;
95 }
96
97 static int
98 decode_record (char **p, struct tar_stat_info *st)
99 {
100 size_t len;
101 char *keyword, *eqp;
102 char *start = *p;
103 struct xhdr_tab *t;
104
105 if (**p == 0)
106 return 1;
107
108 len = strtoul (*p, p, 10);
109 if (**p != ' ')
110 {
111 ERROR ((0, 0, _("Malformed extended headed")));
112 return 1;
113 }
114
115 keyword = ++*p;
116 for (;*p < start + len; ++*p)
117 if (**p == '=')
118 break;
119
120 if (**p != '=')
121 {
122 ERROR ((0, 0, _("Malformed extended headed")));
123 return 1;
124 }
125
126 eqp = *p;
127 **p = 0;
128 t = locate_handler (keyword);
129 if (t)
130 {
131 char endc;
132 char *value;
133
134 value = ++*p;
135
136 endc = start[len-1];
137 start[len-1] = 0;
138 t->decoder (st, keyword, value);
139 start[len-1] = endc;
140 }
141 *eqp = '=';
142 *p = &start[len];
143 return 0;
144 }
145
146 void
147 xheader_decode (struct tar_stat_info *st)
148 {
149 char *p, *endp;
150
151 p = extended_header.blocks->buffer;
152 endp = &extended_header.blocks[extended_header.nblocks-1].buffer
153 [sizeof(extended_header.blocks[0])-1];
154 while (p < endp)
155 if (decode_record (&p, st))
156 break;
157 }
158
159 void
160 xheader_read (union block *p, size_t size)
161 {
162 size_t i;
163
164 free (extended_header.blocks);
165 extended_header.nblocks = (size + BLOCKSIZE - 1) / BLOCKSIZE;
166 extended_header.blocks = xmalloc (sizeof (extended_header.blocks[0]) *
167 extended_header.nblocks);
168 set_next_block_after (p);
169 for (i = 0; i < extended_header.nblocks; i++)
170 {
171 p = find_next_block ();
172 memcpy (&extended_header.blocks[i], p, sizeof (p[0]));
173 set_next_block_after (p);
174 }
175 }
176
177 \f
178 /* Implementations */
179 static void
180 dummy_handler (struct tar_stat_info *st, char *keyword, char *arg)
181 {
182 }
183
184 static void
185 atime_coder (struct tar_stat_info *st, char *keyword, char *arg)
186 {
187 }
188
189 static void
190 atime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
191 {
192 st->stat.st_atime = strtoul (arg, NULL, 0);
193 }
194
195 static void
196 gid_coder (struct tar_stat_info *st, char *keyword, char *arg)
197 {
198 }
199
200 static void
201 gid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
202 {
203 st->stat.st_gid = strtoul (arg, NULL, 0);
204 }
205
206 static void
207 gname_coder (struct tar_stat_info *st, char *keyword, char *arg)
208 {
209 }
210
211 static void
212 gname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
213 {
214 st->gname = strdup (arg);
215 }
216
217 static void
218 linkpath_coder (struct tar_stat_info *st, char *keyword, char *arg)
219 {
220 }
221
222 static void
223 linkpath_decoder (struct tar_stat_info *st, char *keyword, char *arg)
224 {
225 st->link_name = strdup (arg);
226 }
227
228 static void
229 ctime_coder (struct tar_stat_info *st, char *keyword, char *arg)
230 {
231 }
232
233 static void
234 ctime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
235 {
236 st->stat.st_ctime = strtoul (arg, NULL, 0);
237 }
238
239 static void
240 mtime_coder (struct tar_stat_info *st, char *keyword, char *arg)
241 {
242 }
243
244 static void
245 mtime_decoder (struct tar_stat_info *st, char *keyword, char *arg)
246 {
247 st->stat.st_mtime = strtoul (arg, NULL, 0);
248 }
249
250 static void
251 path_coder (struct tar_stat_info *st, char *keyword, char *arg)
252 {
253 }
254
255 static void
256 path_decoder (struct tar_stat_info *st, char *keyword, char *arg)
257 {
258 assign_string (&st->orig_file_name, arg);
259 assign_string (&st->file_name, arg);
260 st->had_trailing_slash = strip_trailing_slashes (st->file_name);
261 }
262
263 static void
264 size_coder (struct tar_stat_info *st, char *keyword, char *arg)
265 {
266 }
267
268 static void
269 size_decoder (struct tar_stat_info *st, char *keyword, char *arg)
270 {
271 st->stat.st_size = strtoul (arg, NULL, 0);
272 }
273
274 static void
275 uid_coder (struct tar_stat_info *st, char *keyword, char *arg)
276 {
277 }
278
279 static void
280 uid_decoder (struct tar_stat_info *st, char *keyword, char *arg)
281 {
282 st->stat.st_uid = strtoul (arg, NULL, 0);
283 }
284
285 static void
286 uname_coder (struct tar_stat_info *st, char *keyword, char *arg)
287 {
288 }
289
290 static void
291 uname_decoder (struct tar_stat_info *st, char *keyword, char *arg)
292 {
293 st->uname = strdup (arg);
294 }
295
This page took 0.048266 seconds and 5 git commands to generate.