]> Dogcows Code - chaz/tar/blob - src/create.c
6e49b59be090b0e45c620e580248d3c8266f4c8d
[chaz/tar] / src / create.c
1 /* Create a tar archive.
2
3 Copyright (C) 1985, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4 2003 Free Software Foundation, Inc.
5
6 Written by John Gilmore, on 1985-08-25.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 #include "system.h"
23
24 #if HAVE_UTIME_H
25 # include <utime.h>
26 #else
27 struct utimbuf
28 {
29 long actime;
30 long modtime;
31 };
32 #endif
33
34 #include <quotearg.h>
35
36 #include "common.h"
37 #include <hash.h>
38
39 struct link
40 {
41 dev_t dev;
42 ino_t ino;
43 size_t nlink;
44 char name[1];
45 };
46 \f
47 /* The maximum uintmax_t value that can be represented with DIGITS digits,
48 assuming that each digit is BITS_PER_DIGIT wide. */
49 #define MAX_VAL_WITH_DIGITS(digits, bits_per_digit) \
50 ((digits) * (bits_per_digit) < sizeof (uintmax_t) * CHAR_BIT \
51 ? ((uintmax_t) 1 << ((digits) * (bits_per_digit))) - 1 \
52 : (uintmax_t) -1)
53
54 /* Convert VALUE to an octal representation suitable for tar headers.
55 Output to buffer WHERE with size SIZE.
56 The result is undefined if SIZE is 0 or if VALUE is too large to fit. */
57
58 static void
59 to_octal (uintmax_t value, char *where, size_t size)
60 {
61 uintmax_t v = value;
62 size_t i = size;
63
64 do
65 {
66 where[--i] = '0' + (v & ((1 << LG_8) - 1));
67 v >>= LG_8;
68 }
69 while (i);
70 }
71
72 /* Convert NEGATIVE VALUE to a base-256 representation suitable for
73 tar headers. NEGATIVE is 1 if VALUE was negative before being cast
74 to uintmax_t, 0 otherwise. Output to buffer WHERE with size SIZE.
75 The result is undefined if SIZE is 0 or if VALUE is too large to
76 fit. */
77
78 static void
79 to_base256 (int negative, uintmax_t value, char *where, size_t size)
80 {
81 uintmax_t v = value;
82 uintmax_t propagated_sign_bits =
83 ((uintmax_t) - negative << (CHAR_BIT * sizeof v - LG_256));
84 size_t i = size;
85
86 do
87 {
88 where[--i] = v & ((1 << LG_256) - 1);
89 v = propagated_sign_bits | (v >> LG_256);
90 }
91 while (i);
92 }
93
94 /* Convert NEGATIVE VALUE (which was originally of size VALSIZE) to
95 external form, using SUBSTITUTE (...) if VALUE won't fit. Output
96 to buffer WHERE with size SIZE. NEGATIVE is 1 iff VALUE was
97 negative before being cast to uintmax_t; its original bitpattern
98 can be deduced from VALSIZE, its original size before casting.
99 TYPE is the kind of value being output (useful for diagnostics).
100 Prefer the POSIX format of SIZE - 1 octal digits (with leading zero
101 digits), followed by '\0'. If this won't work, and if GNU or
102 OLDGNU format is allowed, use '\200' followed by base-256, or (if
103 NEGATIVE is nonzero) '\377' followed by two's complement base-256.
104 If neither format works, use SUBSTITUTE (...) instead. Pass to
105 SUBSTITUTE the address of an 0-or-1 flag recording whether the
106 substitute value is negative. */
107
108 static void
109 to_chars (int negative, uintmax_t value, size_t valsize,
110 uintmax_t (*substitute) (int *),
111 char *where, size_t size, const char *type)
112 {
113 int base256_allowed = (archive_format == GNU_FORMAT
114 || archive_format == OLDGNU_FORMAT);
115
116 /* Generate the POSIX octal representation if the number fits. */
117 if (! negative && value <= MAX_VAL_WITH_DIGITS (size - 1, LG_8))
118 {
119 where[size - 1] = '\0';
120 to_octal (value, where, size - 1);
121 }
122
123 /* Otherwise, generate the base-256 representation if we are
124 generating an old or new GNU format and if the number fits. */
125 else if (((negative ? -1 - value : value)
126 <= MAX_VAL_WITH_DIGITS (size - 1, LG_256))
127 && base256_allowed)
128 {
129 where[0] = negative ? -1 : 1 << (LG_256 - 1);
130 to_base256 (negative, value, where + 1, size - 1);
131 }
132
133 /* Otherwise, if the number is negative, and if it would not cause
134 ambiguity on this host by confusing positive with negative
135 values, then generate the POSIX octal representation of the value
136 modulo 2**(field bits). The resulting tar file is
137 machine-dependent, since it depends on the host word size. Yuck!
138 But this is the traditional behavior. */
139 else if (negative && valsize * CHAR_BIT <= (size - 1) * LG_8)
140 {
141 static int warned_once;
142 if (! warned_once)
143 {
144 warned_once = 1;
145 WARN ((0, 0, _("Generating negative octal headers")));
146 }
147 where[size - 1] = '\0';
148 to_octal (value & MAX_VAL_WITH_DIGITS (valsize * CHAR_BIT, 1),
149 where, size - 1);
150 }
151
152 /* Otherwise, output a substitute value if possible (with a
153 warning), and an error message if not. */
154 else
155 {
156 uintmax_t maxval = (base256_allowed
157 ? MAX_VAL_WITH_DIGITS (size - 1, LG_256)
158 : MAX_VAL_WITH_DIGITS (size - 1, LG_8));
159 char valbuf[UINTMAX_STRSIZE_BOUND + 1];
160 char maxbuf[UINTMAX_STRSIZE_BOUND];
161 char minbuf[UINTMAX_STRSIZE_BOUND + 1];
162 char const *minval_string;
163 char const *maxval_string = STRINGIFY_BIGINT (maxval, maxbuf);
164 char const *value_string;
165
166 if (base256_allowed)
167 {
168 uintmax_t m = maxval + 1 ? maxval + 1 : maxval / 2 + 1;
169 char *p = STRINGIFY_BIGINT (m, minbuf + 1);
170 *--p = '-';
171 minval_string = p;
172 }
173 else
174 minval_string = "0";
175
176 if (negative)
177 {
178 char *p = STRINGIFY_BIGINT (- value, valbuf + 1);
179 *--p = '-';
180 value_string = p;
181 }
182 else
183 value_string = STRINGIFY_BIGINT (value, valbuf);
184
185 if (substitute)
186 {
187 int negsub;
188 uintmax_t sub = substitute (&negsub) & maxval;
189 uintmax_t s = (negsub &= archive_format == GNU_FORMAT) ? - sub : sub;
190 char subbuf[UINTMAX_STRSIZE_BOUND + 1];
191 char *sub_string = STRINGIFY_BIGINT (s, subbuf + 1);
192 if (negsub)
193 *--sub_string = '-';
194 WARN ((0, 0, _("value %s out of %s range %s..%s; substituting %s"),
195 value_string, type, minval_string, maxval_string,
196 sub_string));
197 to_chars (negsub, s, valsize, 0, where, size, type);
198 }
199 else
200 ERROR ((0, 0, _("value %s out of %s range %s..%s"),
201 value_string, type, minval_string, maxval_string));
202 }
203 }
204
205 static uintmax_t
206 gid_substitute (int *negative)
207 {
208 gid_t r;
209 #ifdef GID_NOBODY
210 r = GID_NOBODY;
211 #else
212 static gid_t gid_nobody;
213 if (!gid_nobody && !gname_to_gid ("nobody", &gid_nobody))
214 gid_nobody = -2;
215 r = gid_nobody;
216 #endif
217 *negative = r < 0;
218 return r;
219 }
220
221 void
222 gid_to_chars (gid_t v, char *p, size_t s)
223 {
224 to_chars (v < 0, (uintmax_t) v, sizeof v, gid_substitute, p, s, "gid_t");
225 }
226
227 void
228 major_to_chars (major_t v, char *p, size_t s)
229 {
230 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "major_t");
231 }
232
233 void
234 minor_to_chars (minor_t v, char *p, size_t s)
235 {
236 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "minor_t");
237 }
238
239 void
240 mode_to_chars (mode_t v, char *p, size_t s)
241 {
242 /* In the common case where the internal and external mode bits are the same,
243 and we are not using POSIX or GNU format,
244 propagate all unknown bits to the external mode.
245 This matches historical practice.
246 Otherwise, just copy the bits we know about. */
247 int negative;
248 uintmax_t u;
249 if (S_ISUID == TSUID && S_ISGID == TSGID && S_ISVTX == TSVTX
250 && S_IRUSR == TUREAD && S_IWUSR == TUWRITE && S_IXUSR == TUEXEC
251 && S_IRGRP == TGREAD && S_IWGRP == TGWRITE && S_IXGRP == TGEXEC
252 && S_IROTH == TOREAD && S_IWOTH == TOWRITE && S_IXOTH == TOEXEC
253 && archive_format != POSIX_FORMAT
254 && archive_format != USTAR_FORMAT
255 && archive_format != GNU_FORMAT)
256 {
257 negative = v < 0;
258 u = v;
259 }
260 else
261 {
262 negative = 0;
263 u = ((v & S_ISUID ? TSUID : 0)
264 | (v & S_ISGID ? TSGID : 0)
265 | (v & S_ISVTX ? TSVTX : 0)
266 | (v & S_IRUSR ? TUREAD : 0)
267 | (v & S_IWUSR ? TUWRITE : 0)
268 | (v & S_IXUSR ? TUEXEC : 0)
269 | (v & S_IRGRP ? TGREAD : 0)
270 | (v & S_IWGRP ? TGWRITE : 0)
271 | (v & S_IXGRP ? TGEXEC : 0)
272 | (v & S_IROTH ? TOREAD : 0)
273 | (v & S_IWOTH ? TOWRITE : 0)
274 | (v & S_IXOTH ? TOEXEC : 0));
275 }
276 to_chars (negative, u, sizeof v, 0, p, s, "mode_t");
277 }
278
279 void
280 off_to_chars (off_t v, char *p, size_t s)
281 {
282 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
283 }
284
285 void
286 size_to_chars (size_t v, char *p, size_t s)
287 {
288 to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
289 }
290
291 void
292 time_to_chars (time_t v, char *p, size_t s)
293 {
294 to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "time_t");
295 }
296
297 static uintmax_t
298 uid_substitute (int *negative)
299 {
300 uid_t r;
301 #ifdef UID_NOBODY
302 r = UID_NOBODY;
303 #else
304 static uid_t uid_nobody;
305 if (!uid_nobody && !uname_to_uid ("nobody", &uid_nobody))
306 uid_nobody = -2;
307 r = uid_nobody;
308 #endif
309 *negative = r < 0;
310 return r;
311 }
312
313 void
314 uid_to_chars (uid_t v, char *p, size_t s)
315 {
316 to_chars (v < 0, (uintmax_t) v, sizeof v, uid_substitute, p, s, "uid_t");
317 }
318
319 void
320 uintmax_to_chars (uintmax_t v, char *p, size_t s)
321 {
322 to_chars (0, v, sizeof v, 0, p, s, "uintmax_t");
323 }
324
325 void
326 string_to_chars (char *str, char *p, size_t s)
327 {
328 strncpy (p, str, s);
329 p[s-1] = 0;
330 }
331
332 \f
333 /* A file is not dumpable if
334 a) it is empty *and* world-readable, or
335 b) current archive is /dev/null */
336
337 bool
338 file_dumpable_p (struct tar_stat_info *stat)
339 {
340 return !(dev_null_output
341 || (stat->archive_file_size == 0
342 && (stat->stat.st_mode & MODE_R) == MODE_R));
343 }
344
345 \f
346 /* Writing routines. */
347
348 /* Write the EOT block(s). Zero at least two blocks, through the end
349 of the record. Old tar, as previous versions of GNU tar, writes
350 garbage after two zeroed blocks. */
351 void
352 write_eot (void)
353 {
354 union block *pointer = find_next_block ();
355 memset (pointer->buffer, 0, BLOCKSIZE);
356 set_next_block_after (pointer);
357 pointer = find_next_block ();
358 memset (pointer->buffer, 0, available_space_after (pointer));
359 set_next_block_after (pointer);
360 }
361
362 /* Copy at most LEN bytes from SRC to DST. Terminate with NUL unless
363 SRC is LEN characters long */
364 static void
365 tar_copy_str (char *dst, const char *src, size_t len)
366 {
367 dst[len-1] = 0;
368 strncpy (dst, src, len);
369 }
370
371 /* Write a "private" header */
372 static union block *
373 start_private_header (const char *name, size_t size)
374 {
375 time_t t;
376 union block *header = find_next_block ();
377
378 memset (header->buffer, 0, sizeof (union block));
379
380 tar_copy_str (header->header.name, name, NAME_FIELD_SIZE);
381 OFF_TO_CHARS (size, header->header.size);
382
383 time (&t);
384 TIME_TO_CHARS (t, header->header.mtime);
385 MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
386 UID_TO_CHARS (getuid (), header->header.uid);
387 GID_TO_CHARS (getgid (), header->header.gid);
388 MAJOR_TO_CHARS (0, header->header.devmajor);
389 MAJOR_TO_CHARS (0, header->header.devminor);
390 strncpy (header->header.magic, TMAGIC, TMAGLEN);
391 strncpy (header->header.version, TVERSION, TVERSLEN);
392 return header;
393 }
394
395 /* Create a new header and store there at most NAME_FIELD_SIZE bytes of
396 the file name */
397
398 static union block *
399 write_short_name (struct tar_stat_info *st)
400 {
401 union block *header = find_next_block ();
402 memset (header->buffer, 0, sizeof (union block));
403 tar_copy_str (header->header.name, st->file_name, NAME_FIELD_SIZE);
404 return header;
405 }
406
407 /* Write a GNUTYPE_LONGLINK or GNUTYPE_LONGNAME block. */
408 static void
409 write_gnu_long_link (struct tar_stat_info *st, const char *p, char type)
410 {
411 size_t size = strlen (p) + 1;
412 size_t bufsize;
413 union block *header;
414
415 header = start_private_header ("././@LongLink", size);
416 strcpy (header->header.magic, OLDGNU_MAGIC);
417 header->header.typeflag = type;
418 finish_header (st, header, -1);
419
420 header = find_next_block ();
421
422 bufsize = available_space_after (header);
423
424 while (bufsize < size)
425 {
426 memcpy (header->buffer, p, bufsize);
427 p += bufsize;
428 size -= bufsize;
429 set_next_block_after (header + (bufsize - 1) / BLOCKSIZE);
430 header = find_next_block ();
431 bufsize = available_space_after (header);
432 }
433 memcpy (header->buffer, p, size);
434 memset (header->buffer + size, 0, bufsize - size);
435 set_next_block_after (header + (size - 1) / BLOCKSIZE);
436 }
437
438 static size_t
439 split_long_name (const char *name, size_t length)
440 {
441 size_t i;
442
443 if (length > PREFIX_FIELD_SIZE)
444 length = PREFIX_FIELD_SIZE+2;
445 for (i = length - 1; i > 0; i--)
446 if (ISSLASH (name[i]))
447 break;
448 return i;
449 }
450
451 static union block *
452 write_ustar_long_name (const char *name)
453 {
454 size_t length = strlen (name);
455 size_t i;
456 union block *header;
457
458 if (length > PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1)
459 {
460 WARN ((0, 0, _("%s: file name is too long (max %d); not dumped"),
461 quotearg_colon (name),
462 PREFIX_FIELD_SIZE + NAME_FIELD_SIZE + 1));
463 return NULL;
464 }
465
466 i = split_long_name (name, length);
467 if (i == 0 || length - i - 1 > NAME_FIELD_SIZE)
468 {
469 WARN ((0, 0,
470 _("%s: file name is too long (cannot be split); not dumped"),
471 quotearg_colon (name)));
472 return NULL;
473 }
474
475 header = find_next_block ();
476 memset (header->buffer, 0, sizeof (header->buffer));
477 memcpy (header->header.prefix, name, i);
478 memcpy (header->header.name, name + i + 1, length - i - 1);
479
480 return header;
481 }
482
483 /* Write a long link name, depending on the current archive format */
484 static void
485 write_long_link (struct tar_stat_info *st)
486 {
487 switch (archive_format)
488 {
489 case POSIX_FORMAT:
490 xheader_store ("linkpath", st, NULL);
491 break;
492
493 case V7_FORMAT: /* old V7 tar format */
494 case USTAR_FORMAT:
495 case STAR_FORMAT:
496 WARN ((0, 0,
497 _("%s: link name is too long; not dumped"),
498 quotearg_colon (st->link_name)));
499 break;
500
501 case OLDGNU_FORMAT:
502 case GNU_FORMAT:
503 write_gnu_long_link (st, st->link_name, GNUTYPE_LONGLINK);
504 break;
505
506 default:
507 abort(); /*FIXME*/
508 }
509 }
510
511 static union block *
512 write_long_name (struct tar_stat_info *st)
513 {
514 switch (archive_format)
515 {
516 case POSIX_FORMAT:
517 xheader_store ("path", st, NULL);
518 break;
519
520 case V7_FORMAT:
521 case USTAR_FORMAT:
522 case STAR_FORMAT:
523 return write_ustar_long_name (st->file_name);
524
525 case OLDGNU_FORMAT:
526 case GNU_FORMAT:
527 write_gnu_long_link (st, st->file_name, GNUTYPE_LONGNAME);
528 break;
529
530 default:
531 abort(); /*FIXME*/
532 }
533 return write_short_name (st);
534 }
535
536 static union block *
537 write_extended (struct tar_stat_info *st, union block *old_header, char type)
538 {
539 union block *header, hp;
540 size_t size;
541 char *p;
542
543 if (extended_header.buffer || extended_header.stk == NULL)
544 return old_header;
545
546 xheader_finish (&extended_header);
547 size = extended_header.size;
548
549 memcpy (hp.buffer, old_header, sizeof (hp));
550
551 header = start_private_header ("././@PaxHeader", size);
552 header->header.typeflag = type;
553
554 finish_header (st, header, -1);
555
556 p = extended_header.buffer;
557
558 do
559 {
560 size_t len;
561
562 header = find_next_block ();
563 len = BLOCKSIZE;
564 if (len > size)
565 len = size;
566 memcpy (header->buffer, p, len);
567 if (len < BLOCKSIZE)
568 memset (header->buffer + len, 0, BLOCKSIZE - len);
569 p += len;
570 size -= len;
571 set_next_block_after (header);
572 }
573 while (size > 0);
574
575 xheader_destroy (&extended_header);
576 header = find_next_block ();
577 memcpy (header, &hp.buffer, sizeof (hp.buffer));
578 return header;
579 }
580
581 static union block *
582 write_header_name (struct tar_stat_info *st)
583 {
584 if (NAME_FIELD_SIZE < strlen (st->file_name))
585 return write_long_name (st);
586 else
587 return write_short_name (st);
588 }
589
590 \f
591 /* Header handling. */
592
593 /* Make a header block for the file whose stat info is st,
594 and return its address. */
595
596 union block *
597 start_header (struct tar_stat_info *st)
598 {
599 union block *header;
600
601 header = write_header_name (st);
602 if (!header)
603 return NULL;
604
605 /* Override some stat fields, if requested to do so. */
606
607 if (owner_option != (uid_t) -1)
608 st->stat.st_uid = owner_option;
609 if (group_option != (gid_t) -1)
610 st->stat.st_gid = group_option;
611 if (mode_option)
612 st->stat.st_mode = ((st->stat.st_mode & ~MODE_ALL)
613 | mode_adjust (st->stat.st_mode, mode_option));
614
615 /* Paul Eggert tried the trivial test ($WRITER cf a b; $READER tvf a)
616 for a few tars and came up with the following interoperability
617 matrix:
618
619 WRITER
620 1 2 3 4 5 6 7 8 9 READER
621 . . . . . . . . . 1 = SunOS 4.2 tar
622 # . . # # . . # # 2 = NEC SVR4.0.2 tar
623 . . . # # . . # . 3 = Solaris 2.1 tar
624 . . . . . . . . . 4 = GNU tar 1.11.1
625 . . . . . . . . . 5 = HP-UX 8.07 tar
626 . . . . . . . . . 6 = Ultrix 4.1
627 . . . . . . . . . 7 = AIX 3.2
628 . . . . . . . . . 8 = Hitachi HI-UX 1.03
629 . . . . . . . . . 9 = Omron UNIOS-B 4.3BSD 1.60Beta
630
631 . = works
632 # = ``impossible file type''
633
634 The following mask for old archive removes the `#'s in column 4
635 above, thus making GNU tar both a universal donor and a universal
636 acceptor for Paul's test. */
637
638 if (archive_format == V7_FORMAT || archive_format == USTAR_FORMAT)
639 MODE_TO_CHARS (st->stat.st_mode & MODE_ALL, header->header.mode);
640 else
641 MODE_TO_CHARS (st->stat.st_mode, header->header.mode);
642
643 if (st->stat.st_uid > MAXOCTAL7 && archive_format == POSIX_FORMAT)
644 xheader_store ("uid", st, NULL);
645 else
646 UID_TO_CHARS (st->stat.st_uid, header->header.uid);
647
648 if (st->stat.st_gid > MAXOCTAL7 && archive_format == POSIX_FORMAT)
649 xheader_store ("gid", st, NULL);
650 else
651 GID_TO_CHARS (st->stat.st_gid, header->header.gid);
652
653 if (st->stat.st_size > MAXOCTAL11 && archive_format == POSIX_FORMAT)
654 xheader_store ("size", st, NULL);
655 else
656 OFF_TO_CHARS (st->stat.st_size, header->header.size);
657
658 TIME_TO_CHARS (st->stat.st_mtime, header->header.mtime);
659
660 /* FIXME */
661 if (S_ISCHR (st->stat.st_mode)
662 || S_ISBLK (st->stat.st_mode))
663 {
664 st->devmajor = major (st->stat.st_rdev);
665 st->devminor = minor (st->stat.st_rdev);
666
667 if (st->devmajor > MAXOCTAL7 && archive_format == POSIX_FORMAT)
668 xheader_store ("devmajor", st, NULL);
669 else
670 MAJOR_TO_CHARS (st->devmajor, header->header.devmajor);
671
672 if (st->devminor > MAXOCTAL7 && archive_format == POSIX_FORMAT)
673 xheader_store ("devminor", st, NULL);
674 else
675 MAJOR_TO_CHARS (st->devminor, header->header.devminor);
676 }
677 else
678 {
679 MAJOR_TO_CHARS (0, header->header.devmajor);
680 MINOR_TO_CHARS (0, header->header.devminor);
681 }
682
683 if (archive_format == POSIX_FORMAT)
684 {
685 xheader_store ("atime", st, NULL);
686 xheader_store ("ctime", st, NULL);
687 }
688 else if (incremental_option)
689 if (archive_format == OLDGNU_FORMAT)
690 {
691 TIME_TO_CHARS (st->stat.st_atime, header->oldgnu_header.atime);
692 TIME_TO_CHARS (st->stat.st_ctime, header->oldgnu_header.ctime);
693 }
694
695 header->header.typeflag = archive_format == V7_FORMAT ? AREGTYPE : REGTYPE;
696
697 switch (archive_format)
698 {
699 case V7_FORMAT:
700 break;
701
702 case OLDGNU_FORMAT:
703 case GNU_FORMAT: /*FIXME?*/
704 /* Overwrite header->header.magic and header.version in one blow. */
705 strcpy (header->header.magic, OLDGNU_MAGIC);
706 break;
707
708 case POSIX_FORMAT:
709 case USTAR_FORMAT:
710 strncpy (header->header.magic, TMAGIC, TMAGLEN);
711 strncpy (header->header.version, TVERSION, TVERSLEN);
712 break;
713
714 default:
715 abort ();
716 }
717
718 if (archive_format == V7_FORMAT || numeric_owner_option)
719 {
720 /* header->header.[ug]name are left as the empty string. */
721 }
722 else
723 {
724 uid_to_uname (st->stat.st_uid, &st->uname);
725 gid_to_gname (st->stat.st_gid, &st->gname);
726
727 if (archive_format == POSIX_FORMAT
728 && strlen (st->uname) > UNAME_FIELD_SIZE)
729 xheader_store ("uname", st, NULL);
730 else
731 UNAME_TO_CHARS (st->uname, header->header.uname);
732
733 if (archive_format == POSIX_FORMAT
734 && strlen (st->gname) > GNAME_FIELD_SIZE)
735 xheader_store ("gname", st, NULL);
736 else
737 GNAME_TO_CHARS (st->gname, header->header.gname);
738 }
739
740 return header;
741 }
742
743 /* Finish off a filled-in header block and write it out. We also
744 print the file name and/or full info if verbose is on. If BLOCK_ORDINAL
745 is not negative, is the block ordinal of the first record for this
746 file, which may be a preceding long name or long link record. */
747 void
748 finish_header (struct tar_stat_info *st,
749 union block *header, off_t block_ordinal)
750 {
751 size_t i;
752 int sum;
753 char *p;
754
755 /* Note: It is important to do this before the call to write_extended(),
756 so that the actual ustar header is printed */
757 if (verbose_option
758 && header->header.typeflag != GNUTYPE_LONGLINK
759 && header->header.typeflag != GNUTYPE_LONGNAME
760 && header->header.typeflag != XHDTYPE
761 && header->header.typeflag != XGLTYPE)
762 {
763 /* These globals are parameters to print_header, sigh. */
764
765 current_header = header;
766 current_format = archive_format;
767 print_header (st, block_ordinal);
768 }
769
770 header = write_extended (st, header, XHDTYPE);
771
772 memcpy (header->header.chksum, CHKBLANKS, sizeof header->header.chksum);
773
774 sum = 0;
775 p = header->buffer;
776 for (i = sizeof *header; i-- != 0; )
777 /* We can't use unsigned char here because of old compilers, e.g. V7. */
778 sum += 0xFF & *p++;
779
780 /* Fill in the checksum field. It's formatted differently from the
781 other fields: it has [6] digits, a null, then a space -- rather than
782 digits, then a null. We use to_chars.
783 The final space is already there, from
784 checksumming, and to_chars doesn't modify it.
785
786 This is a fast way to do:
787
788 sprintf(header->header.chksum, "%6o", sum); */
789
790 uintmax_to_chars ((uintmax_t) sum, header->header.chksum, 7);
791
792 set_next_block_after (header);
793 }
794 \f
795
796 void
797 pad_archive (off_t size_left)
798 {
799 union block *blk;
800 while (size_left > 0)
801 {
802 save_sizeleft = size_left;
803 blk = find_next_block ();
804 memset (blk->buffer, 0, BLOCKSIZE);
805 set_next_block_after (blk);
806 size_left -= BLOCKSIZE;
807 }
808 }
809
810 static enum dump_status
811 dump_regular_file (int fd, struct tar_stat_info *stat)
812 {
813 off_t size_left = stat->stat.st_size;
814 off_t block_ordinal;
815 union block *blk;
816
817 block_ordinal = current_block_ordinal ();
818 blk = start_header (stat);
819 if (!blk)
820 return dump_status_fail;
821
822 /* Mark contiguous files, if we support them. */
823 if (archive_format != V7_FORMAT && S_ISCTG (stat->stat.st_mode))
824 blk->header.typeflag = CONTTYPE;
825
826 finish_header (stat, blk, block_ordinal);
827
828 while (size_left > 0)
829 {
830 size_t bufsize, count;
831
832 if (multi_volume_option)
833 {
834 assign_string (&save_name, stat->file_name);
835 save_sizeleft = size_left;
836 save_totsize = stat->stat.st_size;
837 }
838 blk = find_next_block ();
839
840 bufsize = available_space_after (blk);
841
842 if (size_left < bufsize)
843 {
844 /* Last read -- zero out area beyond. */
845 bufsize = size_left;
846 count = bufsize % BLOCKSIZE;
847 if (count)
848 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
849 }
850
851 count = (fd < 0) ? bufsize : safe_read (fd, blk->buffer, bufsize);
852 if (count < 0)
853 {
854 read_diag_details (stat->orig_file_name,
855 stat->stat.st_size - size_left, bufsize);
856 pad_archive (size_left);
857 return dump_status_short;
858 }
859 size_left -= count;
860
861 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
862
863 if (count != bufsize)
864 {
865 char buf[UINTMAX_STRSIZE_BOUND];
866 memset (blk->buffer + count, 0, bufsize - count);
867 WARN ((0, 0,
868 ngettext ("%s: File shrank by %s byte; padding with zeros",
869 "%s: File shrank by %s bytes; padding with zeros",
870 size_left),
871 quotearg_colon (stat->orig_file_name),
872 STRINGIFY_BIGINT (size_left, buf)));
873 if (! ignore_failed_read_option)
874 exit_status = TAREXIT_FAILURE;
875 pad_archive (size_left);
876 return dump_status_short;
877 }
878 }
879 return dump_status_ok;
880 }
881
882 void
883 dump_regular_finish (int fd, struct tar_stat_info *st, time_t original_ctime)
884 {
885 if (fd >= 0)
886 {
887 struct stat final_stat;
888 if (fstat (fd, &final_stat) != 0)
889 {
890 stat_diag (st->orig_file_name);
891 }
892 else if (final_stat.st_ctime != original_ctime)
893 {
894 WARN ((0, 0, _("%s: file changed as we read it"),
895 quotearg_colon (st->orig_file_name)));
896 }
897 if (close (fd) != 0)
898 {
899 close_diag (st->orig_file_name);
900 }
901 }
902 if (remove_files_option)
903 {
904 if (unlink (st->orig_file_name) == -1)
905 unlink_error (st->orig_file_name);
906 }
907 }
908
909 void
910 dump_dir0 (char *directory,
911 struct tar_stat_info *stat, int top_level, dev_t parent_device)
912 {
913 dev_t our_device = stat->stat.st_dev;
914
915 if (!is_avoided_name (stat->orig_file_name))
916 {
917 union block *blk = NULL;
918 off_t block_ordinal = current_block_ordinal ();
919 stat->stat.st_size = 0; /* force 0 size on dir */
920
921 blk = start_header (stat);
922 if (!blk)
923 return;
924
925 if (incremental_option)
926 blk->header.typeflag = GNUTYPE_DUMPDIR;
927 else /* if (standard_option) */
928 blk->header.typeflag = DIRTYPE;
929
930 /* If we're gnudumping, we aren't done yet so don't close it. */
931
932 if (!incremental_option)
933 finish_header (stat, blk, block_ordinal);
934 else if (gnu_list_name->dir_contents)
935 {
936 off_t size_left;
937 off_t totsize;
938 size_t bufsize;
939 ssize_t count;
940 const char *buffer, *p_buffer;
941 off_t block_ordinal = current_block_ordinal ();
942
943 buffer = gnu_list_name->dir_contents; /* FOO */
944 totsize = 0;
945 if (buffer)
946 for (p_buffer = buffer; *p_buffer; )
947 {
948 size_t size = strlen (p_buffer) + 1;
949 totsize += size;
950 p_buffer += size;
951 }
952 totsize++;
953 OFF_TO_CHARS (totsize, blk->header.size);
954 finish_header (stat, blk, block_ordinal);
955 p_buffer = buffer;
956 size_left = totsize;
957 while (size_left > 0)
958 {
959 if (multi_volume_option)
960 {
961 assign_string (&save_name, stat->orig_file_name);
962 save_sizeleft = size_left;
963 save_totsize = totsize;
964 }
965 blk = find_next_block ();
966 bufsize = available_space_after (blk);
967 if (size_left < bufsize)
968 {
969 bufsize = size_left;
970 count = bufsize % BLOCKSIZE;
971 if (count)
972 memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
973 }
974 memcpy (blk->buffer, p_buffer, bufsize);
975 size_left -= bufsize;
976 p_buffer += bufsize;
977 set_next_block_after (blk + (bufsize - 1) / BLOCKSIZE);
978 }
979 if (multi_volume_option)
980 assign_string (&save_name, 0);
981 return;
982 }
983 }
984
985 if (!recursion_option)
986 return;
987
988 if (one_file_system_option
989 && !top_level
990 && parent_device != stat->stat.st_dev)
991 {
992 if (verbose_option)
993 WARN ((0, 0,
994 _("%s: file is on a different filesystem; not dumped"),
995 quotearg_colon (stat->orig_file_name)));
996 return;
997 }
998
999 {
1000 char const *entry;
1001 size_t entry_len;
1002 char *name_buf = strdup (stat->orig_file_name);
1003 size_t name_size = strlen (name_buf);
1004 size_t name_len = name_size;
1005
1006 /* Now output all the files in the directory. */
1007 /* FIXME: Should speed this up by cd-ing into the dir. */
1008
1009 for (entry = directory; (entry_len = strlen (entry)) != 0;
1010 entry += entry_len + 1)
1011 {
1012 if (name_size < name_len + entry_len)
1013 {
1014 name_size = name_len + entry_len;
1015 name_buf = xrealloc (name_buf, name_size + 1);
1016 }
1017 strcpy (name_buf + name_len, entry);
1018 if (!excluded_name (name_buf))
1019 dump_file (name_buf, 0, our_device);
1020 }
1021
1022 free (name_buf);
1023 }
1024 }
1025
1026 /* Ensure exactly one trailing slash. */
1027 static void
1028 ensure_slash (char **pstr)
1029 {
1030 size_t len = strlen (*pstr);
1031 while (len >= 1 && ISSLASH ((*pstr)[len - 1]))
1032 len--;
1033 if (!ISSLASH ((*pstr)[len]))
1034 *pstr = xrealloc (*pstr, len + 2);
1035 (*pstr)[len++] = '/';
1036 (*pstr)[len] = '\0';
1037 }
1038
1039 bool
1040 dump_dir (struct tar_stat_info *stat, int top_level, dev_t parent_device)
1041 {
1042 char *directory;
1043
1044 directory = savedir (stat->orig_file_name);
1045 if (!directory)
1046 {
1047 savedir_diag (stat->orig_file_name);
1048 return false;
1049 }
1050
1051 ensure_slash (&stat->orig_file_name);
1052 ensure_slash (&stat->file_name);
1053
1054 dump_dir0 (directory, stat, top_level, parent_device);
1055
1056 free (directory);
1057 return true;
1058 }
1059
1060 \f
1061 /* Main functions of this module. */
1062
1063 void
1064 create_archive (void)
1065 {
1066 char *p;
1067
1068 open_archive (ACCESS_WRITE);
1069
1070 if (incremental_option)
1071 {
1072 size_t buffer_size = 1000;
1073 char *buffer = xmalloc (buffer_size);
1074 const char *q;
1075
1076 collect_and_sort_names ();
1077
1078 while ((p = name_from_list ()) != NULL)
1079 if (!excluded_name (p))
1080 dump_file (p, -1, (dev_t) 0);
1081
1082 blank_name_list ();
1083 while ((p = name_from_list ()) != NULL)
1084 if (!excluded_name (p))
1085 {
1086 size_t plen = strlen (p);
1087 if (buffer_size <= plen)
1088 {
1089 while ((buffer_size *= 2) <= plen)
1090 continue;
1091 buffer = xrealloc (buffer, buffer_size);
1092 }
1093 memcpy (buffer, p, plen);
1094 if (! ISSLASH (buffer[plen - 1]))
1095 buffer[plen++] = '/';
1096 q = gnu_list_name->dir_contents;
1097 if (q)
1098 while (*q)
1099 {
1100 size_t qlen = strlen (q);
1101 if (*q == 'Y')
1102 {
1103 if (buffer_size < plen + qlen)
1104 {
1105 while ((buffer_size *=2 ) < plen + qlen)
1106 continue;
1107 buffer = xrealloc (buffer, buffer_size);
1108 }
1109 strcpy (buffer + plen, q + 1);
1110 dump_file (buffer, -1, (dev_t) 0);
1111 }
1112 q += qlen + 1;
1113 }
1114 }
1115 free (buffer);
1116 }
1117 else
1118 {
1119 while ((p = name_next (1)) != NULL)
1120 if (!excluded_name (p))
1121 dump_file (p, 1, (dev_t) 0);
1122 }
1123
1124 write_eot ();
1125 close_archive ();
1126
1127 if (listed_incremental_option)
1128 write_directory_file ();
1129 }
1130
1131
1132 /* Calculate the hash of a link. */
1133 static unsigned
1134 hash_link (void const *entry, unsigned n_buckets)
1135 {
1136 struct link const *link = entry;
1137 return (uintmax_t) (link->dev ^ link->ino) % n_buckets;
1138 }
1139
1140 /* Compare two links for equality. */
1141 static bool
1142 compare_links (void const *entry1, void const *entry2)
1143 {
1144 struct link const *link1 = entry1;
1145 struct link const *link2 = entry2;
1146 return ((link1->dev ^ link2->dev) | (link1->ino ^ link2->ino)) == 0;
1147 }
1148
1149 static void
1150 unknown_file_error (char *p)
1151 {
1152 WARN ((0, 0, _("%s: Unknown file type; file ignored"),
1153 quotearg_colon (p)));
1154 if (!ignore_failed_read_option)
1155 exit_status = TAREXIT_FAILURE;
1156 }
1157
1158 \f
1159 /* Handling of hard links */
1160
1161 /* Table of all non-directories that we've written so far. Any time
1162 we see another, we check the table and avoid dumping the data
1163 again if we've done it once already. */
1164 static Hash_table *link_table;
1165
1166 /* Try to dump stat as a hard link to another file in the archive. If
1167 succeeded returns true */
1168 static bool
1169 dump_hard_link (struct tar_stat_info *stat)
1170 {
1171 if (link_table && stat->stat.st_nlink > 1)
1172 {
1173 struct link lp;
1174 struct link *dup;
1175 off_t block_ordinal;
1176 union block *blk;
1177
1178 lp.ino = stat->stat.st_ino;
1179 lp.dev = stat->stat.st_dev;
1180
1181 if ((dup = hash_lookup (link_table, &lp)))
1182 {
1183 /* We found a link. */
1184 char const *link_name = safer_name_suffix (dup->name, 1);
1185
1186 dup->nlink--;
1187
1188 block_ordinal = current_block_ordinal ();
1189 assign_string (&stat->link_name, link_name);
1190 if (NAME_FIELD_SIZE < strlen (link_name))
1191 write_long_link (stat);
1192
1193 stat->stat.st_size = 0;
1194 blk = start_header (stat);
1195 if (!blk)
1196 return true;
1197 tar_copy_str (blk->header.linkname, link_name, NAME_FIELD_SIZE);
1198
1199 blk->header.typeflag = LNKTYPE;
1200 finish_header (stat, blk, block_ordinal);
1201
1202 if (remove_files_option && unlink (stat->orig_file_name) != 0)
1203 unlink_error (stat->orig_file_name);
1204
1205 return true;
1206 }
1207 }
1208 return false;
1209 }
1210
1211 static void
1212 file_count_links (struct tar_stat_info *stat)
1213 {
1214 if (stat->stat.st_nlink > 1)
1215 {
1216 struct link *dup;
1217 struct link *lp = xmalloc (offsetof (struct link, name)
1218 + strlen (stat->orig_file_name) + 1);
1219 lp->ino = stat->stat.st_ino;
1220 lp->dev = stat->stat.st_dev;
1221 lp->nlink = stat->stat.st_nlink;
1222 strcpy (lp->name, stat->orig_file_name);
1223
1224 if (! ((link_table
1225 || (link_table = hash_initialize (0, 0, hash_link,
1226 compare_links, 0)))
1227 && (dup = hash_insert (link_table, lp))))
1228 xalloc_die ();
1229
1230 if (dup != lp)
1231 abort ();
1232 lp->nlink--;
1233 }
1234 }
1235
1236 /* For each dumped file, check if all its links were dumped. Emit
1237 warnings if it is not so. */
1238 void
1239 check_links ()
1240 {
1241 struct link *lp;
1242
1243 if (!link_table)
1244 return;
1245
1246 for (lp = hash_get_first (link_table); lp;
1247 lp = hash_get_next (link_table, lp))
1248 {
1249 if (lp->nlink)
1250 {
1251 WARN ((0, 0, _("Missing links to '%s'.\n"), lp->name));
1252 }
1253 }
1254 }
1255
1256
1257 /* Dump a single file, recursing on directories. P is the file name
1258 to dump. TOP_LEVEL tells whether this is a top-level call; zero
1259 means no, positive means yes, and negative means the top level
1260 of an incremental dump. PARENT_DEVICE is the device of P's
1261 parent directory; it is examined only if TOP_LEVEL is zero. */
1262
1263 /* FIXME: One should make sure that for *every* path leading to setting
1264 exit_status to failure, a clear diagnostic has been issued. */
1265
1266 void
1267 dump_file0 (struct tar_stat_info *stat, char *p,
1268 int top_level, dev_t parent_device)
1269 {
1270 union block *header;
1271 char type;
1272 time_t original_ctime;
1273 struct utimbuf restore_times;
1274 off_t block_ordinal = -1;
1275
1276 if (interactive_option && !confirm ("add", p))
1277 return;
1278
1279 assign_string (&stat->orig_file_name, p);
1280 assign_string (&stat->file_name, safer_name_suffix (p, 0));
1281
1282 if (deref_stat (dereference_option, p, &stat->stat) != 0)
1283 {
1284 stat_diag (p);
1285 return;
1286 }
1287 stat->archive_file_size = stat->stat.st_size;
1288 sys_stat_nanoseconds(stat);
1289 original_ctime = stat->stat.st_ctime;
1290 restore_times.actime = stat->stat.st_atime;
1291 restore_times.modtime = stat->stat.st_mtime;
1292
1293 #ifdef S_ISHIDDEN
1294 if (S_ISHIDDEN (stat->stat.st_mode))
1295 {
1296 char *new = (char *) alloca (strlen (p) + 2);
1297 if (new)
1298 {
1299 strcpy (new, p);
1300 strcat (new, "@");
1301 p = new;
1302 }
1303 }
1304 #endif
1305
1306 /* See if we want only new files, and check if this one is too old to
1307 put in the archive. */
1308
1309 if ((0 < top_level || !incremental_option)
1310 && !S_ISDIR (stat->stat.st_mode)
1311 && stat->stat.st_mtime < newer_mtime_option
1312 && (!after_date_option || stat->stat.st_ctime < newer_ctime_option))
1313 {
1314 if (0 < top_level)
1315 WARN ((0, 0, _("%s: file is unchanged; not dumped"),
1316 quotearg_colon (p)));
1317 /* FIXME: recheck this return. */
1318 return;
1319 }
1320
1321 /* See if we are trying to dump the archive. */
1322 if (sys_file_is_archive (stat))
1323 {
1324 WARN ((0, 0, _("%s: file is the archive; not dumped"),
1325 quotearg_colon (p)));
1326 return;
1327 }
1328
1329 if (S_ISDIR (stat->stat.st_mode))
1330 {
1331 dump_dir (stat, top_level, parent_device);
1332 if (atime_preserve_option)
1333 utime (p, &restore_times);
1334 return;
1335 }
1336 else if (is_avoided_name (p))
1337 return;
1338 else
1339 {
1340 /* Check for multiple links. */
1341 if (dump_hard_link (stat))
1342 return;
1343
1344 /* This is not a link to a previously dumped file, so dump it. */
1345
1346 if (S_ISREG (stat->stat.st_mode)
1347 || S_ISCTG (stat->stat.st_mode))
1348 {
1349 int fd;
1350 enum dump_status status;
1351
1352 if (file_dumpable_p (stat))
1353 {
1354 fd = open (stat->orig_file_name,
1355 O_RDONLY | O_BINARY);
1356 if (fd < 0)
1357 {
1358 if (!top_level && errno == ENOENT)
1359 WARN ((0, 0, _("%s: File removed before we read it"),
1360 quotearg_colon (stat->orig_file_name)));
1361 else
1362 open_diag (stat->orig_file_name);
1363 return;
1364 }
1365 }
1366 else
1367 fd = -1;
1368
1369 if (sparse_option && sparse_file_p (stat))
1370 {
1371 status = sparse_dump_file (fd, stat);
1372 if (status == dump_status_not_implemented)
1373 status = dump_regular_file (fd, stat);
1374 }
1375 else
1376 status = dump_regular_file (fd, stat);
1377
1378 switch (status)
1379 {
1380 case dump_status_ok:
1381 if (multi_volume_option)
1382 assign_string (&save_name, 0);
1383 dump_regular_finish (fd, stat, original_ctime);
1384 break;
1385
1386 case dump_status_short:
1387 if (multi_volume_option)
1388 assign_string (&save_name, 0);
1389 close (fd);
1390 break;
1391
1392 case dump_status_fail:
1393 close (fd);
1394 return;
1395
1396 case dump_status_not_implemented:
1397 abort ();
1398 }
1399
1400 if (atime_preserve_option)
1401 utime (stat->orig_file_name, &restore_times);
1402 file_count_links (stat);
1403 return;
1404 }
1405 #ifdef HAVE_READLINK
1406 else if (S_ISLNK (stat->stat.st_mode))
1407 {
1408 char *buffer;
1409 int size;
1410 size_t linklen = stat->stat.st_size;
1411 if (linklen != stat->stat.st_size || linklen + 1 == 0)
1412 xalloc_die ();
1413 buffer = (char *) alloca (linklen + 1);
1414 size = readlink (p, buffer, linklen + 1);
1415 if (size < 0)
1416 {
1417 readlink_diag (p);
1418 return;
1419 }
1420 buffer[size] = '\0';
1421 assign_string (&stat->link_name, buffer);
1422 if (size > NAME_FIELD_SIZE)
1423 write_long_link (stat);
1424
1425 block_ordinal = current_block_ordinal ();
1426 stat->stat.st_size = 0; /* force 0 size on symlink */
1427 header = start_header (stat);
1428 if (!header)
1429 return;
1430 tar_copy_str (header->header.linkname, buffer, NAME_FIELD_SIZE);
1431 header->header.typeflag = SYMTYPE;
1432 finish_header (stat, header, block_ordinal);
1433 /* nothing more to do to it */
1434
1435 if (remove_files_option)
1436 {
1437 if (unlink (p) == -1)
1438 unlink_error (p);
1439 }
1440 file_count_links (stat);
1441 return;
1442 }
1443 #endif
1444 else if (S_ISCHR (stat->stat.st_mode))
1445 type = CHRTYPE;
1446 else if (S_ISBLK (stat->stat.st_mode))
1447 type = BLKTYPE;
1448 else if (S_ISFIFO (stat->stat.st_mode))
1449 type = FIFOTYPE;
1450 else if (S_ISSOCK (stat->stat.st_mode))
1451 {
1452 WARN ((0, 0, _("%s: socket ignored"), quotearg_colon (p)));
1453 return;
1454 }
1455 else if (S_ISDOOR (stat->stat.st_mode))
1456 {
1457 WARN ((0, 0, _("%s: door ignored"), quotearg_colon (p)));
1458 return;
1459 }
1460 else
1461 {
1462 unknown_file_error (p);
1463 return;
1464 }
1465 }
1466
1467 if (archive_format == V7_FORMAT)
1468 {
1469 unknown_file_error (p);
1470 return;
1471 }
1472
1473 block_ordinal = current_block_ordinal ();
1474 stat->stat.st_size = 0; /* force 0 size */
1475 header = start_header (stat);
1476 if (!header)
1477 return;
1478 header->header.typeflag = type;
1479
1480 if (type != FIFOTYPE)
1481 {
1482 MAJOR_TO_CHARS (major (stat->stat.st_rdev),
1483 header->header.devmajor);
1484 MINOR_TO_CHARS (minor (stat->stat.st_rdev),
1485 header->header.devminor);
1486 }
1487
1488 finish_header (stat, header, block_ordinal);
1489 if (remove_files_option)
1490 {
1491 if (unlink (p) == -1)
1492 unlink_error (p);
1493 }
1494 }
1495
1496 void
1497 dump_file (char *p, int top_level, dev_t parent_device)
1498 {
1499 struct tar_stat_info stat;
1500 tar_stat_init (&stat);
1501 dump_file0 (&stat, p, top_level, parent_device);
1502 tar_stat_destroy (&stat);
1503 }
This page took 0.105716 seconds and 3 git commands to generate.