1 /* tar.c - read in write tar headers for cpio
2 Copyright (C) 1992-2019 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public
15 License along with this program; if not, write to the Free
16 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301 USA. */
18
19 #include <system.h>
20
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include "filetypes.h"
25 #include "cpiohdr.h"
26 #include "dstring.h"
27 #include "extern.h"
28 #include <rmt.h>
29 #include "tarhdr.h"
30
31 /* Stash the tar linkname in static storage. */
32
33 static char *
stash_tar_linkname(char * linkname)34 stash_tar_linkname (char *linkname)
35 {
36 static char hold_tar_linkname[TARLINKNAMESIZE + 1];
37
38 strncpy (hold_tar_linkname, linkname, TARLINKNAMESIZE);
39 hold_tar_linkname[TARLINKNAMESIZE] = '\0';
40 return hold_tar_linkname;
41 }
42
43 /* Try to split a long file name into prefix and suffix parts separated
44 by a slash. Return the length of the prefix (not counting the slash). */
45
46 static size_t
split_long_name(const char * name,size_t length)47 split_long_name (const char *name, size_t length)
48 {
49 size_t i;
50
51 if (length > TARPREFIXSIZE)
52 length = TARPREFIXSIZE+2;
53 for (i = length - 1; i > 0; i--)
54 if (name[i] == '/')
55 break;
56 return i;
57 }
58
59 /* Stash the tar filename and optional prefix in static storage. */
60
61 static char *
stash_tar_filename(char * prefix,char * filename)62 stash_tar_filename (char *prefix, char *filename)
63 {
64 static char hold_tar_filename[TARNAMESIZE + TARPREFIXSIZE + 2];
65 if (prefix == NULL || *prefix == '\0')
66 {
67 strncpy (hold_tar_filename, filename, TARNAMESIZE);
68 hold_tar_filename[TARNAMESIZE] = '\0';
69 }
70 else
71 {
72 strncpy (hold_tar_filename, prefix, TARPREFIXSIZE);
73 hold_tar_filename[TARPREFIXSIZE] = '\0';
74 strcat (hold_tar_filename, "/");
75 strncat (hold_tar_filename, filename, TARNAMESIZE);
76 hold_tar_filename[TARPREFIXSIZE + TARNAMESIZE] = '\0';
77 }
78 return hold_tar_filename;
79 }
80
81 static int
to_oct_or_error(uintmax_t value,size_t digits,char * where,char const * field,char const * file)82 to_oct_or_error (uintmax_t value, size_t digits, char *where, char const *field,
83 char const *file)
84 {
85 if (to_ascii (where, value, digits, LG_8, true))
86 {
87 field_width_error (file, field, value, digits, true);
88 return 1;
89 }
90 return 0;
91 }
92
93
94 /* Compute and return a checksum for TAR_HDR,
95 counting the checksum bytes as if they were spaces. */
96
97 unsigned int
tar_checksum(struct tar_header * tar_hdr)98 tar_checksum (struct tar_header *tar_hdr)
99 {
100 unsigned int sum = 0;
101 char *p = (char *) tar_hdr;
102 char *q = p + TARRECORDSIZE;
103 int i;
104
105 while (p < tar_hdr->chksum)
106 sum += *p++ & 0xff;
107 for (i = 0; i < 8; ++i)
108 {
109 sum += ' ';
110 ++p;
111 }
112 while (p < q)
113 sum += *p++ & 0xff;
114 return sum;
115 }
116
117 #define TO_OCT(file_hdr, c_fld, digits, tar_hdr, tar_field) \
118 do \
119 { \
120 if (to_oct_or_error (file_hdr -> c_fld, \
121 digits, \
122 tar_hdr -> tar_field, \
123 #tar_field, \
124 file_hdr->c_name)) \
125 return 1; \
126 } \
127 while (0)
128
129 /* Write out header FILE_HDR, including the file name, to file
130 descriptor OUT_DES. */
131
132 int
write_out_tar_header(struct cpio_file_stat * file_hdr,int out_des)133 write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des)
134 {
135 int name_len;
136 union tar_record tar_rec;
137 struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
138
139 memset (&tar_rec, 0, sizeof tar_rec);
140
141 /* process_copy_out must ensure that file_hdr->c_name is short enough,
142 or we will lose here. */
143
144 name_len = strlen (file_hdr->c_name);
145 if (name_len <= TARNAMESIZE)
146 {
147 strncpy (tar_hdr->name, file_hdr->c_name, name_len);
148 }
149 else
150 {
151 /* Fit as much as we can into `name', the rest into `prefix'. */
152 int prefix_len = split_long_name (file_hdr->c_name, name_len);
153
154 strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len);
155 strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1,
156 name_len - prefix_len - 1);
157 }
158
159 /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal
160 digits */
161 TO_OCT (file_hdr, c_mode & MODE_ALL, 8, tar_hdr, mode);
162 TO_OCT (file_hdr, c_uid, 8, tar_hdr, uid);
163 TO_OCT (file_hdr, c_gid, 8, tar_hdr, gid);
164 TO_OCT (file_hdr, c_filesize, 12, tar_hdr, size);
165 TO_OCT (file_hdr, c_mtime, 12, tar_hdr, mtime);
166
167 switch (file_hdr->c_mode & CP_IFMT)
168 {
169 case CP_IFREG:
170 if (file_hdr->c_tar_linkname)
171 {
172 /* process_copy_out makes sure that c_tar_linkname is shorter
173 than TARLINKNAMESIZE. */
174 strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
175 TARLINKNAMESIZE);
176 tar_hdr->typeflag = LNKTYPE;
177 to_ascii (tar_hdr->size, 0, 12, LG_8, true);
178 }
179 else
180 tar_hdr->typeflag = REGTYPE;
181 break;
182 case CP_IFDIR:
183 tar_hdr->typeflag = DIRTYPE;
184 break;
185 case CP_IFCHR:
186 tar_hdr->typeflag = CHRTYPE;
187 break;
188 case CP_IFBLK:
189 tar_hdr->typeflag = BLKTYPE;
190 break;
191 #ifdef CP_IFIFO
192 case CP_IFIFO:
193 tar_hdr->typeflag = FIFOTYPE;
194 break;
195 #endif /* CP_IFIFO */
196 #ifdef CP_IFLNK
197 case CP_IFLNK:
198 tar_hdr->typeflag = SYMTYPE;
199 /* process_copy_out makes sure that c_tar_linkname is shorter
200 than TARLINKNAMESIZE. */
201 strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
202 TARLINKNAMESIZE);
203 to_ascii (tar_hdr->size, 0, 12, LG_8, true);
204 break;
205 #endif /* CP_IFLNK */
206 }
207
208 if (archive_format == arf_ustar)
209 {
210 char *name;
211
212 strncpy (tar_hdr->magic, TMAGIC, TMAGLEN);
213 strncpy (tar_hdr->version, TVERSION, TVERSLEN);
214
215 name = getuser (file_hdr->c_uid);
216 if (name)
217 strcpy (tar_hdr->uname, name);
218 name = getgroup (file_hdr->c_gid);
219 if (name)
220 strcpy (tar_hdr->gname, name);
221
222 TO_OCT (file_hdr, c_rdev_maj, 8, tar_hdr, devmajor);
223 TO_OCT (file_hdr, c_rdev_min, 8, tar_hdr, devminor);
224 }
225
226 to_ascii (tar_hdr->chksum, tar_checksum (tar_hdr), 8, LG_8, true);
227
228 tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
229
230 return 0;
231 }
232
233 /* Return nonzero iff all the bytes in BLOCK are NUL.
234 SIZE is the number of bytes to check in BLOCK; it must be a
235 multiple of sizeof (long). */
236
237 int
null_block(long * block,int size)238 null_block (long *block, int size)
239 {
240 register long *p = block;
241 register int i = size / sizeof (long);
242
243 while (i--)
244 if (*p++)
245 return 0;
246 return 1;
247 }
248
249 /* Read a tar header, including the file name, from file descriptor IN_DES
250 into FILE_HDR. */
251
252 void
read_in_tar_header(struct cpio_file_stat * file_hdr,int in_des)253 read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des)
254 {
255 long bytes_skipped = 0;
256 int warned = false;
257 union tar_record tar_rec;
258 struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
259 uid_t *uidp;
260 gid_t *gidp;
261
262 tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
263
264 /* Check for a block of 0's. */
265 if (null_block ((long *) &tar_rec, TARRECORDSIZE))
266 {
267 #if 0
268 /* Found one block of 512 0's. If the next block is also all 0's
269 then this is the end of the archive. If not, assume the
270 previous block was all corruption and continue reading
271 the archive. */
272 /* Commented out because GNU tar sometimes creates archives with
273 only one block of 0's at the end. This happened for the
274 cpio 2.0 distribution! */
275 tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
276 if (null_block ((long *) &tar_rec, TARRECORDSIZE))
277 #endif
278 {
279 cpio_set_c_name (file_hdr, CPIO_TRAILER_NAME);
280 return;
281 }
282 #if 0
283 bytes_skipped = TARRECORDSIZE;
284 #endif
285 }
286
287 while (1)
288 {
289 file_hdr->c_chksum = FROM_OCTAL (tar_hdr->chksum);
290
291 if (file_hdr->c_chksum != tar_checksum (tar_hdr))
292 {
293 /* If the checksum is bad, skip 1 byte and try again. When
294 we try again we do not look for an EOF record (all zeros),
295 because when we start skipping bytes in a corrupted archive
296 the chances are pretty good that we might stumble across
297 2 blocks of 512 zeros (that probably is not really the last
298 record) and it is better to miss the EOF and give the user
299 a "premature EOF" error than to give up too soon on a corrupted
300 archive. */
301 if (!warned)
302 {
303 error (0, 0, _("invalid header: checksum error"));
304 warned = true;
305 }
306 memmove (&tar_rec, ((char *) &tar_rec) + 1, TARRECORDSIZE - 1);
307 tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
308 ++bytes_skipped;
309 continue;
310 }
311
312 if (archive_format != arf_ustar)
313 cpio_set_c_name (file_hdr, stash_tar_filename (NULL, tar_hdr->name));
314 else
315 cpio_set_c_name (file_hdr, stash_tar_filename (tar_hdr->prefix,
316 tar_hdr->name));
317
318 file_hdr->c_nlink = 1;
319 file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode);
320 file_hdr->c_mode = file_hdr->c_mode & 07777;
321 /* Debian hack: This version of cpio uses the -n flag also to extract
322 tar archives using the numeric UID/GID instead of the user/group
323 names in /etc/passwd and /etc/groups. (98/10/15) -BEM */
324 if (archive_format == arf_ustar && !numeric_uid
325 && (uidp = getuidbyname (tar_hdr->uname)))
326 file_hdr->c_uid = *uidp;
327 else
328 file_hdr->c_uid = FROM_OCTAL (tar_hdr->uid);
329
330 if (archive_format == arf_ustar && !numeric_uid
331 && (gidp = getgidbyname (tar_hdr->gname)))
332 file_hdr->c_gid = *gidp;
333 else
334 file_hdr->c_gid = FROM_OCTAL (tar_hdr->gid);
335 file_hdr->c_filesize = FROM_OCTAL (tar_hdr->size);
336 file_hdr->c_mtime = FROM_OCTAL (tar_hdr->mtime);
337 file_hdr->c_rdev_maj = FROM_OCTAL (tar_hdr->devmajor);
338 file_hdr->c_rdev_min = FROM_OCTAL (tar_hdr->devminor);
339 file_hdr->c_tar_linkname = NULL;
340
341 switch (tar_hdr->typeflag)
342 {
343 case REGTYPE:
344 case CONTTYPE: /* For now, punt. */
345 default:
346 file_hdr->c_mode |= CP_IFREG;
347 break;
348 case DIRTYPE:
349 file_hdr->c_mode |= CP_IFDIR;
350 break;
351 case CHRTYPE:
352 file_hdr->c_mode |= CP_IFCHR;
353 /* If a POSIX tar header has a valid linkname it's always supposed
354 to set typeflag to be LNKTYPE. System V.4 tar seems to
355 be broken, and for device files with multiple links it
356 puts the name of the link into linkname, but leaves typeflag
357 as CHRTYPE, BLKTYPE, FIFOTYPE, etc. */
358 file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
359
360 /* Does POSIX say that the filesize must be 0 for devices? We
361 assume so, but HPUX's POSIX tar sets it to be 1 which causes
362 us problems (when reading an archive we assume we can always
363 skip to the next file by skipping filesize bytes). For
364 now at least, it's easier to clear filesize for devices,
365 rather than check everywhere we skip in copyin.c. */
366 file_hdr->c_filesize = 0;
367 break;
368 case BLKTYPE:
369 file_hdr->c_mode |= CP_IFBLK;
370 file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
371 file_hdr->c_filesize = 0;
372 break;
373 #ifdef CP_IFIFO
374 case FIFOTYPE:
375 file_hdr->c_mode |= CP_IFIFO;
376 file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
377 file_hdr->c_filesize = 0;
378 break;
379 #endif
380 case SYMTYPE:
381 #ifdef CP_IFLNK
382 file_hdr->c_mode |= CP_IFLNK;
383 file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
384 file_hdr->c_filesize = 0;
385 break;
386 /* Else fall through. */
387 #endif
388 case LNKTYPE:
389 file_hdr->c_mode |= CP_IFREG;
390 file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
391 file_hdr->c_filesize = 0;
392 break;
393
394 case AREGTYPE:
395 /* Old tar format; if the last char in filename is '/' then it is
396 a directory, otherwise it's a regular file. */
397 if (file_hdr->c_name[file_hdr->c_namesize - 1] == '/')
398 file_hdr->c_mode |= CP_IFDIR;
399 else
400 file_hdr->c_mode |= CP_IFREG;
401 break;
402 }
403 break;
404 }
405 if (bytes_skipped > 0)
406 warn_junk_bytes (bytes_skipped);
407 }
408
409 /* Return
410 2 if BUF is a valid POSIX tar header (the checksum is correct
411 and it has the "ustar" magic string),
412 1 if BUF is a valid old tar header (the checksum is correct),
413 0 otherwise. */
414
415 int
is_tar_header(char * buf)416 is_tar_header (char *buf)
417 {
418 struct tar_header *tar_hdr = (struct tar_header *) buf;
419 unsigned long chksum;
420
421 chksum = FROM_OCTAL (tar_hdr->chksum);
422
423 if (chksum != tar_checksum (tar_hdr))
424 return 0;
425
426 /* GNU tar 1.10 and previous set the magic field to be "ustar " instead
427 of "ustar\0". Only look at the first 5 characters of the magic
428 field so we can recognize old GNU tar ustar archives. */
429 if (!strncmp (tar_hdr->magic, TMAGIC, TMAGLEN - 1))
430 return 2;
431 return 1;
432 }
433
434 /* Return true if the filename is too long to fit in a tar header.
435 For old tar headers, if the filename's length is less than or equal
436 to 100 then it will fit, otherwise it will not. For POSIX tar headers,
437 if the filename's length is less than or equal to 100 then it
438 will definitely fit, and if it is greater than 256 then it
439 will definitely not fit. If the length is between 100 and 256,
440 then the filename will fit only if it is possible to break it
441 into a 155 character "prefix" and 100 character "name". There
442 must be a slash between the "prefix" and the "name", although
443 the slash is not stored or counted in either the "prefix" or
444 the "name", and there must be at least one character in both
445 the "prefix" and the "name". If it is not possible to break down
446 the filename like this then it will not fit. */
447
448 int
is_tar_filename_too_long(char * name)449 is_tar_filename_too_long (char *name)
450 {
451 int whole_name_len;
452 int prefix_name_len;
453
454 whole_name_len = strlen (name);
455 if (whole_name_len <= TARNAMESIZE)
456 return false;
457
458 if (archive_format != arf_ustar)
459 return true;
460
461 if (whole_name_len > TARNAMESIZE + TARPREFIXSIZE + 1)
462 return true;
463
464 /* See whether we can split up the name into acceptably-sized
465 `prefix' and `name' (`p') pieces. */
466 prefix_name_len = split_long_name (name, whole_name_len);
467
468 /* Interestingly, a name consisting of a slash followed by
469 TARNAMESIZE characters can't be stored, because the prefix
470 would be empty, and thus ignored. */
471 if (prefix_name_len == 0
472 || whole_name_len - prefix_name_len - 1 > TARNAMESIZE)
473 return true;
474
475 return false;
476 }
477