-$Id: TODO,v 1.17 2001/02/16 14:16:54 stelian Exp $
+$Id: TODO,v 1.18 2001/04/10 13:42:21 stelian Exp $
Need to verify:
---------------
All others:
-----------
-1. Make dump able to backup several directories and/or files in one
- invocation, like the SunOS version.
+1. More documentation? Examples, crontab?
-2. More documentation? Examples, crontab?
-
-3. Explore and correct dump problems on active filesystems
+2. Explore and correct dump problems on active filesystems
(lseek/read negative count) (This should be OK as of 0.4b14.
Unfortunately, this seems to continue for a very few users).
-4. Reimplement the ext2 specific code in a "backend" and
+3. Reimplement the ext2 specific code in a "backend" and
make the dump code more generic. This would allow creation
of other backends for other filesystems. Implementing a
(v)fat backend should be quite easy, as for BSD ffs (we
already have the code for this). The BSD code in traverse.c
(all those #ifdef _BSD) should go into the ffs backend.
-5. Implement a DEBUG option which doesn't fork on each tape, making
+4. Implement a DEBUG option which doesn't fork on each tape, making
it able to debug dump with gdb.
-6. Add a compression mode using zlib on each file (see
- http://www.cdrom.com/pub/infozip/zlib).
+5. Extend the compression patch to use bzip2.
-7. Make a bootable dump tape? I don't know if it is possible...
+6. Make a bootable dump tape? I don't know if it is possible...
-8. From Kjetil Torgrim Homme <kjetilho@ifi.uio.no>:
+7. From Kjetil Torgrim Homme <kjetilho@ifi.uio.no>:
a archive_file
Archive file. Archive a dump table-of-contents in
the specified archive_file to be used by
ufsrestore(1M) to determine whether a file is in
the dump file that is being restored.
-9. Modify (or get rid of) rmt in order to work with non Linux
+8. Modify (or get rid of) rmt in order to work with non Linux
systems (limited succes has been reported). A good version
of rmt to be looked at is part of star
http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/star.html
-10. Rework the makefiles, actually --prefix doesn't work in
- configure. Maybe use automake in the same step ?
-
-11. EA/ACL support in dump (requested by Michael Ju. Tokarev
+9. EA/ACL support in dump (requested by Michael Ju. Tokarev
<mjt@tls.msk.ru>.
+10. Better readline completition in restore (escape spaces etc).
#ifndef lint
static const char rcsid[] =
- "$Id: main.c,v 1.42 2001/04/10 12:46:53 stelian Exp $";
+ "$Id: main.c,v 1.43 2001/04/10 13:42:22 stelian Exp $";
#endif /* not lint */
#include <config.h>
register int ch;
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
dump_ino_t maxino;
+ struct stat statbuf;
+ dev_t filedev;
#ifdef __linux__
errcode_t retval;
char directory[MAXPATHLEN];
if (ntrec > maxbsize/1024) {
msg("Please choose a blocksize <= %dkB\n",
maxbsize/1024);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
bflag = 1;
/* 04-Feb-00 ILC */
case 'e': /* exclude an inode */
if (iexclude_num == IEXCLUDE_MAXNUM) {
- (void)fprintf(stderr, "Too many -e options\n");
+ msg("Too many -e options\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
iexclude_list[iexclude_num++] = numarg("inode to exclude",0L,0L);
if (iexclude_list[iexclude_num-1] <= ROOTINO) {
- (void)fprintf(stderr, "Cannot exclude inode %ld\n", (long)iexclude_list[iexclude_num-1]);
+ msg("Cannot exclude inode %ld\n", (long)iexclude_list[iexclude_num-1]);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
msg("Added %d to exclude list\n",
case 'T': /* time of last dump */
spcl.c_ddate = unctime(optarg);
if (spcl.c_ddate < 0) {
- (void)fprintf(stderr, "bad time \"%s\"\n",
- optarg);
+ msg("bad time \"%s\"\n", optarg);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
Tflag = 1;
argv += optind;
if (argc < 1) {
- (void)fprintf(stderr, "Must specify disk or filesystem\n");
+ msg("Must specify disk or filesystem\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
diskparam = *argv++;
if (strlen(diskparam) >= MAXPATHLEN) {
- (void)fprintf(stderr, "Disk or filesystem name too long: %s\n",
- diskparam);
+ msg("Disk or filesystem name too long: %s\n", diskparam);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
argc--;
- if (argc >= 1) {
- (void)fprintf(stderr, "Unknown arguments to dump:");
- while (argc--)
- (void)fprintf(stderr, " %s", *argv++);
- (void)fprintf(stderr, "\n");
- exit(X_STARTUP);
- }
if (Tflag && uflag) {
- (void)fprintf(stderr,
- "You cannot use the T and u flags together.\n");
+ msg("You cannot use the T and u flags together.\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
if (strcmp(tapeprefix, "-") == 0) {
*tapeprefix++ = '\0';
#ifdef RDUMP
if (index(tapeprefix, '\n')) {
- (void)fprintf(stderr, "invalid characters in tape\n");
- exit(X_STARTUP);
+ msg("invalid characters in tape\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
}
if (rmthost(host) == 0)
exit(X_STARTUP);
#else
- (void)fprintf(stderr, "remote dump not enabled\n");
+ msg("remote dump not enabled\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
#endif
}
of LABEL= or UID= but it was not
found */
msg("Cannot find a disk having %s\n", diskparam);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
/*
* the file system name with or without the leading '/'.
*/
if ((dt = fstabsearch(disk)) != NULL) {
+ /* if found then only one parameter (i.e. partition)
+ * is allowed */
+ if (argc >= 1) {
+ (void)fprintf(stderr, "Unknown arguments to dump:");
+ while (argc--)
+ (void)fprintf(stderr, " %s", *argv++);
+ (void)fprintf(stderr, "\n");
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
disk = rawname(dt->fs_spec);
(void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
(void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
if (directory[0] != 0) {
if (level != '0') {
- (void)fprintf(stderr, "Only level 0 dumps are allowed on a subdirectory\n");
+ msg("Only level 0 dumps are allowed on a subdirectory\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
if (uflag) {
- (void)fprintf(stderr, "You can't update the dumpdates file when dumping a subdirectory\n");
+ msg("You can't update the dumpdates file when dumping a subdirectory\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
}
if (retval) {
com_err(disk, retval, "while opening filesystem");
if (retval == EXT2_ET_REV_TOO_HIGH)
- printf ("Get a newer version of dump!\n");
+ msg("Get a newer version of dump!\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
if (fs->super->s_rev_level > DUMP_CURRENT_REV) {
com_err(disk, retval, "while opening filesystem");
- printf ("Get a newer version of dump!\n");
+ msg("Get a newer version of dump!\n");
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
if ((diskfd = open(disk, O_RDONLY)) < 0) {
msg("Cannot open %s\n", disk);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
/* if no user label specified, use ext2 filesystem label if available */
#else /* __linux __*/
if ((diskfd = open(disk, O_RDONLY)) < 0) {
msg("Cannot open %s\n", disk);
+ msg("The ENTIRE dump is aborted.\n");
exit(X_STARTUP);
}
sync();
#ifdef __linux__
if (directory[0] == 0)
anydirskipped = mapfiles(maxino, &tapesize);
- else
- anydirskipped = mapfilesfromdir(maxino, &tapesize, directory);
+ else {
+ if (stat(pathname, &statbuf) == -1) {
+ msg("File cannot be accessed (%s).\n", pathname);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ filedev = statbuf.st_dev;
+ if (!(statbuf.st_mode & S_IFDIR)) /* is a file */
+ anydirskipped = maponefile(maxino, &tapesize,
+ directory);
+ else
+ anydirskipped = mapfilesfromdir(maxino, &tapesize,
+ directory);
+ }
+ while (argc--) {
+ int anydirskipped2;
+ char *p = *argv;
+ /* check if file is available */
+ if (stat(p, &statbuf) == -1) {
+ msg("File cannot be accessed (%s).\n", p);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ /* check if file is on same unix partiton as the first
+ * argument */
+ if (statbuf.st_dev != filedev) {
+ msg("Files are not on same file system (%s).\n", p);
+ msg("The ENTIRE dump is aborted.\n");
+ exit(X_STARTUP);
+ }
+ /* check if file is a directory */
+ if (!(statbuf.st_mode & S_IFDIR))
+ anydirskipped2 = maponefile(maxino, &tapesize,
+ p+strlen(dt->fs_file));
+ else
+ /* read directory inodes.
+ * NOTE: nested directories are not recognized
+ * so inodes may be umped twice!
+ */
+ anydirskipped2 = mapfilesfromdir(maxino, &tapesize,
+ p+strlen(dt->fs_file));
+ if (!anydirskipped)
+ anydirskipped = anydirskipped2;
+ argv++;
+ }
#else
anydirskipped = mapfiles(maxino, &tapesize);
#endif
#ifndef lint
static const char rcsid[] =
- "$Id: traverse.c,v 1.31 2001/03/28 12:59:48 stelian Exp $";
+ "$Id: traverse.c,v 1.32 2001/04/10 13:42:22 stelian Exp $";
#endif /* not lint */
#include <config.h>
}
#endif /* __linux__ */
+#ifdef __linux__
+int
+maponefile(dump_ino_t maxino, long *tapesize, char *directory)
+{
+ errcode_t retval;
+ ext2_ino_t dir_ino;
+ char dir_name [MAXPATHLEN];
+ int i, anydirskipped = 0;
+
+ /*
+ * Mark every directory in the path as being dumped
+ */
+ for (i = 0; i < strlen (directory); i++) {
+ if (directory[i] == '/') {
+ strncpy (dir_name, directory, i);
+ dir_name[i] = '\0';
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO,
+ dir_name, &dir_ino);
+ if (retval) {
+ com_err(disk, retval,
+ "while translating %s", dir_name);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t) dir_ino, 0,
+ tapesize, &anydirskipped);
+ }
+ }
+ /*
+ * Mark the final directory
+ */
+ retval = ext2fs_namei(fs, ROOTINO, ROOTINO, directory, &dir_ino);
+ if (retval) {
+ com_err(disk, retval, "while translating %s", directory);
+ exit(X_ABORT);
+ }
+ mapfileino((dump_ino_t)dir_ino, 0, tapesize, &anydirskipped);
+
+ mapfileino(ROOTINO, 0, tapesize, &anydirskipped);
+
+ /*
+ * Restore gets very upset if the root is not dumped,
+ * so ensure that it always is dumped.
+ */
+ SETINO(ROOTINO, dumpdirmap);
+ return anydirskipped;
+}
+#endif /* __linux__ */
+
#ifdef __linux__
struct mapfile_context {
long *tapesize;