1 /* GNU dump extensions to tar.
2 
3    Copyright 1988-2021 Free Software Foundation, Inc.
4 
5    This file is part of GNU tar.
6 
7    GNU tar is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    GNU tar is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include <system.h>
21 #include <hash.h>
22 #include <quotearg.h>
23 #include "common.h"
24 
25 /* Incremental dump specialities.  */
26 
27 /* Which child files to save under a directory.  */
28 enum children
29   {
30     NO_CHILDREN,
31     CHANGED_CHILDREN,
32     ALL_CHILDREN
33   };
34 
35 #define DIRF_INIT     0x0001    /* directory structure is initialized
36 				   (procdir called at least once) */
37 #define DIRF_NFS      0x0002    /* directory is mounted on nfs */
38 #define DIRF_FOUND    0x0004    /* directory is found on fs */
39 #define DIRF_NEW      0x0008    /* directory is new (not found
40 				   in the previous dump) */
41 #define DIRF_RENAMED  0x0010    /* Last target in a chain of renames */
42 /* A directory which is renamed from another one is recognized by its
43    orig member, which is not-NULL.  This directory may eventually be
44    the source for another rename, in which case it will be pointed to by
45    the orig member of another directory structure.  The last directory
46    in such a chain of renames (the one which is not pointed to by any
47    other orig) is marked with the DIRF_RENAMED flag.  This marks a starting
48    point from which append_incremental_renames starts encoding renames for
49    this chain. */
50 
51 #define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
52 #define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
53 #define DIR_IS_FOUND(d) ((d)->flags & DIRF_FOUND)
54 /* #define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW) FIXME: not used */
55 #define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED)
56 
57 #define DIR_SET_FLAG(d,f) (d)->flags |= (f)
58 #define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
59 
60 struct dumpdir                 /* Dump directory listing */
61 {
62   char *contents;              /* Actual contents */
63   size_t total;                /* Total number of elements */
64   size_t elc;                  /* Number of D/N/Y elements. */
65   char **elv;                  /* Array of D/N/Y elements */
66 };
67 
68 /* Directory attributes.  */
69 struct directory
70   {
71     struct directory *next;
72     struct timespec mtime;      /* Modification time */
73     dev_t device_number;	/* device number for directory */
74     ino_t inode_number;		/* inode number for directory */
75     struct dumpdir *dump;       /* Directory contents */
76     struct dumpdir *idump;      /* Initial contents if the directory was
77 				   rescanned */
78     enum children children;     /* What to save under this directory */
79     unsigned flags;             /* See DIRF_ macros above */
80     struct directory *orig;     /* If the directory was renamed, points to
81 				   the original directory structure */
82     const char *tagfile;        /* Tag file, if the directory falls under
83 				   exclusion_tag_under */
84     char *caname;               /* canonical name */
85     char *name;	     	        /* file name of directory */
86   };
87 
88 static struct dumpdir *
dumpdir_create0(const char * contents,const char * cmask)89 dumpdir_create0 (const char *contents, const char *cmask)
90 {
91   struct dumpdir *dump;
92   size_t i, total, ctsize, len;
93   char *p;
94   const char *q;
95 
96   for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
97     {
98       len = strlen (q) + 1;
99       ctsize += len;
100       if (!cmask || strchr (cmask, *q))
101 	i++;
102     }
103   dump = xmalloc (sizeof (*dump) + ctsize);
104   dump->contents = (char*)(dump + 1);
105   memcpy (dump->contents, contents, ctsize);
106   dump->total = total;
107   dump->elc = i;
108   dump->elv = xcalloc (i + 1, sizeof (dump->elv[0]));
109 
110   for (i = 0, p = dump->contents; *p; p += strlen (p) + 1)
111     {
112       if (!cmask || strchr (cmask, *p))
113 	dump->elv[i++] = p + 1;
114     }
115   dump->elv[i] = NULL;
116   return dump;
117 }
118 
119 static struct dumpdir *
dumpdir_create(const char * contents)120 dumpdir_create (const char *contents)
121 {
122   return dumpdir_create0 (contents, "YND");
123 }
124 
125 static void
dumpdir_free(struct dumpdir * dump)126 dumpdir_free (struct dumpdir *dump)
127 {
128   free (dump->elv);
129   free (dump);
130 }
131 
132 static int
compare_dirnames(const void * first,const void * second)133 compare_dirnames (const void *first, const void *second)
134 {
135   char const *const *name1 = first;
136   char const *const *name2 = second;
137   return strcmp (*name1, *name2);
138 }
139 
140 /* Locate NAME in the dumpdir array DUMP.
141    Return pointer to the slot in DUMP->contents, or NULL if not found */
142 static char *
dumpdir_locate(struct dumpdir * dump,const char * name)143 dumpdir_locate (struct dumpdir *dump, const char *name)
144 {
145   char **ptr;
146   if (!dump)
147     return NULL;
148 
149   ptr = bsearch (&name, dump->elv, dump->elc, sizeof (dump->elv[0]),
150 		 compare_dirnames);
151   return ptr ? *ptr - 1: NULL;
152 }
153 
154 struct dumpdir_iter
155 {
156   struct dumpdir *dump; /* Dumpdir being iterated */
157   int all;              /* Iterate over all entries, not only D/N/Y */
158   size_t next;          /* Index of the next element */
159 };
160 
161 static char *
dumpdir_next(struct dumpdir_iter * itr)162 dumpdir_next (struct dumpdir_iter *itr)
163 {
164   size_t cur = itr->next;
165   char *ret = NULL;
166 
167   if (itr->all)
168     {
169       ret = itr->dump->contents + cur;
170       if (*ret == 0)
171 	return NULL;
172       itr->next += strlen (ret) + 1;
173     }
174   else if (cur < itr->dump->elc)
175     {
176       ret = itr->dump->elv[cur] - 1;
177       itr->next++;
178     }
179 
180   return ret;
181 }
182 
183 static char *
dumpdir_first(struct dumpdir * dump,int all,struct dumpdir_iter ** pitr)184 dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
185 {
186   struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
187   itr->dump = dump;
188   itr->all = all;
189   itr->next = 0;
190   *pitr = itr;
191   return dumpdir_next (itr);
192 }
193 
194 /* Return size in bytes of the dumpdir array P */
195 size_t
dumpdir_size(const char * p)196 dumpdir_size (const char *p)
197 {
198   size_t totsize = 0;
199 
200   while (*p)
201     {
202       size_t size = strlen (p) + 1;
203       totsize += size;
204       p += size;
205     }
206   return totsize + 1;
207 }
208 
209 
210 static struct directory *dirhead, *dirtail;
211 static Hash_table *directory_table;
212 static Hash_table *directory_meta_table;
213 
214 #if HAVE_ST_FSTYPE_STRING
215   static char const nfs_string[] = "nfs";
216 # define NFS_FILE_STAT(st) (strcmp ((st).st_fstype, nfs_string) == 0)
217 #else
218 # define ST_DEV_MSB(st) (~ (dev_t) 0 << (sizeof (st).st_dev * CHAR_BIT - 1))
219 # define NFS_FILE_STAT(st) (((st).st_dev & ST_DEV_MSB (st)) != 0)
220 #endif
221 
222 /* Calculate the hash of a directory.  */
223 static size_t
hash_directory_canonical_name(void const * entry,size_t n_buckets)224 hash_directory_canonical_name (void const *entry, size_t n_buckets)
225 {
226   struct directory const *directory = entry;
227   return hash_string (directory->caname, n_buckets);
228 }
229 
230 /* Compare two directories for equality of their names. */
231 static bool
compare_directory_canonical_names(void const * entry1,void const * entry2)232 compare_directory_canonical_names (void const *entry1, void const *entry2)
233 {
234   struct directory const *directory1 = entry1;
235   struct directory const *directory2 = entry2;
236   return strcmp (directory1->caname, directory2->caname) == 0;
237 }
238 
239 static size_t
hash_directory_meta(void const * entry,size_t n_buckets)240 hash_directory_meta (void const *entry, size_t n_buckets)
241 {
242   struct directory const *directory = entry;
243   /* FIXME: Work out a better algorytm */
244   return (directory->device_number + directory->inode_number) % n_buckets;
245 }
246 
247 /* Compare two directories for equality of their device and inode numbers. */
248 static bool
compare_directory_meta(void const * entry1,void const * entry2)249 compare_directory_meta (void const *entry1, void const *entry2)
250 {
251   struct directory const *directory1 = entry1;
252   struct directory const *directory2 = entry2;
253   return directory1->device_number == directory2->device_number
254             && directory1->inode_number == directory2->inode_number;
255 }
256 
257 /* Make a directory entry for given relative NAME and canonical name CANAME.
258    The latter is "stolen", i.e. the returned directory contains pointer to
259    it. */
260 static struct directory *
make_directory(const char * name,char * caname)261 make_directory (const char *name, char *caname)
262 {
263   size_t namelen = strlen (name);
264   struct directory *directory = xmalloc (sizeof (*directory));
265   directory->next = NULL;
266   directory->dump = directory->idump = NULL;
267   directory->orig = NULL;
268   directory->flags = false;
269   if (namelen > 1 && ISSLASH (name[namelen - 1]))
270     namelen--;
271   directory->name = xmalloc (namelen + 1);
272   memcpy (directory->name, name, namelen);
273   directory->name[namelen] = 0;
274   directory->caname = caname;
275   directory->tagfile = NULL;
276   return directory;
277 }
278 
279 static void
free_directory(struct directory * dir)280 free_directory (struct directory *dir)
281 {
282   free (dir->caname);
283   free (dir->name);
284   free (dir);
285 }
286 
287 static struct directory *
attach_directory(const char * name)288 attach_directory (const char *name)
289 {
290   char *cname = normalize_filename (chdir_current, name);
291   struct directory *dir = make_directory (name, cname);
292   if (dirtail)
293     dirtail->next = dir;
294   else
295     dirhead = dir;
296   dirtail = dir;
297   return dir;
298 }
299 
300 
301 static void
dirlist_replace_prefix(const char * pref,const char * repl)302 dirlist_replace_prefix (const char *pref, const char *repl)
303 {
304   struct directory *dp;
305   size_t pref_len = strlen (pref);
306   size_t repl_len = strlen (repl);
307   for (dp = dirhead; dp; dp = dp->next)
308     replace_prefix (&dp->name, pref, pref_len, repl, repl_len);
309 }
310 
311 void
clear_directory_table(void)312 clear_directory_table (void)
313 {
314   struct directory *dp;
315 
316   if (directory_table)
317     hash_clear (directory_table);
318   if (directory_meta_table)
319     hash_clear (directory_meta_table);
320   for (dp = dirhead; dp; )
321     {
322       struct directory *next = dp->next;
323       free_directory (dp);
324       dp = next;
325     }
326   dirhead = dirtail = NULL;
327 }
328 
329 /* Create and link a new directory entry for directory NAME, having a
330    device number DEV and an inode number INO, with NFS indicating
331    whether it is an NFS device and FOUND indicating whether we have
332    found that the directory exists.  */
333 static struct directory *
note_directory(char const * name,struct timespec mtime,dev_t dev,ino_t ino,bool nfs,bool found,const char * contents)334 note_directory (char const *name, struct timespec mtime,
335 		dev_t dev, ino_t ino, bool nfs, bool found,
336 		const char *contents)
337 {
338   struct directory *directory = attach_directory (name);
339 
340   directory->mtime = mtime;
341   directory->device_number = dev;
342   directory->inode_number = ino;
343   directory->children = CHANGED_CHILDREN;
344   if (nfs)
345     DIR_SET_FLAG (directory, DIRF_NFS);
346   if (found)
347     DIR_SET_FLAG (directory, DIRF_FOUND);
348   if (contents)
349     directory->dump = dumpdir_create (contents);
350   else
351     directory->dump = NULL;
352 
353   if (! ((directory_table
354 	  || (directory_table = hash_initialize (0, 0,
355 						 hash_directory_canonical_name,
356 						 compare_directory_canonical_names,
357 						 0)))
358 	 && hash_insert (directory_table, directory)))
359     xalloc_die ();
360 
361   if (! ((directory_meta_table
362 	  || (directory_meta_table = hash_initialize (0, 0,
363 						      hash_directory_meta,
364 						      compare_directory_meta,
365 						      0)))
366 	 && hash_insert (directory_meta_table, directory)))
367     xalloc_die ();
368 
369   return directory;
370 }
371 
372 /* Return a directory entry for a given file NAME, or zero if none found.  */
373 static struct directory *
find_directory(const char * name)374 find_directory (const char *name)
375 {
376   if (! directory_table)
377     return 0;
378   else
379     {
380       char *caname = normalize_filename (chdir_current, name);
381       struct directory *dir = make_directory (name, caname);
382       struct directory *ret = hash_lookup (directory_table, dir);
383       free_directory (dir);
384       return ret;
385     }
386 }
387 
388 #if 0
389 /* Remove directory entry for the given CANAME */
390 void
391 remove_directory (const char *caname)
392 {
393   struct directory *dir = make_directory (caname, xstrdup (caname));
394   struct directory *ret = hash_delete (directory_table, dir);
395   if (ret)
396     free_directory (ret);
397   free_directory (dir);
398 }
399 #endif
400 
401 /* If first OLD_PREFIX_LEN bytes of DIR->NAME name match OLD_PREFIX,
402    replace them with NEW_PREFIX. */
403 void
rebase_directory(struct directory * dir,const char * old_prefix,size_t old_prefix_len,const char * new_prefix,size_t new_prefix_len)404 rebase_directory (struct directory *dir,
405 		  const char *old_prefix, size_t old_prefix_len,
406 		  const char *new_prefix, size_t new_prefix_len)
407 {
408   replace_prefix (&dir->name, old_prefix, old_prefix_len,
409 		  new_prefix, new_prefix_len);
410 }
411 
412 /* Return a directory entry for a given combination of device and inode
413    numbers, or zero if none found.  */
414 static struct directory *
find_directory_meta(dev_t dev,ino_t ino)415 find_directory_meta (dev_t dev, ino_t ino)
416 {
417   if (! directory_meta_table)
418     return 0;
419   else
420     {
421       struct directory *dir = make_directory ("", NULL);
422       struct directory *ret;
423       dir->device_number = dev;
424       dir->inode_number = ino;
425       ret = hash_lookup (directory_meta_table, dir);
426       free_directory (dir);
427       return ret;
428     }
429 }
430 
431 void
update_parent_directory(struct tar_stat_info * parent)432 update_parent_directory (struct tar_stat_info *parent)
433 {
434   struct directory *directory = find_directory (parent->orig_file_name);
435   if (directory)
436     {
437       struct stat st;
438       if (fstat (parent->fd, &st) != 0)
439 	stat_diag (directory->name);
440       else
441 	directory->mtime = get_stat_mtime (&st);
442     }
443 }
444 
445 #define PD_FORCE_CHILDREN 0x10
446 #define PD_FORCE_INIT     0x20
447 #define PD_CHILDREN(f) ((f) & 3)
448 
449 static struct directory *
procdir(const char * name_buffer,struct tar_stat_info * st,int flag,char * entry)450 procdir (const char *name_buffer, struct tar_stat_info *st,
451 	 int flag,
452 	 char *entry)
453 {
454   struct directory *directory;
455   struct stat *stat_data = &st->stat;
456   bool nfs = NFS_FILE_STAT (*stat_data);
457   bool perhaps_renamed = false;
458 
459   if ((directory = find_directory (name_buffer)) != NULL)
460     {
461       if (DIR_IS_INITED (directory))
462 	{
463 	  if (flag & PD_FORCE_INIT)
464 	    {
465 	      assign_string (&directory->name, name_buffer);
466 	    }
467 	  else
468 	    {
469 	      *entry = 'N'; /* Avoid duplicating this directory */
470 	      return directory;
471 	    }
472 	}
473 
474       if (strcmp (directory->name, name_buffer))
475 	{
476 	  *entry = 'N';
477 	  return directory;
478 	}
479 
480       /* With NFS, the same file can have two different devices
481 	 if an NFS directory is mounted in multiple locations,
482 	 which is relatively common when automounting.
483 	 To avoid spurious incremental redumping of
484 	 directories, consider all NFS devices as equal,
485 	 relying on the i-node to establish differences.  */
486 
487       if (! ((!check_device_option
488 	      || (DIR_IS_NFS (directory) && nfs)
489 	      || directory->device_number == stat_data->st_dev)
490 	     && directory->inode_number == stat_data->st_ino))
491 	{
492 	  /* FIXME: find_directory_meta ignores nfs */
493 	  struct directory *d = find_directory_meta (stat_data->st_dev,
494 						     stat_data->st_ino);
495 	  if (d)
496 	    {
497 	      if (strcmp (d->name, name_buffer))
498 		{
499 		  WARNOPT (WARN_RENAME_DIRECTORY,
500 			   (0, 0,
501 			    _("%s: Directory has been renamed from %s"),
502 			    quotearg_colon (name_buffer),
503 			    quote_n (1, d->name)));
504 		  directory->orig = d;
505 		  DIR_SET_FLAG (directory, DIRF_RENAMED);
506 		  DIR_CLEAR_FLAG (d, DIRF_RENAMED);
507 		  dirlist_replace_prefix (d->name, name_buffer);
508 		}
509 	      directory->children = CHANGED_CHILDREN;
510 	    }
511 	  else
512 	    {
513 	      perhaps_renamed = true;
514 	      directory->children = ALL_CHILDREN;
515 	      directory->device_number = stat_data->st_dev;
516 	      directory->inode_number = stat_data->st_ino;
517 	    }
518 	  if (nfs)
519 	    DIR_SET_FLAG (directory, DIRF_NFS);
520 	}
521       else
522 	directory->children = CHANGED_CHILDREN;
523 
524       DIR_SET_FLAG (directory, DIRF_FOUND);
525     }
526   else
527     {
528       struct directory *d = find_directory_meta (stat_data->st_dev,
529 						 stat_data->st_ino);
530 
531       directory = note_directory (name_buffer,
532 				  get_stat_mtime (stat_data),
533 				  stat_data->st_dev,
534 				  stat_data->st_ino,
535 				  nfs,
536 				  true,
537 				  NULL);
538 
539       if (d)
540 	{
541 	  if (strcmp (d->name, name_buffer))
542 	    {
543 	      WARNOPT (WARN_RENAME_DIRECTORY,
544 		       (0, 0, _("%s: Directory has been renamed from %s"),
545 			quotearg_colon (name_buffer),
546 			quote_n (1, d->name)));
547 	      directory->orig = d;
548 	      DIR_SET_FLAG (directory, DIRF_RENAMED);
549 	      DIR_CLEAR_FLAG (d, DIRF_RENAMED);
550 	      dirlist_replace_prefix (d->name, name_buffer);
551 	    }
552 	  directory->children = CHANGED_CHILDREN;
553 	}
554       else
555 	{
556 	  DIR_SET_FLAG (directory, DIRF_NEW);
557 	  WARNOPT (WARN_NEW_DIRECTORY,
558 		   (0, 0, _("%s: Directory is new"),
559 		    quotearg_colon (name_buffer)));
560 	  directory->children =
561 	    (listed_incremental_option
562 	     || (OLDER_STAT_TIME (*stat_data, m)
563 		 || (after_date_option
564 		     && OLDER_STAT_TIME (*stat_data, c))))
565 	    ? ALL_CHILDREN
566 	    : CHANGED_CHILDREN;
567 	}
568     }
569 
570   if (one_file_system_option && st->parent
571       && stat_data->st_dev != st->parent->stat.st_dev)
572     {
573       WARNOPT (WARN_XDEV,
574 	       (0, 0,
575 		_("%s: directory is on a different filesystem; not dumped"),
576 		quotearg_colon (directory->name)));
577       directory->children = NO_CHILDREN;
578       /* If there is any dumpdir info in that directory, remove it */
579       if (directory->dump)
580 	{
581 	  dumpdir_free (directory->dump);
582 	  directory->dump = NULL;
583 	}
584       perhaps_renamed = false;
585     }
586 
587   else if (flag & PD_FORCE_CHILDREN)
588     {
589       directory->children = PD_CHILDREN(flag);
590       if (directory->children == NO_CHILDREN)
591 	*entry = 'N';
592     }
593 
594   if (perhaps_renamed)
595     WARNOPT (WARN_RENAME_DIRECTORY,
596 	     (0, 0, _("%s: Directory has been renamed"),
597 	      quotearg_colon (name_buffer)));
598 
599   DIR_SET_FLAG (directory, DIRF_INIT);
600 
601   if (directory->children != NO_CHILDREN)
602     {
603       const char *tag_file_name;
604 
605       switch (check_exclusion_tags (st, &tag_file_name))
606 	{
607 	case exclusion_tag_all:
608 	  /* This warning can be duplicated by code in dump_file0, but only
609 	     in case when the topmost directory being archived contains
610 	     an exclusion tag. */
611 	  exclusion_tag_warning (name_buffer, tag_file_name,
612 				 _("directory not dumped"));
613 	  *entry = 'N';
614 	  directory->children = NO_CHILDREN;
615 	  break;
616 
617 	case exclusion_tag_contents:
618 	  exclusion_tag_warning (name_buffer, tag_file_name,
619 				 _("contents not dumped"));
620 	  directory->children = NO_CHILDREN;
621 	  directory->tagfile = tag_file_name;
622 	  break;
623 
624 	case exclusion_tag_under:
625 	  exclusion_tag_warning (name_buffer, tag_file_name,
626 				 _("contents not dumped"));
627 	  directory->tagfile = tag_file_name;
628 	  break;
629 
630 	case exclusion_tag_none:
631 	  break;
632 	}
633     }
634 
635   return directory;
636 }
637 
638 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
639    build a new dumpdir template.
640 
641    DIR must be returned by a previous call to savedir().
642 
643    File names in DIRECTORY->dump->contents must be sorted
644    alphabetically.
645 
646    DIRECTORY->dump is replaced with the created template. Each entry is
647    prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
648 
649 static void
makedumpdir(struct directory * directory,const char * dir)650 makedumpdir (struct directory *directory, const char *dir)
651 {
652   size_t i,
653          dirsize,  /* Number of elements in DIR */
654          len;      /* Length of DIR, including terminating nul */
655   const char *p;
656   char const **array;
657   char *new_dump, *new_dump_ptr;
658   struct dumpdir *dump;
659 
660   if (directory->children == ALL_CHILDREN)
661     dump = NULL;
662   else if (directory->orig)
663     dump = directory->orig->idump ?
664            directory->orig->idump : directory->orig->dump;
665   else
666     dump = directory->dump;
667 
668   /* Count the size of DIR and the number of elements it contains */
669   dirsize = 0;
670   len = 0;
671   for (p = dir; *p; p += strlen (p) + 1, dirsize++)
672     len += strlen (p) + 2;
673   len++;
674 
675   /* Create a sorted directory listing */
676   array = xcalloc (dirsize, sizeof array[0]);
677   for (i = 0, p = dir; *p; p += strlen (p) + 1, i++)
678     array[i] = p;
679 
680   qsort (array, dirsize, sizeof (array[0]), compare_dirnames);
681 
682   /* Prepare space for new dumpdir */
683   new_dump = xmalloc (len);
684   new_dump_ptr = new_dump;
685 
686   /* Fill in the dumpdir template */
687   for (i = 0; i < dirsize; i++)
688     {
689       const char *loc = dumpdir_locate (dump, array[i]);
690       if (loc)
691 	{
692 	  if (directory->tagfile)
693 	    *new_dump_ptr = 'I';
694 	  else
695 	    *new_dump_ptr = ' ';
696 	  new_dump_ptr++;
697 	}
698       else if (directory->tagfile)
699 	*new_dump_ptr++ = 'I';
700       else
701 	*new_dump_ptr++ = 'Y'; /* New entry */
702 
703       /* Copy the file name */
704       for (p = array[i]; (*new_dump_ptr++ = *p++); )
705 	;
706     }
707   *new_dump_ptr = 0;
708   directory->idump = directory->dump;
709   directory->dump = dumpdir_create0 (new_dump, NULL);
710   free (new_dump);
711   free (array);
712 }
713 
714 /* Create a dumpdir containing only one entry: that for the
715    tagfile. */
716 static void
maketagdumpdir(struct directory * directory)717 maketagdumpdir (struct directory *directory)
718 {
719   size_t len = strlen (directory->tagfile) + 1;
720   char *new_dump = xmalloc (len + 2);
721   new_dump[0] = 'Y';
722   memcpy (new_dump + 1, directory->tagfile, len);
723   new_dump[len + 1] = 0;
724 
725   directory->idump = directory->dump;
726   directory->dump = dumpdir_create0 (new_dump, NULL);
727   free (new_dump);
728 }
729 
730 /* Recursively scan the directory identified by ST.  */
731 struct directory *
scan_directory(struct tar_stat_info * st)732 scan_directory (struct tar_stat_info *st)
733 {
734   char const *dir = st->orig_file_name;
735   char *dirp = get_directory_entries (st);
736   dev_t device = st->stat.st_dev;
737   bool cmdline = ! st->parent;
738   namebuf_t nbuf;
739   char *tmp;
740   struct directory *directory;
741   char ch;
742 
743   if (! dirp)
744     savedir_error (dir);
745 
746   info_attach_exclist (st);
747 
748   tmp = xstrdup (dir);
749   zap_slashes (tmp);
750 
751   directory = procdir (tmp, st,
752 		       (cmdline ? PD_FORCE_INIT : 0),
753 		       &ch);
754 
755   free (tmp);
756 
757   nbuf = namebuf_create (dir);
758 
759   if (dirp)
760     {
761       if (directory->children != NO_CHILDREN)
762 	{
763 	  char *entry;	/* directory entry being scanned */
764 	  struct dumpdir_iter *itr;
765 
766 	  makedumpdir (directory, dirp);
767 
768 	  for (entry = dumpdir_first (directory->dump, 1, &itr);
769 	       entry;
770 	       entry = dumpdir_next (itr))
771 	    {
772 	      char *full_name = namebuf_name (nbuf, entry + 1);
773 
774 	      if (*entry == 'I') /* Ignored entry */
775 		*entry = 'N';
776 	      else if (excluded_name (full_name, st))
777 		*entry = 'N';
778 	      else
779 		{
780 		  int fd = st->fd;
781 		  void (*diag) (char const *) = 0;
782 		  struct tar_stat_info stsub;
783 		  tar_stat_init (&stsub);
784 
785 		  if (fd < 0)
786 		    {
787 		      errno = - fd;
788 		      diag = open_diag;
789 		    }
790 		  else if (fstatat (fd, entry + 1, &stsub.stat,
791 				    fstatat_flags) != 0)
792 		    diag = stat_diag;
793 		  else if (S_ISDIR (stsub.stat.st_mode))
794 		    {
795 		      int subfd = subfile_open (st, entry + 1,
796 						open_read_flags);
797 		      if (subfd < 0)
798 			diag = open_diag;
799 		      else
800 			{
801 			  stsub.fd = subfd;
802 			  if (fstat (subfd, &stsub.stat) != 0)
803 			    diag = stat_diag;
804 			}
805 		    }
806 
807 		  if (diag)
808 		    {
809 		      file_removed_diag (full_name, false, diag);
810 		      *entry = 'N';
811 		    }
812 		  else if (S_ISDIR (stsub.stat.st_mode))
813 		    {
814 		      int pd_flag = 0;
815 		      if (!recursion_option)
816 			pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
817 		      else if (directory->children == ALL_CHILDREN)
818 			pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
819 		      *entry = 'D';
820 
821 		      stsub.parent = st;
822 		      procdir (full_name, &stsub, pd_flag, entry);
823 		      restore_parent_fd (&stsub);
824 		    }
825 		  else if (one_file_system_option &&
826 			   device != stsub.stat.st_dev)
827 		    *entry = 'N';
828 		  else if (*entry == 'Y')
829 		    /* New entry, skip further checks */;
830 		  /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
831 		  else if (OLDER_STAT_TIME (stsub.stat, m)
832 			   && (!after_date_option
833 			       || OLDER_STAT_TIME (stsub.stat, c)))
834 		    *entry = 'N';
835 		  else
836 		    *entry = 'Y';
837 
838 		  tar_stat_destroy (&stsub);
839 		}
840 	    }
841 	  free (itr);
842 	}
843       else if (directory->tagfile)
844 	maketagdumpdir (directory);
845     }
846 
847   namebuf_free (nbuf);
848 
849   free (dirp);
850 
851   return directory;
852 }
853 
854 /* Return pointer to the contents of the directory DIR */
855 const char *
directory_contents(struct directory * dir)856 directory_contents (struct directory *dir)
857 {
858   if (!dir)
859     return NULL;
860   return dir->dump ? dir->dump->contents : NULL;
861 }
862 
863 /* A "safe" version of directory_contents, which never returns NULL. */
864 const char *
safe_directory_contents(struct directory * dir)865 safe_directory_contents (struct directory *dir)
866 {
867   const char *ret = directory_contents (dir);
868   return ret ? ret : "\0\0\0\0";
869 }
870 
871 
872 static void
obstack_code_rename(struct obstack * stk,char const * from,char const * to)873 obstack_code_rename (struct obstack *stk, char const *from, char const *to)
874 {
875   char const *s;
876 
877   s = from[0] == 0 ? from :
878                      safer_name_suffix (from, false, absolute_names_option);
879   obstack_1grow (stk, 'R');
880   obstack_grow (stk, s, strlen (s) + 1);
881 
882   s = to[0] == 0 ? to:
883                    safer_name_suffix (to, false, absolute_names_option);
884   obstack_1grow (stk, 'T');
885   obstack_grow (stk, s, strlen (s) + 1);
886 }
887 
888 static void
store_rename(struct directory * dir,struct obstack * stk)889 store_rename (struct directory *dir, struct obstack *stk)
890 {
891   struct directory *prev, *p;
892 
893   /* Detect eventual cycles. If the chain forms a cycle, prev points to
894      the entry DIR is renamed from.*/
895   for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
896     ;
897 
898   if (prev == NULL)
899     {
900       for (p = dir; p && p->orig; p = p->orig)
901 	obstack_code_rename (stk, p->orig->name, p->name);
902     }
903   else
904     {
905       char *temp_name;
906 
907       /* Break the cycle by using a temporary name for one of its
908 	 elements.
909 	 First, create a temp name stub entry. */
910       temp_name = dir_name (dir->name);
911       obstack_1grow (stk, 'X');
912       obstack_grow (stk, temp_name, strlen (temp_name) + 1);
913 
914       obstack_code_rename (stk, dir->name, "");
915 
916       for (p = dir; p != prev; p = p->orig)
917 	obstack_code_rename (stk, p->orig->name, p->name);
918 
919       obstack_code_rename (stk, "", prev->name);
920       free (temp_name);
921     }
922 }
923 
924 void
append_incremental_renames(struct directory * dir)925 append_incremental_renames (struct directory *dir)
926 {
927   struct obstack stk;
928   size_t size;
929   struct directory *dp;
930   const char *dump;
931 
932   if (dirhead == NULL)
933     return;
934 
935   obstack_init (&stk);
936   dump = directory_contents (dir);
937   if (dump)
938     {
939       size = dumpdir_size (dump) - 1;
940       obstack_grow (&stk, dump, size);
941     }
942   else
943     size = 0;
944 
945   for (dp = dirhead; dp; dp = dp->next)
946     if (DIR_IS_RENAMED (dp))
947       store_rename (dp, &stk);
948 
949   /* FIXME: Is this the right thing to do when DIR is null?  */
950   if (dir && obstack_object_size (&stk) != size)
951     {
952       obstack_1grow (&stk, 0);
953       dumpdir_free (dir->dump);
954       dir->dump = dumpdir_create (obstack_finish (&stk));
955     }
956   obstack_free (&stk, NULL);
957 }
958 
959 
960 
961 static FILE *listed_incremental_stream;
962 
963 /* Version of incremental format snapshots (directory files) used by this
964    tar. Currently it is supposed to be a single decimal number. 0 means
965    incremental snapshots as per tar version before 1.15.2.
966 
967    The current tar version supports incremental versions from
968    0 up to TAR_INCREMENTAL_VERSION, inclusive.
969    It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
970 
971 #define TAR_INCREMENTAL_VERSION 2
972 
973 /* Read incremental snapshot formats 0 and 1 */
974 static void
read_incr_db_01(int version,const char * initbuf)975 read_incr_db_01 (int version, const char *initbuf)
976 {
977   int n;
978   uintmax_t u;
979   char *buf = NULL;
980   size_t bufsize = 0;
981   char *ebuf;
982   long lineno = 1;
983 
984   if (version == 1)
985     {
986       if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
987 	{
988 	  read_error (listed_incremental_option);
989 	  free (buf);
990 	  return;
991 	}
992       ++lineno;
993     }
994   else
995     {
996       buf = strdup (initbuf);
997       bufsize = strlen (buf) + 1;
998     }
999 
1000   newer_mtime_option = decode_timespec (buf, &ebuf, false);
1001 
1002   if (! valid_timespec (newer_mtime_option))
1003     FATAL_ERROR ((0, errno, "%s:%ld: %s",
1004 		  quotearg_colon (listed_incremental_option),
1005 		  lineno,
1006 		  _("Invalid time stamp")));
1007   else
1008     {
1009       if (version == 1 && *ebuf)
1010 	{
1011 	  char const *buf_ns = ebuf + 1;
1012 	  errno = 0;
1013 	  u = strtoumax (buf_ns, &ebuf, 10);
1014 	  if (!errno && BILLION <= u)
1015 	    errno = ERANGE;
1016 	  if (errno || buf_ns == ebuf)
1017 	    {
1018 	      ERROR ((0, errno, "%s:%ld: %s",
1019 		      quotearg_colon (listed_incremental_option),
1020 		      lineno,
1021 		      _("Invalid time stamp")));
1022 	      newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
1023 	      newer_mtime_option.tv_nsec = -1;
1024 	    }
1025 	  else
1026 	    newer_mtime_option.tv_nsec = u;
1027 	}
1028     }
1029 
1030   while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
1031     {
1032       dev_t dev;
1033       ino_t ino;
1034       bool nfs = buf[0] == '+';
1035       char *strp = buf + nfs;
1036       struct timespec mtime;
1037 
1038       lineno++;
1039 
1040       if (buf[n - 1] == '\n')
1041 	buf[n - 1] = '\0';
1042 
1043       if (version == 1)
1044 	{
1045 	  mtime = decode_timespec (strp, &ebuf, false);
1046 	  strp = ebuf;
1047 	  if (!valid_timespec (mtime) || *strp != ' ')
1048 	    FATAL_ERROR ((0, errno, "%s:%ld: %s",
1049 			  quotearg_colon (listed_incremental_option), lineno,
1050 			  _("Invalid modification time")));
1051 
1052 	  errno = 0;
1053 	  u = strtoumax (strp, &ebuf, 10);
1054 	  if (!errno && BILLION <= u)
1055 	    errno = ERANGE;
1056 	  if (errno || strp == ebuf || *ebuf != ' ')
1057 	    {
1058 	      FATAL_ERROR ((0, errno, "%s:%ld: %s",
1059 			    quotearg_colon (listed_incremental_option), lineno,
1060 			    _("Invalid modification time (nanoseconds)")));
1061 	      mtime.tv_nsec = -1;
1062 	    }
1063 	  else
1064 	    mtime.tv_nsec = u;
1065 	  strp = ebuf;
1066 	}
1067       else
1068 	mtime.tv_sec = mtime.tv_nsec = 0;
1069 
1070       dev = strtosysint (strp, &ebuf,
1071 			 TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t));
1072       strp = ebuf;
1073       if (errno || *strp != ' ')
1074 	FATAL_ERROR ((0, errno, "%s:%ld: %s",
1075 		quotearg_colon (listed_incremental_option), lineno,
1076 		      _("Invalid device number")));
1077 
1078       ino = strtosysint (strp, &ebuf,
1079 			 TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t));
1080       strp = ebuf;
1081       if (errno || *strp != ' ')
1082 	FATAL_ERROR ((0, errno, "%s:%ld: %s",
1083 		      quotearg_colon (listed_incremental_option), lineno,
1084 		      _("Invalid inode number")));
1085 
1086       strp++;
1087       unquote_string (strp);
1088       note_directory (strp, mtime, dev, ino, nfs, false, NULL);
1089     }
1090   free (buf);
1091 }
1092 
1093 /* Read a nul-terminated string from FP and store it in STK.
1094    Store the number of bytes read (including nul terminator) in PCOUNT.
1095 
1096    Return the last character read or EOF on end of file. */
1097 static int
read_obstack(FILE * fp,struct obstack * stk,size_t * pcount)1098 read_obstack (FILE *fp, struct obstack *stk, size_t *pcount)
1099 {
1100   int c;
1101   size_t i;
1102 
1103   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
1104     obstack_1grow (stk, c);
1105   obstack_1grow (stk, 0);
1106 
1107   *pcount = i;
1108   return c;
1109 }
1110 
1111 /* Read from file FP a null-terminated string and convert it to an
1112    integer.  FIELDNAME is the intended use of the integer, useful for
1113    diagnostics.  MIN_VAL and MAX_VAL are its minimum and maximum
1114    permissible values; MIN_VAL must be nonpositive and MAX_VAL positive.
1115    Store into *PVAL the resulting value, converted to intmax_t.
1116 
1117    Throw a fatal error if the string cannot be converted or if the
1118    converted value is out of range.
1119 
1120    Return true if successful, false if end of file.  */
1121 
1122 static bool
read_num(FILE * fp,char const * fieldname,intmax_t min_val,uintmax_t max_val,intmax_t * pval)1123 read_num (FILE *fp, char const *fieldname,
1124 	  intmax_t min_val, uintmax_t max_val, intmax_t *pval)
1125 {
1126   int i;
1127   char buf[INT_BUFSIZE_BOUND (intmax_t)];
1128   char offbuf[INT_BUFSIZE_BOUND (off_t)];
1129   char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
1130   char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
1131   int conversion_errno;
1132   int c = getc (fp);
1133   bool negative = c == '-';
1134 
1135   for (i = 0; (i == 0 && negative) || ISDIGIT (c); i++)
1136     {
1137       buf[i] = c;
1138       if (i == sizeof buf - 1)
1139 	FATAL_ERROR ((0, 0,
1140 		      _("%s: byte %s: %s %.*s... too long"),
1141 		      quotearg_colon (listed_incremental_option),
1142 		      offtostr (ftello (fp), offbuf),
1143 		      fieldname, i + 1, buf));
1144       c = getc (fp);
1145     }
1146 
1147   buf[i] = 0;
1148 
1149   if (c < 0)
1150     {
1151       if (ferror (fp))
1152 	read_fatal (listed_incremental_option);
1153       if (i != 0)
1154 	FATAL_ERROR ((0, 0, "%s: %s",
1155 		      quotearg_colon (listed_incremental_option),
1156 		      _("Unexpected EOF in snapshot file")));
1157       return false;
1158     }
1159 
1160   if (c)
1161     {
1162       unsigned uc = c;
1163       FATAL_ERROR ((0, 0,
1164 		    _("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
1165 		    quotearg_colon (listed_incremental_option),
1166 		    offtostr (ftello (fp), offbuf),
1167 		    fieldname, buf, uc));
1168     }
1169 
1170   *pval = strtosysint (buf, NULL, min_val, max_val);
1171   conversion_errno = errno;
1172 
1173   switch (conversion_errno)
1174     {
1175     case ERANGE:
1176       FATAL_ERROR ((0, conversion_errno,
1177 		    _("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
1178 		    quotearg_colon (listed_incremental_option),
1179 		    offtostr (ftello (fp), offbuf),
1180 		    imaxtostr (min_val, minbuf),
1181 		    umaxtostr (max_val, maxbuf), fieldname, buf));
1182     default:
1183       FATAL_ERROR ((0, conversion_errno,
1184 		    _("%s: byte %s: %s %s"),
1185 		    quotearg_colon (listed_incremental_option),
1186 		    offtostr (ftello (fp), offbuf), fieldname, buf));
1187     case 0:
1188       break;
1189     }
1190 
1191   return true;
1192 }
1193 
1194 /* Read from FP two NUL-terminated strings representing a struct
1195    timespec.  Return the resulting value in PVAL.
1196 
1197    Throw a fatal error if the string cannot be converted.  */
1198 
1199 static void
read_timespec(FILE * fp,struct timespec * pval)1200 read_timespec (FILE *fp, struct timespec *pval)
1201 {
1202   intmax_t s, ns;
1203 
1204   if (read_num (fp, "sec", TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t), &s)
1205       && read_num (fp, "nsec", 0, BILLION - 1, &ns))
1206     {
1207       pval->tv_sec = s;
1208       pval->tv_nsec = ns;
1209     }
1210   else
1211     {
1212       FATAL_ERROR ((0, 0, "%s: %s",
1213 		    quotearg_colon (listed_incremental_option),
1214 		    _("Unexpected EOF in snapshot file")));
1215     }
1216 }
1217 
1218 /* Read incremental snapshot format 2 */
1219 static void
read_incr_db_2(void)1220 read_incr_db_2 (void)
1221 {
1222   struct obstack stk;
1223   char offbuf[INT_BUFSIZE_BOUND (off_t)];
1224 
1225   obstack_init (&stk);
1226 
1227   read_timespec (listed_incremental_stream, &newer_mtime_option);
1228 
1229   for (;;)
1230     {
1231       intmax_t i;
1232       struct timespec mtime;
1233       dev_t dev;
1234       ino_t ino;
1235       bool nfs;
1236       char *name;
1237       char *content;
1238       size_t s;
1239 
1240       if (! read_num (listed_incremental_stream, "nfs", 0, 1, &i))
1241 	return; /* Normal return */
1242 
1243       nfs = i;
1244 
1245       read_timespec (listed_incremental_stream, &mtime);
1246 
1247       if (! read_num (listed_incremental_stream, "dev",
1248 		      TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), &i))
1249 	break;
1250       dev = i;
1251 
1252       if (! read_num (listed_incremental_stream, "ino",
1253 		      TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), &i))
1254 	break;
1255       ino = i;
1256 
1257       if (read_obstack (listed_incremental_stream, &stk, &s))
1258 	break;
1259 
1260       name = obstack_finish (&stk);
1261 
1262       while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1)
1263 	;
1264       if (getc (listed_incremental_stream) != 0)
1265 	FATAL_ERROR ((0, 0, _("%s: byte %s: %s"),
1266 		      quotearg_colon (listed_incremental_option),
1267 		      offtostr (ftello (listed_incremental_stream), offbuf),
1268 		      _("Missing record terminator")));
1269 
1270       content = obstack_finish (&stk);
1271       note_directory (name, mtime, dev, ino, nfs, false, content);
1272       obstack_free (&stk, content);
1273     }
1274   FATAL_ERROR ((0, 0, "%s: %s",
1275 		quotearg_colon (listed_incremental_option),
1276 		_("Unexpected EOF in snapshot file")));
1277 }
1278 
1279 /* Display (to stdout) the range of allowed values for each field
1280    in the snapshot file.  The array below should be kept in sync
1281    with any changes made to the read_num() calls in the parsing
1282    loop inside read_incr_db_2().
1283 
1284    (This function is invoked via the --show-snapshot-field-ranges
1285    command line option.) */
1286 
1287 struct field_range
1288 {
1289   char const *fieldname;
1290   intmax_t min_val;
1291   uintmax_t max_val;
1292 };
1293 
1294 static struct field_range const field_ranges[] = {
1295   { "nfs", 0, 1 },
1296   { "timestamp_sec", TYPE_MINIMUM (time_t), TYPE_MAXIMUM (time_t) },
1297   { "timestamp_nsec", 0, BILLION - 1 },
1298   { "dev", TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t) },
1299   { "ino", TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t) },
1300   { NULL, 0, 0 }
1301 };
1302 
1303 void
show_snapshot_field_ranges(void)1304 show_snapshot_field_ranges (void)
1305 {
1306   struct field_range const *p;
1307   char minbuf[SYSINT_BUFSIZE];
1308   char maxbuf[SYSINT_BUFSIZE];
1309 
1310   printf("This tar's snapshot file field ranges are\n");
1311   printf ("   (%-15s => [ %s, %s ]):\n\n", "field name", "min", "max");
1312 
1313   for (p=field_ranges; p->fieldname != NULL; p++)
1314     {
1315       printf ("    %-15s => [ %s, %s ],\n", p->fieldname,
1316 	      sysinttostr (p->min_val, p->min_val, p->max_val, minbuf),
1317 	      sysinttostr (p->max_val, p->min_val, p->max_val, maxbuf));
1318 
1319     }
1320 
1321   printf("\n");
1322 }
1323 
1324 /* Read incremental snapshot file (directory file).
1325    If the file has older incremental version, make sure that it is processed
1326    correctly and that tar will use the most conservative backup method among
1327    possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
1328    etc.) This ensures that the snapshots are updated to the recent version
1329    without any loss of data. */
1330 void
read_directory_file(void)1331 read_directory_file (void)
1332 {
1333   int fd;
1334   char *buf = NULL;
1335   size_t bufsize = 0;
1336   int flags = O_RDWR | O_CREAT;
1337 
1338   if (incremental_level == 0)
1339     flags |= O_TRUNC;
1340   /* Open the file for both read and write.  That way, we can write
1341      it later without having to reopen it, and don't have to worry if
1342      we chdir in the meantime.  */
1343   fd = open (listed_incremental_option, flags, MODE_RW);
1344   if (fd < 0)
1345     {
1346       open_error (listed_incremental_option);
1347       return;
1348     }
1349 
1350   listed_incremental_stream = fdopen (fd, "r+");
1351   if (! listed_incremental_stream)
1352     {
1353       open_error (listed_incremental_option);
1354       close (fd);
1355       return;
1356     }
1357 
1358   /* Consume the first name from the name list and reset the
1359      list afterwards.  This is done to change to the new
1360      directory, if the first name is a chdir request (-C dir),
1361      which is necessary to recreate absolute file names. */
1362   name_from_list ();
1363   blank_name_list ();
1364 
1365   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
1366     {
1367       char *ebuf;
1368       uintmax_t incremental_version;
1369 
1370       if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0)
1371 	{
1372 	  ebuf = buf + sizeof PACKAGE_NAME - 1;
1373 	  if (*ebuf++ != '-')
1374 	    ERROR((1, 0, _("Bad incremental file format")));
1375 	  for (; *ebuf != '-'; ebuf++)
1376 	    if (!*ebuf)
1377 	      ERROR((1, 0, _("Bad incremental file format")));
1378 
1379 	  incremental_version = strtoumax (ebuf + 1, NULL, 10);
1380 	}
1381       else
1382 	incremental_version = 0;
1383 
1384       switch (incremental_version)
1385 	{
1386 	case 0:
1387 	case 1:
1388 	  read_incr_db_01 (incremental_version, buf);
1389 	  break;
1390 
1391 	case TAR_INCREMENTAL_VERSION:
1392 	  read_incr_db_2 ();
1393 	  break;
1394 
1395 	default:
1396 	  ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX),
1397 		  incremental_version));
1398 	}
1399 
1400     }
1401 
1402   if (ferror (listed_incremental_stream))
1403     read_error (listed_incremental_option);
1404   free (buf);
1405 }
1406 
1407 /* Output incremental data for the directory ENTRY to the file DATA.
1408    Return nonzero if successful, preserving errno on write failure.  */
1409 static bool
write_directory_file_entry(void * entry,void * data)1410 write_directory_file_entry (void *entry, void *data)
1411 {
1412   struct directory const *directory = entry;
1413   FILE *fp = data;
1414 
1415   if (DIR_IS_FOUND (directory))
1416     {
1417       char buf[SYSINT_BUFSIZE];
1418       char const *s;
1419 
1420       s = DIR_IS_NFS (directory) ? "1" : "0";
1421       fwrite (s, 2, 1, fp);
1422       s = sysinttostr (directory->mtime.tv_sec, TYPE_MINIMUM (time_t),
1423 		       TYPE_MAXIMUM (time_t), buf);
1424       fwrite (s, strlen (s) + 1, 1, fp);
1425       s = imaxtostr (directory->mtime.tv_nsec, buf);
1426       fwrite (s, strlen (s) + 1, 1, fp);
1427       s = sysinttostr (directory->device_number,
1428 		       TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
1429       fwrite (s, strlen (s) + 1, 1, fp);
1430       s = sysinttostr (directory->inode_number,
1431 		       TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
1432       fwrite (s, strlen (s) + 1, 1, fp);
1433 
1434       fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
1435       if (directory->dump)
1436 	{
1437 	  const char *p;
1438 	  struct dumpdir_iter *itr;
1439 
1440 	  for (p = dumpdir_first (directory->dump, 0, &itr);
1441 	       p;
1442 	       p = dumpdir_next (itr))
1443 	    fwrite (p, strlen (p) + 1, 1, fp);
1444 	  free (itr);
1445 	}
1446       fwrite ("\0\0", 2, 1, fp);
1447     }
1448 
1449   return ! ferror (fp);
1450 }
1451 
1452 void
write_directory_file(void)1453 write_directory_file (void)
1454 {
1455   FILE *fp = listed_incremental_stream;
1456   char buf[UINTMAX_STRSIZE_BOUND];
1457   char *s;
1458 
1459   if (! fp)
1460     return;
1461 
1462   if (fseeko (fp, 0L, SEEK_SET) != 0)
1463     seek_error (listed_incremental_option);
1464   if (sys_truncate (fileno (fp)) != 0)
1465     truncate_error (listed_incremental_option);
1466 
1467   fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
1468 	   TAR_INCREMENTAL_VERSION);
1469 
1470   s = (TYPE_SIGNED (time_t)
1471        ? imaxtostr (start_time.tv_sec, buf)
1472        : umaxtostr (start_time.tv_sec, buf));
1473   fwrite (s, strlen (s) + 1, 1, fp);
1474   s = umaxtostr (start_time.tv_nsec, buf);
1475   fwrite (s, strlen (s) + 1, 1, fp);
1476 
1477   if (! ferror (fp) && directory_table)
1478     hash_do_for_each (directory_table, write_directory_file_entry, fp);
1479 
1480   if (ferror (fp))
1481     write_error (listed_incremental_option);
1482   if (fclose (fp) != 0)
1483     close_error (listed_incremental_option);
1484 }
1485 
1486 
1487 /* Restoration of incremental dumps.  */
1488 
1489 static void
get_gnu_dumpdir(struct tar_stat_info * stat_info)1490 get_gnu_dumpdir (struct tar_stat_info *stat_info)
1491 {
1492   size_t size;
1493   size_t copied;
1494   union block *data_block;
1495   char *to;
1496   char *archive_dir;
1497 
1498   size = stat_info->stat.st_size;
1499 
1500   archive_dir = xmalloc (size);
1501   to = archive_dir;
1502 
1503   set_next_block_after (current_header);
1504   mv_begin_read (stat_info);
1505 
1506   for (; size > 0; size -= copied)
1507     {
1508       mv_size_left (size);
1509       data_block = find_next_block ();
1510       if (!data_block)
1511 	ERROR ((1, 0, _("Unexpected EOF in archive")));
1512       copied = available_space_after (data_block);
1513       if (copied > size)
1514 	copied = size;
1515       memcpy (to, data_block->buffer, copied);
1516       to += copied;
1517       set_next_block_after ((union block *)
1518 			    (data_block->buffer + copied - 1));
1519     }
1520 
1521   mv_end ();
1522 
1523   stat_info->dumpdir = archive_dir;
1524   stat_info->skipped = true; /* For skip_member() and friends
1525 				to work correctly */
1526 }
1527 
1528 /* Return T if STAT_INFO represents a dumpdir archive member.
1529    Note: can invalidate current_header. It happens if flush_archive()
1530    gets called within get_gnu_dumpdir() */
1531 bool
is_dumpdir(struct tar_stat_info * stat_info)1532 is_dumpdir (struct tar_stat_info *stat_info)
1533 {
1534   if (stat_info->is_dumpdir && !stat_info->dumpdir)
1535     get_gnu_dumpdir (stat_info);
1536   return stat_info->is_dumpdir;
1537 }
1538 
1539 static bool
dumpdir_ok(char * dumpdir)1540 dumpdir_ok (char *dumpdir)
1541 {
1542   char *p;
1543   int has_tempdir = 0;
1544   int expect = 0;
1545 
1546   for (p = dumpdir; *p; p += strlen (p) + 1)
1547     {
1548       if (expect && *p != expect)
1549 	{
1550 	  unsigned char uc = *p;
1551 	  ERROR ((0, 0,
1552 		  _("Malformed dumpdir: expected '%c' but found %#3o"),
1553 		  expect, uc));
1554 	  return false;
1555 	}
1556       switch (*p)
1557 	{
1558 	case 'X':
1559 	  if (has_tempdir)
1560 	    {
1561 	      ERROR ((0, 0,
1562 		      _("Malformed dumpdir: 'X' duplicated")));
1563 	      return false;
1564 	    }
1565 	  else
1566 	    has_tempdir = 1;
1567 	  break;
1568 
1569 	case 'R':
1570 	  if (p[1] == 0)
1571 	    {
1572 	      if (!has_tempdir)
1573 		{
1574 		  ERROR ((0, 0,
1575 			  _("Malformed dumpdir: empty name in 'R'")));
1576 		  return false;
1577 		}
1578 	      else
1579 		has_tempdir = 0;
1580 	    }
1581 	  expect = 'T';
1582 	  break;
1583 
1584 	case 'T':
1585 	  if (expect != 'T')
1586 	    {
1587 	      ERROR ((0, 0,
1588 		      _("Malformed dumpdir: 'T' not preceded by 'R'")));
1589 	      return false;
1590 	    }
1591 	  if (p[1] == 0 && !has_tempdir)
1592 	    {
1593 	      ERROR ((0, 0,
1594 		      _("Malformed dumpdir: empty name in 'T'")));
1595 	      return false;
1596 	    }
1597 	  expect = 0;
1598 	  break;
1599 
1600 	case 'N':
1601 	case 'Y':
1602 	case 'D':
1603 	  break;
1604 
1605 	default:
1606 	  /* FIXME: bail out? */
1607 	  break;
1608 	}
1609     }
1610 
1611   if (expect)
1612     {
1613       ERROR ((0, 0,
1614 	      _("Malformed dumpdir: expected '%c' but found end of data"),
1615 	      expect));
1616       return false;
1617     }
1618 
1619   if (has_tempdir)
1620     WARNOPT (WARN_BAD_DUMPDIR,
1621 	     (0, 0, _("Malformed dumpdir: 'X' never used")));
1622 
1623   return true;
1624 }
1625 
1626 /* Examine the directories under directory_name and delete any
1627    files that were not there at the time of the back-up. */
1628 static bool
try_purge_directory(char const * directory_name)1629 try_purge_directory (char const *directory_name)
1630 {
1631   char *current_dir;
1632   char *cur, *arc, *p;
1633   char *temp_stub = NULL;
1634   struct dumpdir *dump;
1635 
1636   if (!is_dumpdir (&current_stat_info))
1637     return false;
1638 
1639   current_dir = tar_savedir (directory_name, 0);
1640 
1641   if (!current_dir)
1642     /* The directory doesn't exist now.  It'll be created.  In any
1643        case, we don't have to delete any files out of it.  */
1644     return false;
1645 
1646   /* Verify if dump directory is sane */
1647   if (!dumpdir_ok (current_stat_info.dumpdir))
1648     return false;
1649 
1650   /* Process renames */
1651   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
1652     {
1653       if (*arc == 'X')
1654 	{
1655 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1656 	  size_t len = strlen (arc + 1);
1657 	  temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
1658 	  memcpy (temp_stub, arc + 1, len);
1659 	  temp_stub[len] = '/';
1660 	  memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
1661 		  sizeof TEMP_DIR_TEMPLATE);
1662 	  if (!mkdtemp (temp_stub))
1663 	    {
1664 	      ERROR ((0, errno,
1665 		      _("Cannot create temporary directory using template %s"),
1666 		      quote (temp_stub)));
1667 	      free (temp_stub);
1668 	      free (current_dir);
1669 	      return false;
1670 	    }
1671 	}
1672       else if (*arc == 'R')
1673 	{
1674 	  char *src, *dst;
1675 	  src = arc + 1;
1676 	  arc += strlen (arc) + 1;
1677 	  dst = arc + 1;
1678 
1679 	  /* Ensure that neither source nor destination are absolute file
1680 	     names (unless permitted by -P option), and that they do not
1681 	     contain dubious parts (e.g. ../).
1682 
1683 	     This is an extra safety precaution. Besides, it might be
1684 	     necessary to extract from archives created with tar versions
1685 	     prior to 1.19. */
1686 
1687 	  if (*src)
1688 	    src = safer_name_suffix (src, false, absolute_names_option);
1689 	  if (*dst)
1690 	    dst = safer_name_suffix (dst, false, absolute_names_option);
1691 
1692 	  if (*src == 0)
1693 	    src = temp_stub;
1694 	  else if (*dst == 0)
1695 	    dst = temp_stub;
1696 
1697 	  if (!rename_directory (src, dst))
1698 	    {
1699 	      free (temp_stub);
1700 	      free (current_dir);
1701 	      /* FIXME: Make sure purge_directory(dst) will return
1702 		 immediately */
1703 	      return false;
1704 	    }
1705 	}
1706     }
1707 
1708   free (temp_stub);
1709 
1710   /* Process deletes */
1711   dump = dumpdir_create (current_stat_info.dumpdir);
1712   p = NULL;
1713   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
1714     {
1715       const char *entry;
1716       struct stat st;
1717       free (p);
1718       p = make_file_name (directory_name, cur);
1719 
1720       if (deref_stat (p, &st) != 0)
1721 	{
1722 	  if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
1723 				  dirs and check it here? */
1724 	    {
1725 	      stat_diag (p);
1726 	      WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1727 		     quotearg_colon (p)));
1728 	    }
1729 	  continue;
1730 	}
1731 
1732       if (!(entry = dumpdir_locate (dump, cur))
1733 	  || (*entry == 'D' && !S_ISDIR (st.st_mode))
1734 	  || (*entry == 'Y' && S_ISDIR (st.st_mode)))
1735 	{
1736 	  if (one_file_system_option && st.st_dev != root_device)
1737 	    {
1738 	      WARN ((0, 0,
1739 		     _("%s: directory is on a different device: not purging"),
1740 		     quotearg_colon (p)));
1741 	      continue;
1742 	    }
1743 
1744 	  if (! interactive_option || confirm ("delete", p))
1745 	    {
1746 	      if (verbose_option)
1747 		fprintf (stdlis, _("%s: Deleting %s\n"),
1748 			 program_name, quote (p));
1749 	      if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
1750 		{
1751 		  int e = errno;
1752 		  ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
1753 		}
1754 	    }
1755 	}
1756     }
1757   free (p);
1758   dumpdir_free (dump);
1759 
1760   free (current_dir);
1761   return true;
1762 }
1763 
1764 void
purge_directory(char const * directory_name)1765 purge_directory (char const *directory_name)
1766 {
1767   if (!try_purge_directory (directory_name))
1768     skip_member ();
1769 }
1770 
1771 void
list_dumpdir(char * buffer,size_t size)1772 list_dumpdir (char *buffer, size_t size)
1773 {
1774   int state = 0;
1775   while (size)
1776     {
1777       switch (*buffer)
1778 	{
1779 	case 'Y':
1780 	case 'N':
1781 	case 'D':
1782 	case 'R':
1783 	case 'T':
1784 	case 'X':
1785 	  fprintf (stdlis, "%c", *buffer);
1786 	  if (state == 0)
1787 	    {
1788 	      fprintf (stdlis, " ");
1789 	      state = 1;
1790 	    }
1791 	  buffer++;
1792 	  size--;
1793 	  break;
1794 
1795 	case 0:
1796 	  fputc ('\n', stdlis);
1797 	  buffer++;
1798 	  size--;
1799 	  state = 0;
1800 	  break;
1801 
1802 	default:
1803 	  fputc (*buffer, stdlis);
1804 	  buffer++;
1805 	  size--;
1806 	}
1807     }
1808 }
1809