Avoid overwriting exit_status with a value indicating less important condition.
[debian/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)
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 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 struct dumpdir *
112 dumpdir_create (const char *contents)
113 {
114   return dumpdir_create0 (contents, "YND");
115 }
116
117 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 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 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 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 && 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 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 (const char *name)
406 {
407   struct directory *directory;
408   char *p;
409
410   p = dir_name (name);
411   directory = find_directory (p);
412   if (directory)
413     {
414       struct stat st;
415       if (deref_stat (dereference_option, p, &st) != 0)
416         {
417           if (errno != ENOENT) 
418             stat_diag (directory->name);
419           /* else: should have been already reported */
420         }
421       else
422         directory->mtime = get_stat_mtime (&st);
423     }
424   free (p);
425 }
426
427 #define PD_FORCE_CHILDREN 0x10
428 #define PD_FORCE_INIT     0x20
429 #define PD_CHILDREN(f) ((f) & 3)
430
431 static struct directory *
432 procdir (const char *name_buffer, struct stat *stat_data,
433          dev_t device,
434          int flag,
435          char *entry)
436 {
437   struct directory *directory;
438   bool nfs = NFS_FILE_STAT (*stat_data);
439
440   if ((directory = find_directory (name_buffer)) != NULL)
441     {
442       if (DIR_IS_INITED (directory))
443         {
444           if (flag & PD_FORCE_INIT)
445             {
446               assign_string (&directory->name, name_buffer);
447             }
448           else
449             {
450               *entry = 'N'; /* Avoid duplicating this directory */
451               return directory;
452             }
453         }
454
455       if (strcmp (directory->name, name_buffer))
456         {
457           *entry = 'N';
458           return directory;
459         }
460       
461       /* With NFS, the same file can have two different devices
462          if an NFS directory is mounted in multiple locations,
463          which is relatively common when automounting.
464          To avoid spurious incremental redumping of
465          directories, consider all NFS devices as equal,
466          relying on the i-node to establish differences.  */
467       
468       if (! ((!check_device_option
469               || (DIR_IS_NFS (directory) && nfs)
470               || directory->device_number == stat_data->st_dev)
471              && directory->inode_number == stat_data->st_ino))
472         {
473           /* FIXME: find_directory_meta ignores nfs */
474           struct directory *d = find_directory_meta (stat_data->st_dev,
475                                                      stat_data->st_ino);
476           if (d)
477             {
478               if (strcmp (d->name, name_buffer))
479                 {
480                   WARNOPT (WARN_RENAME_DIRECTORY,
481                            (0, 0,
482                             _("%s: Directory has been renamed from %s"),
483                             quotearg_colon (name_buffer),
484                             quote_n (1, d->name)));
485                   directory->orig = d;
486                   DIR_SET_FLAG (directory, DIRF_RENAMED);
487                   dirlist_replace_prefix (d->name, name_buffer);
488                 }
489               directory->children = CHANGED_CHILDREN;
490             }
491           else
492             {
493               WARNOPT (WARN_RENAME_DIRECTORY,
494                        (0, 0, _("%s: Directory has been renamed"),
495                         quotearg_colon (name_buffer)));
496               directory->children = ALL_CHILDREN;
497               directory->device_number = stat_data->st_dev;
498               directory->inode_number = stat_data->st_ino;
499             }
500           if (nfs)
501             DIR_SET_FLAG (directory, DIRF_NFS);
502         }
503       else
504         directory->children = CHANGED_CHILDREN;
505       
506       DIR_SET_FLAG (directory, DIRF_FOUND);
507     }
508   else
509     {
510       struct directory *d = find_directory_meta (stat_data->st_dev,
511                                                  stat_data->st_ino);
512       
513       directory = note_directory (name_buffer,
514                                   get_stat_mtime(stat_data),
515                                   stat_data->st_dev,
516                                   stat_data->st_ino,
517                                   nfs,
518                                   true,
519                                   NULL);
520
521       if (d)
522         {
523           if (strcmp (d->name, name_buffer))
524             {
525               WARNOPT (WARN_RENAME_DIRECTORY,
526                        (0, 0, _("%s: Directory has been renamed from %s"),
527                         quotearg_colon (name_buffer),
528                         quote_n (1, d->name)));
529               directory->orig = d;
530               DIR_SET_FLAG (directory, DIRF_RENAMED);
531               dirlist_replace_prefix (d->name, name_buffer);
532             }
533           directory->children = CHANGED_CHILDREN;
534         }
535       else
536         {
537           DIR_SET_FLAG (directory, DIRF_NEW);
538           WARNOPT (WARN_NEW_DIRECTORY,
539                    (0, 0, _("%s: Directory is new"),
540                     quotearg_colon (name_buffer)));
541           directory->children =
542             (listed_incremental_option
543              || (OLDER_STAT_TIME (*stat_data, m)
544                  || (after_date_option
545                      && OLDER_STAT_TIME (*stat_data, c))))
546             ? ALL_CHILDREN
547             : CHANGED_CHILDREN;
548         }
549     }
550
551   /* If the directory is on another device and --one-file-system was given,
552      omit it... */
553   if (one_file_system_option && device != stat_data->st_dev
554       /* ... except if it was explicitely given in the command line */
555       && !is_individual_file (name_buffer))
556     /* FIXME: 
557         WARNOPT (WARN_XDEV,
558                  (0, 0,
559                   _("%s: directory is on a different filesystem; not dumped"),
560                   quotearg_colon (directory->name)));
561     */
562     directory->children = NO_CHILDREN;
563   else if (flag & PD_FORCE_CHILDREN)
564     {
565       directory->children = PD_CHILDREN(flag);
566       if (directory->children == NO_CHILDREN)
567         *entry = 'N';
568     }
569           
570   DIR_SET_FLAG (directory, DIRF_INIT);
571
572   if (directory->children != NO_CHILDREN)
573     {
574       const char *tag_file_name;
575
576       switch (check_exclusion_tags (name_buffer, &tag_file_name))
577         {
578         case exclusion_tag_all:
579           /* This warning can be duplicated by code in dump_file0, but only
580              in case when the topmost directory being archived contains
581              an exclusion tag. */
582           exclusion_tag_warning (name_buffer, tag_file_name,
583                                  _("directory not dumped"));
584           *entry = 'N';
585           directory->children = NO_CHILDREN;
586           break;
587
588         case exclusion_tag_contents:
589           exclusion_tag_warning (name_buffer, tag_file_name,
590                                  _("contents not dumped"));
591           directory->children = NO_CHILDREN;
592           break;
593           
594         case exclusion_tag_under:
595           exclusion_tag_warning (name_buffer, tag_file_name,
596                                  _("contents not dumped"));
597           directory->tagfile = tag_file_name;
598           break;
599           
600         case exclusion_tag_none:
601           break;
602         }
603     }
604
605   return directory;
606 }
607
608 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
609    build a new dumpdir template.
610
611    DIR must be returned by a previous call to savedir().
612
613    File names in DIRECTORY->dump->contents must be sorted
614    alphabetically.
615
616    DIRECTORY->dump is replaced with the created template. Each entry is
617    prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
618
619 void
620 makedumpdir (struct directory *directory, const char *dir)
621 {
622   size_t i,
623          dirsize,  /* Number of elements in DIR */
624          len;      /* Length of DIR, including terminating nul */
625   const char *p;
626   char const **array;
627   char *new_dump, *new_dump_ptr;
628   struct dumpdir *dump;
629
630   if (directory->children == ALL_CHILDREN)
631     dump = NULL;
632   else if (DIR_IS_RENAMED (directory))
633     dump = directory->orig->idump ?
634            directory->orig->idump : directory->orig->dump;
635   else
636     dump = directory->dump;
637
638   /* Count the size of DIR and the number of elements it contains */
639   dirsize = 0;
640   len = 0;
641   for (p = dir; *p; p += strlen (p) + 1, dirsize++)
642     len += strlen (p) + 2;
643   len++;
644
645   /* Create a sorted directory listing */
646   array = xcalloc (dirsize, sizeof array[0]);
647   for (i = 0, p = dir; *p; p += strlen (p) + 1, i++)
648     array[i] = p;
649
650   qsort (array, dirsize, sizeof (array[0]), compare_dirnames);
651
652   /* Prepare space for new dumpdir */
653   new_dump = xmalloc (len);
654   new_dump_ptr = new_dump;
655
656   /* Fill in the dumpdir template */
657   for (i = 0; i < dirsize; i++)
658     {
659       const char *loc = dumpdir_locate (dump, array[i]);
660       if (loc)
661         {
662           if (directory->tagfile)
663             *new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
664                                 ' ' : 'I';
665           else
666             *new_dump_ptr = ' ';
667           new_dump_ptr++;
668         }
669       else if (directory->tagfile)
670         *new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
671                                ' ' : 'I';
672       else
673         *new_dump_ptr++ = 'Y'; /* New entry */
674
675       /* Copy the file name */
676       for (p = array[i]; (*new_dump_ptr++ = *p++); )
677         ;
678     }
679   *new_dump_ptr = 0;
680   directory->idump = directory->dump;
681   directory->dump = dumpdir_create0 (new_dump, NULL);
682   free (array);
683 }
684
685 /* Recursively scan the given directory DIR.
686    DEVICE is the device number where DIR resides (for --one-file-system).
687    If CMDLINE is true, the directory name was explicitly listed in the
688    command line.
689    Unless *PDIR is NULL, store there a pointer to the struct directory
690    describing DIR. */
691 struct directory *
692 scan_directory (char *dir, dev_t device, bool cmdline)
693 {
694   char *dirp = savedir (dir);   /* for scanning directory */
695   char *name_buffer;            /* directory, `/', and directory member */
696   size_t name_buffer_size;      /* allocated size of name_buffer, minus 2 */
697   size_t name_length;           /* used length in name_buffer */
698   struct stat stat_data;
699   struct directory *directory;
700   char ch;
701   
702   if (! dirp)
703     savedir_error (dir);
704
705   name_buffer_size = strlen (dir) + NAME_FIELD_SIZE;
706   name_buffer = xmalloc (name_buffer_size + 2);
707   strcpy (name_buffer, dir);
708   zap_slashes (name_buffer);
709   
710   if (deref_stat (dereference_option, name_buffer, &stat_data))
711     {
712       dir_removed_diag (name_buffer, cmdline, stat_diag);
713       free (name_buffer);
714       free (dirp);
715       return NULL;
716     }
717
718   directory = procdir (name_buffer, &stat_data, device,
719                        (cmdline ? PD_FORCE_INIT : 0),
720                        &ch);
721   
722   name_length = strlen (name_buffer); 
723   if (! ISSLASH (name_buffer[name_length - 1]))
724     {
725       name_buffer[name_length] = DIRECTORY_SEPARATOR;
726       /* name_buffer has been allocated an extra slot */
727       name_buffer[++name_length] = 0;
728     }
729
730   if (dirp && directory->children != NO_CHILDREN)
731     {
732       char *entry;      /* directory entry being scanned */
733       size_t entrylen;  /* length of directory entry */
734       dumpdir_iter_t itr;
735
736       makedumpdir (directory, dirp);
737
738       for (entry = dumpdir_first (directory->dump, 1, &itr);
739            entry;
740            entry = dumpdir_next (itr))
741         {
742           entrylen = strlen (entry);
743           if (name_buffer_size <= entrylen - 1 + name_length)
744             {
745               do
746                 name_buffer_size += NAME_FIELD_SIZE;
747               while (name_buffer_size <= entrylen - 1 + name_length);
748               name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
749             }
750           strcpy (name_buffer + name_length, entry + 1);
751
752           if (*entry == 'I') /* Ignored entry */
753             *entry = 'N';
754           else if (excluded_name (name_buffer))
755             *entry = 'N';
756           else
757             {
758               if (deref_stat (dereference_option, name_buffer, &stat_data))
759                 {
760                   file_removed_diag (name_buffer, false, stat_diag);
761                   *entry = 'N';
762                   continue;
763                 }
764
765               if (S_ISDIR (stat_data.st_mode))
766                 {
767                   int pd_flag = 0;
768                   if (!recursion_option)
769                     pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
770                   else if (directory->children == ALL_CHILDREN)
771                     pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
772                   *entry = 'D';
773                   procdir (name_buffer, &stat_data, device, pd_flag, entry);
774                 }
775
776               else if (one_file_system_option && device != stat_data.st_dev)
777                 *entry = 'N';
778
779               else if (*entry == 'Y')
780                 /* New entry, skip further checks */;
781
782               /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
783
784               else if (OLDER_STAT_TIME (stat_data, m)
785                        && (!after_date_option
786                            || OLDER_STAT_TIME (stat_data, c)))
787                 *entry = 'N';
788               else
789                 *entry = 'Y';
790             }
791         }
792       free (itr);
793     }
794
795   free (name_buffer);
796   if (dirp)
797     free (dirp);
798
799   return directory;
800 }
801
802 /* Return pointer to the contents of the directory DIR */
803 const char *
804 directory_contents (struct directory *dir)
805 {
806   if (!dir)
807     return NULL;
808   return dir->dump ? dir->dump->contents : NULL;
809 }
810
811 /* A "safe" version of directory_contents, which never returns NULL. */
812 const char *
813 safe_directory_contents (struct directory *dir)
814 {
815   const char *ret = directory_contents (dir);
816   return ret ? ret : "\0\0\0\0";
817 }
818
819 void
820 name_fill_directory (struct name *name, dev_t device, bool cmdline)
821 {
822   name->directory = scan_directory (name->name, device, cmdline);
823 }
824
825 \f
826 static void
827 obstack_code_rename (struct obstack *stk, char *from, char *to)
828 {
829   char *s;
830
831   s = from[0] == 0 ? from :
832                      safer_name_suffix (from, false, absolute_names_option);
833   obstack_1grow (stk, 'R');
834   obstack_grow (stk, s, strlen (s) + 1);
835
836   s = to[0] == 0 ? to:
837                    safer_name_suffix (to, false, absolute_names_option);
838   obstack_1grow (stk, 'T');
839   obstack_grow (stk, s, strlen (s) + 1);
840 }
841
842 static void
843 store_rename (struct directory *dir, struct obstack *stk)
844 {
845   if (DIR_IS_RENAMED (dir))
846     {
847       struct directory *prev, *p;
848
849       /* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
850          are ignored when hit by this function next time.
851          If the chain forms a cycle, prev points to the entry DIR is renamed
852          from. In this case it still retains DIRF_RENAMED flag, which will be
853          cleared in the `else' branch below */
854       for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
855         DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
856
857       if (prev == NULL)
858         {
859           for (p = dir; p && p->orig; p = p->orig)
860             obstack_code_rename (stk, p->orig->name, p->name);
861         }
862       else
863         {
864           char *temp_name;
865
866           DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
867
868           /* Break the cycle by using a temporary name for one of its
869              elements.
870              First, create a temp name stub entry. */
871           temp_name = dir_name (dir->name);
872           obstack_1grow (stk, 'X');
873           obstack_grow (stk, temp_name, strlen (temp_name) + 1);
874
875           obstack_code_rename (stk, dir->name, "");
876
877           for (p = dir; p != prev; p = p->orig)
878             obstack_code_rename (stk, p->orig->name, p->name);
879
880           obstack_code_rename (stk, "", prev->name);
881         }
882     }
883 }
884
885 void
886 append_incremental_renames (struct directory *dir)
887 {
888   struct obstack stk;
889   size_t size;
890   struct directory *dp;
891   const char *dump;
892   
893   if (dirhead == NULL)
894     return;
895
896   obstack_init (&stk);
897   dump = directory_contents (dir);
898   if (dump)
899     {
900       size = dumpdir_size (dump) - 1;
901       obstack_grow (&stk, dump, size);
902     }
903   else
904     size = 0;
905
906   for (dp = dirhead; dp; dp = dp->next)
907     store_rename (dp, &stk);
908
909   if (obstack_object_size (&stk) != size)
910     {
911       obstack_1grow (&stk, 0);
912       dumpdir_free (dir->dump);
913       dir->dump = dumpdir_create (obstack_finish (&stk));
914     }
915   obstack_free (&stk, NULL);
916 }
917
918 \f
919
920 static FILE *listed_incremental_stream;
921
922 /* Version of incremental format snapshots (directory files) used by this
923    tar. Currently it is supposed to be a single decimal number. 0 means
924    incremental snapshots as per tar version before 1.15.2.
925
926    The current tar version supports incremental versions from
927    0 up to TAR_INCREMENTAL_VERSION, inclusive.
928    It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
929
930 #define TAR_INCREMENTAL_VERSION 2
931
932 /* Read incremental snapshot formats 0 and 1 */
933 static void
934 read_incr_db_01 (int version, const char *initbuf)
935 {
936   int n;
937   uintmax_t u;
938   time_t sec;
939   long int nsec;
940   char *buf = 0;
941   size_t bufsize;
942   char *ebuf;
943   long lineno = 1;
944
945   if (version == 1)
946     {
947       if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
948         {
949           read_error (listed_incremental_option);
950           free (buf);
951           return;
952         }
953       ++lineno;
954     }
955   else
956     {
957       buf = strdup (initbuf);
958       bufsize = strlen (buf) + 1;
959     }
960
961   sec = TYPE_MINIMUM (time_t);
962   nsec = -1;
963   errno = 0;
964   u = strtoumax (buf, &ebuf, 10);
965   if (!errno && TYPE_MAXIMUM (time_t) < u)
966     errno = ERANGE;
967   if (errno || buf == ebuf)
968     ERROR ((0, errno, "%s:%ld: %s",
969             quotearg_colon (listed_incremental_option),
970             lineno,
971             _("Invalid time stamp")));
972   else
973     {
974       sec = u;
975
976       if (version == 1 && *ebuf)
977         {
978           char const *buf_ns = ebuf + 1;
979           errno = 0;
980           u = strtoumax (buf_ns, &ebuf, 10);
981           if (!errno && BILLION <= u)
982             errno = ERANGE;
983           if (errno || buf_ns == ebuf)
984             {
985               ERROR ((0, errno, "%s:%ld: %s",
986                       quotearg_colon (listed_incremental_option),
987                       lineno,
988                       _("Invalid time stamp")));
989               sec = TYPE_MINIMUM (time_t);
990             }
991           else
992             nsec = u;
993         }
994       else
995         {
996           /* pre-1 incremental format does not contain nanoseconds */
997           nsec = 0;
998         }
999     }
1000   newer_mtime_option.tv_sec = sec;
1001   newer_mtime_option.tv_nsec = nsec;
1002
1003
1004   while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
1005     {
1006       dev_t dev;
1007       ino_t ino;
1008       bool nfs = buf[0] == '+';
1009       char *strp = buf + nfs;
1010       struct timespec mtime;
1011
1012       lineno++;
1013
1014       if (buf[n - 1] == '\n')
1015         buf[n - 1] = '\0';
1016
1017       if (version == 1)
1018         {
1019           errno = 0;
1020           u = strtoumax (strp, &ebuf, 10);
1021           if (!errno && TYPE_MAXIMUM (time_t) < 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 (seconds)")));
1028               sec = (time_t) -1;
1029             }
1030           else
1031             sec = u;
1032           strp = ebuf;
1033
1034           errno = 0;
1035           u = strtoumax (strp, &ebuf, 10);
1036           if (!errno && BILLION <= u)
1037             errno = ERANGE;
1038           if (errno || strp == ebuf || *ebuf != ' ')
1039             {
1040               ERROR ((0, errno, "%s:%ld: %s",
1041                       quotearg_colon (listed_incremental_option), lineno,
1042                       _("Invalid modification time (nanoseconds)")));
1043               nsec = -1;
1044             }
1045           else
1046             nsec = u;
1047           mtime.tv_sec = sec;
1048           mtime.tv_nsec = nsec;
1049           strp = ebuf;
1050         }
1051       else
1052         memset (&mtime, 0, sizeof mtime);
1053
1054       errno = 0;
1055       u = strtoumax (strp, &ebuf, 10);
1056       if (!errno && TYPE_MAXIMUM (dev_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 device number")));
1063           dev = (dev_t) -1;
1064         }
1065       else
1066         dev = u;
1067       strp = ebuf;
1068
1069       errno = 0;
1070       u = strtoumax (strp, &ebuf, 10);
1071       if (!errno && TYPE_MAXIMUM (ino_t) < u)
1072         errno = ERANGE;
1073       if (errno || strp == ebuf || *ebuf != ' ')
1074         {
1075           ERROR ((0, errno, "%s:%ld: %s",
1076                   quotearg_colon (listed_incremental_option), lineno,
1077                   _("Invalid inode number")));
1078           ino = (ino_t) -1;
1079         }
1080       else
1081         ino = u;
1082       strp = ebuf;
1083
1084       strp++;
1085       unquote_string (strp);
1086       note_directory (strp, mtime, dev, ino, nfs, false, NULL);
1087     }
1088   free (buf);
1089 }
1090
1091 /* Read a nul-terminated string from FP and store it in STK.
1092    Store the number of bytes read (including nul terminator) in PCOUNT.
1093
1094    Return the last character read or EOF on end of file. */
1095 static int
1096 read_obstack (FILE *fp, struct obstack *stk, size_t *pcount)
1097 {
1098   int c;
1099   size_t i;
1100
1101   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
1102     obstack_1grow (stk, c);
1103   obstack_1grow (stk, 0);
1104
1105   *pcount = i;
1106   return c;
1107 }
1108
1109 /* Read from file FP a nul-terminated string and convert it to
1110    intmax_t.  Return the resulting value in PVAL.  Assume '-' has
1111    already been read.
1112
1113    Throw a fatal error if the string cannot be converted or if the
1114    converted value is less than MIN_VAL.  */
1115
1116 static void
1117 read_negative_num (FILE *fp, intmax_t min_val, intmax_t *pval)
1118 {
1119   int c;
1120   size_t i;
1121   char buf[INT_BUFSIZE_BOUND (intmax_t)];
1122   char *ep;
1123   buf[0] = '-';
1124
1125   for (i = 1; ISDIGIT (c = getc (fp)); i++)
1126     {
1127       if (i == sizeof buf - 1)
1128         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
1129       buf[i] = c;
1130     }
1131
1132   if (c < 0)
1133     {
1134       if (ferror (fp))
1135         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
1136       else
1137         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
1138     }
1139
1140   buf[i] = 0;
1141   errno = 0;
1142   *pval = strtoimax (buf, &ep, 10);
1143   if (c || errno || *pval < min_val)
1144     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
1145 }
1146
1147 /* Read from file FP a nul-terminated string and convert it to
1148    uintmax_t.  Return the resulting value in PVAL.  Assume C has
1149    already been read.
1150
1151    Throw a fatal error if the string cannot be converted or if the
1152    converted value exceeds MAX_VAL.
1153
1154    Return the last character read or EOF on end of file. */
1155
1156 static int
1157 read_unsigned_num (int c, FILE *fp, uintmax_t max_val, uintmax_t *pval)
1158 {
1159   size_t i;
1160   char buf[UINTMAX_STRSIZE_BOUND], *ep;
1161
1162   for (i = 0; ISDIGIT (c); i++)
1163     {
1164       if (i == sizeof buf - 1)
1165         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
1166       buf[i] = c;
1167       c = getc (fp);
1168     }
1169
1170   if (c < 0)
1171     {
1172       if (ferror (fp))
1173         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
1174       else if (i == 0)
1175         return c;
1176       else
1177         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
1178     }
1179
1180   buf[i] = 0;
1181   errno = 0;
1182   *pval = strtoumax (buf, &ep, 10);
1183   if (c || errno || max_val < *pval)
1184     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
1185   return c;
1186 }
1187
1188 /* Read from file FP a nul-terminated string and convert it to
1189    uintmax_t.  Return the resulting value in PVAL.
1190
1191    Throw a fatal error if the string cannot be converted or if the
1192    converted value exceeds MAX_VAL.
1193
1194    Return the last character read or EOF on end of file. */
1195
1196 static int
1197 read_num (FILE *fp, uintmax_t max_val, uintmax_t *pval)
1198 {
1199   return read_unsigned_num (getc (fp), fp, max_val, pval);
1200 }
1201
1202 /* Read from FP two NUL-terminated strings representing a struct
1203    timespec.  Return the resulting value in PVAL.
1204
1205    Throw a fatal error if the string cannot be converted.  */
1206
1207 static void
1208 read_timespec (FILE *fp, struct timespec *pval)
1209 {
1210   int c = getc (fp);
1211   intmax_t i;
1212   uintmax_t u;
1213
1214   if (c == '-')
1215     {
1216       read_negative_num (fp, TYPE_MINIMUM (time_t), &i);
1217       c = 0;
1218       pval->tv_sec = i;
1219     }
1220   else
1221     {
1222       c = read_unsigned_num (c, fp, TYPE_MAXIMUM (time_t), &u);
1223       pval->tv_sec = u;
1224     }
1225
1226   if (c || read_num (fp, BILLION - 1, &u))
1227     FATAL_ERROR ((0, 0, "%s: %s",
1228                   quotearg_colon (listed_incremental_option),
1229                   _("Unexpected EOF in snapshot file")));
1230   pval->tv_nsec = u;
1231 }
1232
1233 /* Read incremental snapshot format 2 */
1234 static void
1235 read_incr_db_2 ()
1236 {
1237   uintmax_t u;
1238   struct obstack stk;
1239
1240   obstack_init (&stk);
1241
1242   read_timespec (listed_incremental_stream, &newer_mtime_option);
1243
1244   for (;;)
1245     {
1246       struct timespec mtime;
1247       dev_t dev;
1248       ino_t ino;
1249       bool nfs;
1250       char *name;
1251       char *content;
1252       size_t s;
1253
1254       if (read_num (listed_incremental_stream, 1, &u))
1255         return; /* Normal return */
1256
1257       nfs = u;
1258
1259       read_timespec (listed_incremental_stream, &mtime);
1260
1261       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u))
1262         break;
1263       dev = u;
1264
1265       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u))
1266         break;
1267       ino = u;
1268
1269       if (read_obstack (listed_incremental_stream, &stk, &s))
1270         break;
1271
1272       name = obstack_finish (&stk);
1273
1274       while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1)
1275         ;
1276       if (getc (listed_incremental_stream) != 0)
1277         FATAL_ERROR ((0, 0, "%s: %s",
1278                       quotearg_colon (listed_incremental_option),
1279                       _("Missing record terminator")));
1280
1281       content = obstack_finish (&stk);
1282       note_directory (name, mtime, dev, ino, nfs, false, content);
1283       obstack_free (&stk, content);
1284     }
1285   FATAL_ERROR ((0, 0, "%s: %s",
1286                 quotearg_colon (listed_incremental_option),
1287                 _("Unexpected EOF in snapshot file")));
1288 }
1289
1290 /* Read incremental snapshot file (directory file).
1291    If the file has older incremental version, make sure that it is processed
1292    correctly and that tar will use the most conservative backup method among
1293    possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
1294    etc.) This ensures that the snapshots are updated to the recent version
1295    without any loss of data. */
1296 void
1297 read_directory_file (void)
1298 {
1299   int fd;
1300   char *buf = 0;
1301   size_t bufsize;
1302   int flags = O_RDWR | O_CREAT;
1303
1304   if (incremental_level == 0)
1305     flags |= O_TRUNC;
1306   /* Open the file for both read and write.  That way, we can write
1307      it later without having to reopen it, and don't have to worry if
1308      we chdir in the meantime.  */
1309   fd = open (listed_incremental_option, flags, MODE_RW);
1310   if (fd < 0)
1311     {
1312       open_error (listed_incremental_option);
1313       return;
1314     }
1315
1316   listed_incremental_stream = fdopen (fd, "r+");
1317   if (! listed_incremental_stream)
1318     {
1319       open_error (listed_incremental_option);
1320       close (fd);
1321       return;
1322     }
1323
1324   /* Consume the first name from the name list and reset the
1325      list afterwards.  This is done to change to the new
1326      directory, if the first name is a chdir request (-C dir),
1327      which is necessary to recreate absolute file names. */
1328   name_from_list ();
1329   blank_name_list ();
1330   
1331   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
1332     {
1333       char *ebuf;
1334       uintmax_t incremental_version;
1335
1336       if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0)
1337         {
1338           ebuf = buf + sizeof PACKAGE_NAME - 1;
1339           if (*ebuf++ != '-')
1340             ERROR((1, 0, _("Bad incremental file format")));
1341           for (; *ebuf != '-'; ebuf++)
1342             if (!*ebuf)
1343               ERROR((1, 0, _("Bad incremental file format")));
1344
1345           incremental_version = strtoumax (ebuf + 1, NULL, 10);
1346         }
1347       else
1348         incremental_version = 0;
1349
1350       switch (incremental_version)
1351         {
1352         case 0:
1353         case 1:
1354           read_incr_db_01 (incremental_version, buf);
1355           break;
1356
1357         case TAR_INCREMENTAL_VERSION:
1358           read_incr_db_2 ();
1359           break;
1360
1361         default:
1362           ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX),
1363                   incremental_version));
1364         }
1365
1366     }
1367
1368   if (ferror (listed_incremental_stream))
1369     read_error (listed_incremental_option);
1370   if (buf)
1371     free (buf);
1372 }
1373
1374 /* Output incremental data for the directory ENTRY to the file DATA.
1375    Return nonzero if successful, preserving errno on write failure.  */
1376 static bool
1377 write_directory_file_entry (void *entry, void *data)
1378 {
1379   struct directory const *directory = entry;
1380   FILE *fp = data;
1381
1382   if (DIR_IS_FOUND (directory))
1383     {
1384       char buf[UINTMAX_STRSIZE_BOUND];
1385       char *s;
1386
1387       s = DIR_IS_NFS (directory) ? "1" : "0";
1388       fwrite (s, 2, 1, fp);
1389       s = (TYPE_SIGNED (time_t)
1390            ? imaxtostr (directory->mtime.tv_sec, buf)
1391            : umaxtostr (directory->mtime.tv_sec, buf));
1392       fwrite (s, strlen (s) + 1, 1, fp);
1393       s = umaxtostr (directory->mtime.tv_nsec, buf);
1394       fwrite (s, strlen (s) + 1, 1, fp);
1395       s = umaxtostr (directory->device_number, buf);
1396       fwrite (s, strlen (s) + 1, 1, fp);
1397       s = umaxtostr (directory->inode_number, buf);
1398       fwrite (s, strlen (s) + 1, 1, fp);
1399
1400       fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
1401       if (directory->dump)
1402         {
1403           const char *p;
1404           dumpdir_iter_t itr;
1405
1406           for (p = dumpdir_first (directory->dump, 0, &itr);
1407                p;
1408                p = dumpdir_next (itr))
1409             fwrite (p, strlen (p) + 1, 1, fp);
1410           free (itr);
1411         }
1412       fwrite ("\0\0", 2, 1, fp);
1413     }
1414
1415   return ! ferror (fp);
1416 }
1417
1418 void
1419 write_directory_file (void)
1420 {
1421   FILE *fp = listed_incremental_stream;
1422   char buf[UINTMAX_STRSIZE_BOUND];
1423   char *s;
1424
1425   if (! fp)
1426     return;
1427
1428   if (fseek (fp, 0L, SEEK_SET) != 0)
1429     seek_error (listed_incremental_option);
1430   if (sys_truncate (fileno (fp)) != 0)
1431     truncate_error (listed_incremental_option);
1432
1433   fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
1434            TAR_INCREMENTAL_VERSION);
1435
1436   s = (TYPE_SIGNED (time_t)
1437        ? imaxtostr (start_time.tv_sec, buf)
1438        : umaxtostr (start_time.tv_sec, buf));
1439   fwrite (s, strlen (s) + 1, 1, fp);
1440   s = umaxtostr (start_time.tv_nsec, buf);
1441   fwrite (s, strlen (s) + 1, 1, fp);
1442
1443   if (! ferror (fp) && directory_table)
1444     hash_do_for_each (directory_table, write_directory_file_entry, fp);
1445
1446   if (ferror (fp))
1447     write_error (listed_incremental_option);
1448   if (fclose (fp) != 0)
1449     close_error (listed_incremental_option);
1450 }
1451
1452 \f
1453 /* Restoration of incremental dumps.  */
1454
1455 static void
1456 get_gnu_dumpdir (struct tar_stat_info *stat_info)
1457 {
1458   size_t size;
1459   size_t copied;
1460   union block *data_block;
1461   char *to;
1462   char *archive_dir;
1463
1464   size = stat_info->stat.st_size;
1465
1466   archive_dir = xmalloc (size);
1467   to = archive_dir;
1468
1469   set_next_block_after (current_header);
1470   mv_begin (stat_info);
1471
1472   for (; size > 0; size -= copied)
1473     {
1474       mv_size_left (size);
1475       data_block = find_next_block ();
1476       if (!data_block)
1477         ERROR ((1, 0, _("Unexpected EOF in archive")));
1478       copied = available_space_after (data_block);
1479       if (copied > size)
1480         copied = size;
1481       memcpy (to, data_block->buffer, copied);
1482       to += copied;
1483       set_next_block_after ((union block *)
1484                             (data_block->buffer + copied - 1));
1485     }
1486
1487   mv_end ();
1488
1489   stat_info->dumpdir = archive_dir;
1490   stat_info->skipped = true; /* For skip_member() and friends
1491                                 to work correctly */
1492 }
1493
1494 /* Return T if STAT_INFO represents a dumpdir archive member.
1495    Note: can invalidate current_header. It happens if flush_archive()
1496    gets called within get_gnu_dumpdir() */
1497 bool
1498 is_dumpdir (struct tar_stat_info *stat_info)
1499 {
1500   if (stat_info->is_dumpdir && !stat_info->dumpdir)
1501     get_gnu_dumpdir (stat_info);
1502   return stat_info->is_dumpdir;
1503 }
1504
1505 static bool
1506 dumpdir_ok (char *dumpdir)
1507 {
1508   char *p;
1509   int has_tempdir = 0;
1510   int expect = 0;
1511
1512   for (p = dumpdir; *p; p += strlen (p) + 1)
1513     {
1514       if (expect && *p != expect)
1515         {
1516           ERROR ((0, 0,
1517                   _("Malformed dumpdir: expected '%c' but found %#3o"),
1518                   expect, *p));
1519           return false;
1520         }
1521       switch (*p)
1522         {
1523         case 'X':
1524           if (has_tempdir)
1525             {
1526               ERROR ((0, 0,
1527                       _("Malformed dumpdir: 'X' duplicated")));
1528               return false;
1529             }
1530           else
1531             has_tempdir = 1;
1532           break;
1533
1534         case 'R':
1535           if (p[1] == 0)
1536             {
1537               if (!has_tempdir)
1538                 {
1539                   ERROR ((0, 0,
1540                           _("Malformed dumpdir: empty name in 'R'")));
1541                   return false;
1542                 }
1543               else
1544                 has_tempdir = 0;
1545             }
1546           expect = 'T';
1547           break;
1548
1549         case 'T':
1550           if (expect != 'T')
1551             {
1552               ERROR ((0, 0,
1553                       _("Malformed dumpdir: 'T' not preceeded by 'R'")));
1554               return false;
1555             }
1556           if (p[1] == 0 && !has_tempdir)
1557             {
1558               ERROR ((0, 0,
1559                       _("Malformed dumpdir: empty name in 'T'")));
1560               return false;
1561             }
1562           expect = 0;
1563           break;
1564
1565         case 'N':
1566         case 'Y':
1567         case 'D':
1568           break;
1569
1570         default:
1571           /* FIXME: bail out? */
1572           break;
1573         }
1574     }
1575
1576   if (expect)
1577     {
1578       ERROR ((0, 0,
1579               _("Malformed dumpdir: expected '%c' but found end of data"),
1580               expect));
1581       return false;
1582     }
1583
1584   if (has_tempdir)
1585     WARNOPT (WARN_BAD_DUMPDIR,
1586              (0, 0, _("Malformed dumpdir: 'X' never used")));
1587
1588   return true;
1589 }
1590
1591 /* Examine the directories under directory_name and delete any
1592    files that were not there at the time of the back-up. */
1593 static bool
1594 try_purge_directory (char const *directory_name)
1595 {
1596   char *current_dir;
1597   char *cur, *arc, *p;
1598   char *temp_stub = NULL;
1599   struct dumpdir *dump;
1600
1601   if (!is_dumpdir (&current_stat_info))
1602     return false;
1603
1604   current_dir = savedir (directory_name);
1605
1606   if (!current_dir)
1607     /* The directory doesn't exist now.  It'll be created.  In any
1608        case, we don't have to delete any files out of it.  */
1609     return false;
1610
1611   /* Verify if dump directory is sane */
1612   if (!dumpdir_ok (current_stat_info.dumpdir))
1613     return false;
1614
1615   /* Process renames */
1616   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
1617     {
1618       if (*arc == 'X')
1619         {
1620 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1621           size_t len = strlen (arc + 1);
1622           temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
1623           memcpy (temp_stub, arc + 1, len);
1624           temp_stub[len] = '/';
1625           memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
1626                   sizeof TEMP_DIR_TEMPLATE);
1627           if (!mkdtemp (temp_stub))
1628             {
1629               ERROR ((0, errno,
1630                       _("Cannot create temporary directory using template %s"),
1631                       quote (temp_stub)));
1632               free (temp_stub);
1633               free (current_dir);
1634               return false;
1635             }
1636         }
1637       else if (*arc == 'R')
1638         {
1639           char *src, *dst;
1640           src = arc + 1;
1641           arc += strlen (arc) + 1;
1642           dst = arc + 1;
1643
1644           /* Ensure that neither source nor destination are absolute file
1645              names (unless permitted by -P option), and that they do not
1646              contain dubious parts (e.g. ../).
1647
1648              This is an extra safety precaution. Besides, it might be
1649              necessary to extract from archives created with tar versions
1650              prior to 1.19. */
1651
1652           if (*src)
1653             src = safer_name_suffix (src, false, absolute_names_option);
1654           if (*dst)
1655             dst = safer_name_suffix (dst, false, absolute_names_option);
1656
1657           if (*src == 0)
1658             src = temp_stub;
1659           else if (*dst == 0)
1660             dst = temp_stub;
1661
1662           if (!rename_directory (src, dst))
1663             {
1664               free (temp_stub);
1665               free (current_dir);
1666               /* FIXME: Make sure purge_directory(dst) will return
1667                  immediately */
1668               return false;
1669             }
1670         }
1671     }
1672
1673   free (temp_stub);
1674
1675   /* Process deletes */
1676   dump = dumpdir_create (current_stat_info.dumpdir);
1677   p = NULL;
1678   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
1679     {
1680       const char *entry;
1681       struct stat st;
1682       if (p)
1683         free (p);
1684       p = new_name (directory_name, cur);
1685
1686       if (deref_stat (false, p, &st))
1687         {
1688           if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
1689                                   dirs and check it here? */
1690             {
1691               stat_diag (p);
1692               WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1693                      quotearg_colon (p)));
1694             }
1695           continue;
1696         }
1697
1698       if (!(entry = dumpdir_locate (dump, cur))
1699           || (*entry == 'D' && !S_ISDIR (st.st_mode))
1700           || (*entry == 'Y' && S_ISDIR (st.st_mode)))
1701         {
1702           if (one_file_system_option && st.st_dev != root_device)
1703             {
1704               WARN ((0, 0,
1705                      _("%s: directory is on a different device: not purging"),
1706                      quotearg_colon (p)));
1707               continue;
1708             }
1709
1710           if (! interactive_option || confirm ("delete", p))
1711             {
1712               if (verbose_option)
1713                 fprintf (stdlis, _("%s: Deleting %s\n"),
1714                          program_name, quote (p));
1715               if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
1716                 {
1717                   int e = errno;
1718                   ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
1719                 }
1720             }
1721         }
1722     }
1723   free (p);
1724   dumpdir_free (dump);
1725   
1726   free (current_dir);
1727   return true;
1728 }
1729
1730 void
1731 purge_directory (char const *directory_name)
1732 {
1733   if (!try_purge_directory (directory_name))
1734     skip_member ();
1735 }
1736
1737 void
1738 list_dumpdir (char *buffer, size_t size)
1739 {
1740   int state = 0;
1741   while (size)
1742     {
1743       switch (*buffer)
1744         {
1745         case 'Y':
1746         case 'N':
1747         case 'D':
1748         case 'R':
1749         case 'T':
1750         case 'X':
1751           fprintf (stdlis, "%c", *buffer);
1752           if (state == 0)
1753             {
1754               fprintf (stdlis, " ");
1755               state = 1;
1756             }
1757           buffer++;
1758           size--;
1759           break;
1760
1761         case 0:
1762           fputc ('\n', stdlis);
1763           buffer++;
1764           size--;
1765           state = 0;
1766           break;
1767
1768         default:
1769           fputc (*buffer, stdlis);
1770           buffer++;
1771           size--;
1772         }
1773     }
1774 }