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