This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any later
+ Free Software Foundation; either version 3, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <system.h>
-#include <getline.h>
#include <hash.h>
-#include <mkdtemp.h>
#include <quotearg.h>
#include "common.h"
unsigned flags; /* See DIRF_ macros above */
struct directory *orig; /* If the directory was renamed, points to
the original directory structure */
+ const char *tagfile; /* Tag file, if the directory falls under
+ exclusion_tag_under */
char name[1]; /* file name of directory */
};
directory->orig = NULL;
directory->flags = false;
strcpy (directory->name, name);
- if (ISSLASH (directory->name[namelen-1]))
- directory->name[namelen-1] = 0;
+ if (namelen && ISSLASH (directory->name[namelen - 1]))
+ directory->name[namelen - 1] = 0;
+ directory->tagfile = NULL;
return directory;
}
procdir (char *name_buffer, struct stat *stat_data,
dev_t device,
enum children children,
- bool verbose)
+ bool verbose,
+ char *entry)
{
struct directory *directory;
bool nfs = NFS_FILE_STAT (*stat_data);
directories, consider all NFS devices as equal,
relying on the i-node to establish differences. */
- if (! (((DIR_IS_NFS (directory) & nfs)
+ if (! ((!check_device_option
+ || (DIR_IS_NFS (directory) && nfs)
|| directory->device_number == stat_data->st_dev)
&& directory->inode_number == stat_data->st_ino))
{
DIR_SET_FLAG (directory, DIRF_INIT);
+ {
+ const char *tag_file_name;
+
+ switch (check_exclusion_tags (name_buffer, &tag_file_name))
+ {
+ case exclusion_tag_all:
+ /* This warning can be duplicated by code in dump_file0, but only
+ in case when the topmost directory being archived contains
+ an exclusion tag. */
+ exclusion_tag_warning (name_buffer, tag_file_name,
+ _("directory not dumped"));
+ if (entry)
+ *entry = 'N';
+ directory->children = NO_CHILDREN;
+ break;
+
+ case exclusion_tag_contents:
+ exclusion_tag_warning (name_buffer, tag_file_name,
+ _("contents not dumped"));
+ directory->children = NO_CHILDREN;
+ break;
+
+ case exclusion_tag_under:
+ exclusion_tag_warning (name_buffer, tag_file_name,
+ _("contents not dumped"));
+ directory->tagfile = tag_file_name;
+ break;
+
+ case exclusion_tag_none:
+ break;
+ }
+ }
+
return directory;
}
const char *loc = dumpdir_locate (dump, array[i]);
if (loc)
{
- *new_dump_ptr++ = ' ';
+ if (directory->tagfile)
+ *new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
+ ' ' : 'I';
+ else
+ *new_dump_ptr = ' ';
+ new_dump_ptr++;
dump = loc + strlen (loc) + 1;
}
+ else if (directory->tagfile)
+ *new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
+ ' ' : 'I';
else
*new_dump_ptr++ = 'Y'; /* New entry */
/* Recursively scan the given directory. */
static char *
-scan_directory (char *dir_name, dev_t device)
+scan_directory (char *dir, dev_t device)
{
- char *dirp = savedir (dir_name); /* for scanning directory */
+ char *dirp = savedir (dir); /* for scanning directory */
char *name_buffer; /* directory, `/', and directory member */
size_t name_buffer_size; /* allocated size of name_buffer, minus 2 */
size_t name_length; /* used length in name_buffer */
struct directory *directory;
if (! dirp)
- savedir_error (dir_name);
+ savedir_error (dir);
- name_buffer_size = strlen (dir_name) + NAME_FIELD_SIZE;
+ name_buffer_size = strlen (dir) + NAME_FIELD_SIZE;
name_buffer = xmalloc (name_buffer_size + 2);
- strcpy (name_buffer, dir_name);
- if (! ISSLASH (dir_name[strlen (dir_name) - 1]))
+ strcpy (name_buffer, dir);
+ if (! ISSLASH (dir[strlen (dir) - 1]))
strcat (name_buffer, "/");
name_length = strlen (name_buffer);
return NULL;
}
- directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false);
+ directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false,
+ NULL);
if (dirp && directory->children != NO_CHILDREN)
{
}
strcpy (name_buffer + name_length, entry + 1);
- if (excluded_name (name_buffer))
+ if (*entry == 'I') /* Ignored entry */
+ *entry = 'N';
+ else if (excluded_name (name_buffer))
*entry = 'N';
else
{
if (S_ISDIR (stat_data.st_mode))
{
+ *entry = 'D';
procdir (name_buffer, &stat_data, device,
directory->children,
- verbose_option);
- *entry = 'D';
+ verbose_option, entry);
}
else if (one_file_system_option && device != stat_data.st_dev)
}
char *
-get_directory_contents (char *dir_name, dev_t device)
+get_directory_contents (char *dir, dev_t device)
{
- return scan_directory (dir_name, device);
+ return scan_directory (dir, device);
}
\f
static void
obstack_code_rename (struct obstack *stk, char *from, char *to)
{
+ char *s;
+
+ s = from[0] == 0 ? from :
+ safer_name_suffix (from, false, absolute_names_option);
obstack_1grow (stk, 'R');
- obstack_grow (stk, from, strlen (from) + 1);
+ obstack_grow (stk, s, strlen (s) + 1);
+
+ s = to[0] == 0 ? to:
+ safer_name_suffix (to, false, absolute_names_option);
obstack_1grow (stk, 'T');
- obstack_grow (stk, to, strlen (to) + 1);
+ obstack_grow (stk, s, strlen (s) + 1);
}
static bool
arc += strlen (arc) + 1;
dst = arc + 1;
+ /* Ensure that neither source nor destination are absolute file
+ names (unless permitted by -P option), and that they do not
+ contain dubious parts (e.g. ../).
+
+ This is an extra safety precaution. Besides, it might be
+ necessary to extract from archives created with tar versions
+ prior to 1.19. */
+
+ if (*src)
+ src = safer_name_suffix (src, false, absolute_names_option);
+ if (*dst)
+ dst = safer_name_suffix (dst, false, absolute_names_option);
+
if (*src == 0)
src = temp_stub;
else if (*dst == 0)