]> git.cworth.org Git - tar/blob - src/incremen.c
dc880cd88ce32f27d00dea401d3d98309346a7b6
[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   namebuf_t nbuf;
696   char *tmp;
697   struct stat stat_data;
698   struct directory *directory;
699   char ch;
700   
701   if (! dirp)
702     savedir_error (dir);
703
704   tmp = xstrdup (dir);
705   zap_slashes (tmp);
706   
707   if (deref_stat (dereference_option, tmp, &stat_data))
708     {
709       dir_removed_diag (tmp, cmdline, stat_diag);
710       free (tmp);
711       free (dirp);
712       return NULL;
713     }
714
715   directory = procdir (tmp, &stat_data, device,
716                        (cmdline ? PD_FORCE_INIT : 0),
717                        &ch);
718   
719   free (tmp);
720
721   nbuf = namebuf_create (dir);
722
723   if (dirp && directory->children != NO_CHILDREN)
724     {
725       char *entry;      /* directory entry being scanned */
726       dumpdir_iter_t itr;
727
728       makedumpdir (directory, dirp);
729
730       for (entry = dumpdir_first (directory->dump, 1, &itr);
731            entry;
732            entry = dumpdir_next (itr))
733         {
734           char *full_name = namebuf_name (nbuf, entry + 1);
735
736           if (*entry == 'I') /* Ignored entry */
737             *entry = 'N';
738           else if (excluded_name (full_name))
739             *entry = 'N';
740           else
741             {
742               if (deref_stat (dereference_option, full_name, &stat_data))
743                 {
744                   file_removed_diag (full_name, false, stat_diag);
745                   *entry = 'N';
746                   continue;
747                 }
748
749               if (S_ISDIR (stat_data.st_mode))
750                 {
751                   int pd_flag = 0;
752                   if (!recursion_option)
753                     pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
754                   else if (directory->children == ALL_CHILDREN)
755                     pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
756                   *entry = 'D';
757                   procdir (full_name, &stat_data, device, pd_flag, entry);
758                 }
759
760               else if (one_file_system_option && device != stat_data.st_dev)
761                 *entry = 'N';
762
763               else if (*entry == 'Y')
764                 /* New entry, skip further checks */;
765
766               /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
767
768               else if (OLDER_STAT_TIME (stat_data, m)
769                        && (!after_date_option
770                            || OLDER_STAT_TIME (stat_data, c)))
771                 *entry = 'N';
772               else
773                 *entry = 'Y';
774             }
775         }
776       free (itr);
777     }
778
779   namebuf_free (nbuf);
780
781   if (dirp)
782     free (dirp);
783
784   return directory;
785 }
786
787 /* Return pointer to the contents of the directory DIR */
788 const char *
789 directory_contents (struct directory *dir)
790 {
791   if (!dir)
792     return NULL;
793   return dir->dump ? dir->dump->contents : NULL;
794 }
795
796 /* A "safe" version of directory_contents, which never returns NULL. */
797 const char *
798 safe_directory_contents (struct directory *dir)
799 {
800   const char *ret = directory_contents (dir);
801   return ret ? ret : "\0\0\0\0";
802 }
803
804 void
805 name_fill_directory (struct name *name, dev_t device, bool cmdline)
806 {
807   name->directory = scan_directory (name->name, device, cmdline);
808 }
809
810 \f
811 static void
812 obstack_code_rename (struct obstack *stk, char *from, char *to)
813 {
814   char *s;
815
816   s = from[0] == 0 ? from :
817                      safer_name_suffix (from, false, absolute_names_option);
818   obstack_1grow (stk, 'R');
819   obstack_grow (stk, s, strlen (s) + 1);
820
821   s = to[0] == 0 ? to:
822                    safer_name_suffix (to, false, absolute_names_option);
823   obstack_1grow (stk, 'T');
824   obstack_grow (stk, s, strlen (s) + 1);
825 }
826
827 static void
828 store_rename (struct directory *dir, struct obstack *stk)
829 {
830   if (DIR_IS_RENAMED (dir))
831     {
832       struct directory *prev, *p;
833
834       /* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
835          are ignored when hit by this function next time.
836          If the chain forms a cycle, prev points to the entry DIR is renamed
837          from. In this case it still retains DIRF_RENAMED flag, which will be
838          cleared in the `else' branch below */
839       for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
840         DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
841
842       if (prev == NULL)
843         {
844           for (p = dir; p && p->orig; p = p->orig)
845             obstack_code_rename (stk, p->orig->name, p->name);
846         }
847       else
848         {
849           char *temp_name;
850
851           DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
852
853           /* Break the cycle by using a temporary name for one of its
854              elements.
855              First, create a temp name stub entry. */
856           temp_name = dir_name (dir->name);
857           obstack_1grow (stk, 'X');
858           obstack_grow (stk, temp_name, strlen (temp_name) + 1);
859
860           obstack_code_rename (stk, dir->name, "");
861
862           for (p = dir; p != prev; p = p->orig)
863             obstack_code_rename (stk, p->orig->name, p->name);
864
865           obstack_code_rename (stk, "", prev->name);
866         }
867     }
868 }
869
870 void
871 append_incremental_renames (struct directory *dir)
872 {
873   struct obstack stk;
874   size_t size;
875   struct directory *dp;
876   const char *dump;
877   
878   if (dirhead == NULL)
879     return;
880
881   obstack_init (&stk);
882   dump = directory_contents (dir);
883   if (dump)
884     {
885       size = dumpdir_size (dump) - 1;
886       obstack_grow (&stk, dump, size);
887     }
888   else
889     size = 0;
890
891   for (dp = dirhead; dp; dp = dp->next)
892     store_rename (dp, &stk);
893
894   if (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 ()
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 *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           dumpdir_iter_t 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 (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 (false, p, &st))
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 }