]> git.wh0rd.org - dump.git/commitdiff
From Uwe Gohlke:
authorStelian Pop <stelian@popies.net>
Sun, 26 Oct 2003 16:05:44 +0000 (16:05 +0000)
committerStelian Pop <stelian@popies.net>
Sun, 26 Oct 2003 16:05:44 +0000 (16:05 +0000)
* compile under Solaris
* restore MacOSX made dumps
* made rmt work with local/remote QFA.

26 files changed:
CHANGES
common/dumprmt.c
compat/include/bsdcompat.h
compat/include/pathnames.h
compat/include/protocols/dumprestore.h
compat/lib/bylabel.c
compat/lib/compaterr.c
compat/lib/compatglob.c
config.h.in
configure
configure.in
dump/dump.h
dump/itime.c
dump/main.c
dump/tape.c
dump/traverse.c
restore/dirs.c
restore/extern.h
restore/interactive.c
restore/main.c
restore/restore.c
restore/restore.h
restore/symtab.c
restore/tape.c
restore/utilities.c
rmt/rmt.c

diff --git a/CHANGES b/CHANGES
index 06baed279ba41ce5f0d0d5c888e783dd99408879..8a16dfa43da031b087c34c1c8137d0a4a31ec04c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.232 2003/09/03 15:00:21 stelian Exp $
+$Id: CHANGES,v 1.233 2003/10/26 16:05:44 stelian Exp $
 
 Changes between versions 0.4b34 and 0.4b35 (released ??????????????)
 ====================================================================
@@ -22,6 +22,21 @@ Changes between versions 0.4b34 and 0.4b35 (released ??????????????)
        different signature. Thanks to Mike Harris <mharris@redhat.com>
        for reporting this bug.
 
+5.     Made dump/restore build on Solaris, making possible to
+       restore Linux's "enhanced" tapes. Thanks to Uwe Gohlke
+       <uwe@ugsoft.de> for the patch.
+
+6.     Made an extension in the dump tape format capable of saving
+       MacOSX specific inode extensions. Uwe Gohlke <uwe@ugsoft.de>
+       wrote the extension and contributed the restore code back
+       into this codebase. The same extension mechanism will be
+       used in the future to save ACLs...
+
+7.     Made rmt work correctly with regard to QFA and local/remote
+       files and tapes. The remote access will however work only 
+       when the dump provided rmt version is used. If you want to
+       use another rmt server, please do not use the QFA feature.
+
 Changes between versions 0.4b33 and 0.4b34 (released April 18, 2003)
 ====================================================================
 
index eb61a55c9a4ced0db589b507249058fa887ca6b8..7f88f63a9fb95851eec469556015230170bde7ac 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: dumprmt.c,v 1.27 2003/03/30 15:40:33 stelian Exp $";
+       "$Id: dumprmt.c,v 1.28 2003/10/26 16:05:45 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -114,6 +114,8 @@ int krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *));
 static int errfd = -1;
 extern int dokerberos;
 extern int ntrec;              /* blocking factor on tape */
+extern int abortifconnerr;     /* set to 1 if this lib should exit on connection errors
+                                otherwise just print a message using msg */
 #ifndef errno
 extern int errno;
 #endif
@@ -152,8 +154,8 @@ rmtconnaborted(UNUSED(int signo))
                        }
                }
        }
-
-       exit(X_ABORT);
+       if (abortifconnerr)
+               exit(X_ABORT);
 }
 
 static int
@@ -174,20 +176,36 @@ rmtgetconn(void)
 
        if (!rsh && sp == NULL) {
                sp = getservbyname(dokerberos ? "kshell" : "shell", "tcp");
-               if (sp == NULL)
-                       errx(1, "%s/tcp: unknown service",
-                           dokerberos ? "kshell" : "shell");
+               if (sp == NULL) {
+                       if (abortifconnerr) {
+                               errx(1, "%s/tcp: unknown service", dokerberos ? "kshell" : "shell");
+                       } else {
+                               msg("%s/tcp: unknown service", dokerberos ? "kshell" : "shell");
+                               return 0;
+                       }
+               }
        }
        if (pwd == NULL) {
                pwd = getpwuid(getuid());
-               if (pwd == NULL)
-                       errx(1, "who are you?");
+               if (pwd == NULL) {
+                       if (abortifconnerr) {
+                               errx(1, "who are you?");
+                       } else {
+                               msg("who are you?");
+                               return 0;
+                       }
+               }
        }
        if ((cp = strchr(rmtpeer, '@')) != NULL) {
                tuser = rmtpeer;
                *cp = '\0';
-               if (!okname(tuser))
-                       exit(X_STARTUP);
+               if (!okname(tuser)) {
+                       if (abortifconnerr) {
+                               exit(X_STARTUP);
+                       } else {
+                               return 0;
+                       }
+               }
                rmtpeer = ++cp;
        } else
                tuser = pwd->pw_name;
@@ -250,7 +268,7 @@ rmtgetconn(void)
                        perror("TCP_NODELAY setsockopt");
                fromrmtape = tormtape;
        }
-       (void)fprintf(stderr, "Connection to %s established.\n", rmtpeer);
+       (void)fprintf(stdout, "Connection to %s established.\n", rmtpeer);
        return 1;
 }
 
@@ -305,9 +323,11 @@ rmtread(char *buf, size_t count)
 
        (void)snprintf(line, sizeof (line), "R%u\n", (unsigned)count);
        n = rmtcall("read", line);
-       if (n < 0)
+       if (n < 0) {
                /* rmtcall() properly sets errno for us on errors. */
-               return (n);
+               errno = n;
+               return (-1);
+       }
        for (i = 0; i < n; i += cc) {
                cc = read(fromrmtape, buf+i, n - i);
                if (cc <= 0)
index ecb102f4d9eceb097b6a2175a0be4f57fc13fc32..0edf00db24009f3374303f7401b1d676e78beb7f 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: bsdcompat.h,v 1.19 2002/07/19 14:57:39 stelian Exp $
+ *     $Id: bsdcompat.h,v 1.20 2003/10/26 16:05:46 stelian Exp $
  */
 
 #include <config.h>
 #define        WINO            1
 #define        DEV_BSIZE       512
 #define        DEV_BSHIFT      9
+
+#ifndef sunos
 #define        MAXBSIZE        EXT2_MAX_BLOCK_SIZE
 #define ROOTINO                EXT2_ROOT_INO
+#else
+#define ROOTINO                2
+#endif
 #ifdef EXT2_NODUMP_FL
 #define UF_NODUMP      EXT2_NODUMP_FL
 #endif
@@ -36,7 +41,6 @@
 #define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
 #define powerof2(x)    ((((x)-1)&(x))==0)
 
-#define dbtob(b)       ((unsigned)(b) << DEV_BSHIFT)
 #define fsbtodb(sb,b)  ((int)(((long long)(b) * EXT2_BLOCK_SIZE((sb)->super)) / DEV_BSIZE))
 #define dbtofsb(sb,b)  ((int)(((long long)(b) * DEV_BSIZE) / EXT2_BLOCK_SIZE((sb)->super)))
 
@@ -75,6 +79,25 @@ typedef __u64                u_quad_t;
 
 #define NINDIR(fs)     EXT2_ADDR_PER_BLOCK(fs->super)
 
+#ifdef sunos
+typedef uint8_t __u8;
+typedef uint16_t __u16;
+typedef uint32_t __u32;
+typedef int8_t __s8;
+typedef int16_t __s16;
+typedef int32_t __s32;
+#ifndef u_int
+#typedef unsigned int u_int;
+#endif
+#ifndef u_int16_t
+typedef unsigned short u_int16_t;
+#endif
+#ifndef u_char
+typedef unsigned char u_char;
+#endif
+typedef int64_t quad_t;
+#endif /* sunos */
+
 struct dinode {
        __u16   di_mode;
        __u16   di_uid;
@@ -118,6 +141,10 @@ struct dinode {
 #define MAXNAMLEN      255
 #endif
 
+#ifdef sunos
+#define MAXNAMLEN      255
+#endif
+
 /*
  * For old libc.
  */
@@ -130,6 +157,10 @@ struct dinode {
 #define DT_REG          8
 #define DT_LNK         10
 #define DT_SOCK                12
+
+#ifdef sunos
+#define DT_WHT         14
+#endif
 #endif
 
 #ifndef d_fileno
@@ -158,20 +189,23 @@ struct direct {
  * without the d_name field, plus enough space for the name with a terminating
  * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
  */
+#ifdef __linux__
 #if    0
 #if (BYTE_ORDER == LITTLE_ENDIAN)
 #define DIRSIZ(oldfmt, dp) \
     ((oldfmt) ? \
     ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \
     ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)))
-#else
+#else /* BYTE_ORDER */
 #define DIRSIZ(oldfmt, dp) \
     ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
 #endif
-#else
-
+#else /* 0 */
 #define DIRSIZ(oldfmt,dp)      EXT2_DIR_REC_LEN(((dp)->d_namlen & 0xff) + 1)
-
+#endif
+#else /* __linux__ */
+#define DIRSIZ(oldfmt, dp) \
+       ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
 #endif
 
 /*
index afaa14ddfcf2cfb642a04d088a1843557de1e341..281d204671cfaf7be24314b6fd19701ff05f1ce0 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: pathnames.h,v 1.13 2003/03/30 15:40:34 stelian Exp $
+ *     $Id: pathnames.h,v 1.14 2003/10/26 16:05:46 stelian Exp $
  */
 
 /*
 #endif
 
 #ifndef _PATH_DEFTAPE
+#ifdef __linux__
 #define        _PATH_DEFTAPE   "/dev/st0"
 #endif
+#ifdef sunos
+#define        _PATH_DEFTAPE   "/dev/rmt/0"
+#endif
+#endif
 
 #define        _PATH_RMT       "/etc/rmt"              /* path on remote host */
index f616e3153c5a46d47e9a7a5acca1c4453615b82f..9c6844fd52f2eca58fdb71f4f121720a631487a7 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: dumprestore.h,v 1.19 2003/03/31 09:42:57 stelian Exp $
+ *     $Id: dumprestore.h,v 1.20 2003/10/26 16:05:46 stelian Exp $
  */
 
 /*
 #define NFS_MAGIC      (int)60012
 #define CHECKSUM       (int)84446
 
+#ifdef __linux__
 typedef u_int32_t      dump_ino_t;
+#endif
+
+#ifdef sunos
+typedef unsigned int   dump_ino_t;
+#endif
 
 union u_data {
        char    s_addrs[TP_NINDIR];     /* 1 => data; 0 => hole in inode */
@@ -91,8 +97,12 @@ union u_spcl {
                int32_t c_checksum;         /* record checksum */
 #ifdef __linux__
                struct  new_bsd_inode c_dinode;
+#else
+#ifdef sunos
+               struct  new_bsd_inode c_dinode;
 #else
                struct  dinode  c_dinode;   /* ownership and mode of inode */
+#endif
 #endif
                int32_t c_count;            /* number of valid c_addr entries */
                union u_data c_data;        /* see above */
@@ -104,7 +114,8 @@ union u_spcl {
                int32_t c_flags;            /* additional information */
                int32_t c_firstrec;         /* first record on volume */
                int32_t c_ntrec;            /* blocksize on volume */
-               int32_t c_spare[31];        /* reserved for future uses */
+                int32_t        c_extattributes;    /* additional inode info */
+                int32_t        c_spare[30];        /* reserved for future uses */
        } s_spcl;
 } u_spcl;
 #define spcl u_spcl.s_spcl
@@ -130,6 +141,15 @@ union u_spcl {
 #define DR_METAONLY    0x0100  /* only the metadata of the inode has
                                   been dumped */
 #define DR_INODEINFO   0x0002  /* TS_END header contains c_inos information */
+#define DR_EXTATTRIBUTES       0x8000
+
+/*
+ * extattributes inode info
+ */
+#define EXT_REGULAR            0
+#define EXT_MACOSFNDRINFO      1
+#define EXT_MACOSRESFORK       2
+#define EXT_ACL                        3
 
 
 /*
@@ -144,7 +164,11 @@ struct tapebuf {
        unsigned int    compressed:1;
        unsigned int    flags:3;
        unsigned int    length:28;
+#ifdef sunos
+       char            buf;
+#else
        char            buf[0]; /* the data */
+#endif
 };
 
 #endif /* !_DUMPRESTORE_H_ */
index 7f710ed7655e7196cef4a528cb5c92a242dc48e9..96fe9181d94c80541ef74da01745cad2b5937031 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <config.h>
 #include <compatlfs.h>
+#include <sys/types.h>
 #include <stdio.h>
 #include <sys/param.h>
 #include <string.h>
@@ -20,6 +21,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <malloc.h>
+#include <sys/cdefs.h>
 #include "bylabel.h"
 
 #define PROC_PARTITIONS "/proc/partitions"
index 6cd4c5f72b5d4a0afa27330cf32ae1335f9fafa8..8ae4686e56c49910d318085ab4663e13d39d96c4 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: compaterr.c,v 1.10 2003/03/30 15:40:35 stelian Exp $";
+       "$Id: compaterr.c,v 1.11 2003/10/26 16:05:46 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <sys/types.h>
 #include <compaterr.h>
 #include <errno.h>
 #include <stdio.h>
index 4a83a2f75d07df75fc65d9e235a6eb45635bc176..8cf77eaa96447a97c8683aca3702aec8ee261482 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: compatglob.c,v 1.9 2003/03/30 15:40:35 stelian Exp $";
+       "$Id: compatglob.c,v 1.10 2003/10/26 16:05:46 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <sys/types.h>
 
 #ifndef HAVE_GLOB
 
@@ -358,7 +359,7 @@ globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob)
                 * the password file
                 */
                if (
-#ifndef __linux__
+#if !defined(__linux__) && !defined(sunos)
 #ifndef        __NETBSD_SYSCALLS
                    issetugid() != 0 ||
 #endif
index 0faf4ca7b91c9bbafeb8517b7f3b63ad2de24a87..18943d203cdd57f79e012b80374130342e2be724 100644 (file)
@@ -3,6 +3,9 @@
 /* Define this if you want to include Quick File Access debugging code. */
 #undef DEBUG_QFA
 
+/* Define this if you want to include Mac OSX restore compatibility. */
+#undef DUMP_MACOSX
+
 /* Define this if you have bzlib compression library. */
 #undef HAVE_BZLIB
 
index 84dac8b640520873cb610b613742e2d88071b533..5e61ddd1e44e24ddb81d48460a5f4958b10f1105 100755 (executable)
--- a/configure
+++ b/configure
@@ -849,6 +849,7 @@ Optional Features:
   --enable-largefile         enable Large File System support (default is YES)
   --enable-qfa               enable Quick File Access support (default is YES)
   --enable-qfadebug          include Quick File Access debugging code (default is NO)
+  --enable-macosx            include Mac OSX restore compatibility (default is NO)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -3508,6 +3509,27 @@ else
 
 fi;
 
+# Check whether --enable-macosx or --disable-macosx was given.
+if test "${enable_macosx+set}" = set; then
+  enableval="$enable_macosx"
+  if test "$enableval" = "yes"
+then
+
+cat >>confdefs.h <<\_ACEOF
+#define DUMP_MACOSX 1
+_ACEOF
+
+       echo "Including Mac OSX restore compatibility code"
+else
+       echo "Not including Mac OSX restore compatibility code"
+fi
+
+else
+  echo "Not including Mac OSX restore compatibility code by default"
+
+fi;
+
+
 
 # Check whether --with-cc or --without-cc was given.
 if test "${with_cc+set}" = set; then
index 4bc4abd93778ccc0364b295adeeafa136c6a8c3c..94aedbf50fb9b9a4eae1226a444da4be95976d66 100644 (file)
@@ -220,6 +220,23 @@ fi
 echo "Not including Quick File Access debugging code by default"
 )
 
+dnl
+dnl Handle --enable-macosx
+dnl
+AC_ARG_ENABLE([macosx],
+[  --enable-macosx            include Mac OSX restore compatibility (default is NO)],
+if test "$enableval" = "yes"
+then
+       AC_DEFINE([DUMP_MACOSX],1,[Define this if you want to include Mac OSX restore compatibility.])
+       echo "Including Mac OSX restore compatibility code"
+else
+       echo "Not including Mac OSX restore compatibility code"
+fi
+,
+echo "Not including Mac OSX restore compatibility code by default"
+)
+
+
 dnl
 dnl set $(CC) from --with-cc=value
 dnl
index 1c3c42572a663995eef30aae52daddac4e9091ec..5b052c8a592a4d65e810325119e58678b2366808 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: dump.h,v 1.46 2003/05/12 14:16:39 stelian Exp $
+ *     $Id: dump.h,v 1.47 2003/10/26 16:05:46 stelian Exp $
  */
 
 /*-
@@ -263,6 +263,15 @@ extern int errno;
 int dump_fs_open(const char *disk, ext2_filsys *fs);
 #endif
 
+#ifndef        __linux__
+#ifndef        _PATH_UTMP
+#define        _PATH_UTMP      "/etc/utmp"
+#endif
+#ifndef        _PATH_FSTAB
+#define        _PATH_FSTAB     "/etc/fstab"
+#endif
+#endif
+
 #ifdef sunos
 extern char *calloc();
 extern char *malloc();
index 6f59a8502979bdd48993cc8188419265068bf03d..7187d0033dab3873f201a5683aa408d299513f75 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: itime.c,v 1.25 2003/03/30 15:40:36 stelian Exp $";
+       "$Id: itime.c,v 1.26 2003/10/26 16:05:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -52,7 +52,6 @@ static const char rcsid[] =
 #include <sys/param.h>
 #include <sys/time.h>
 #include <time.h>
-#include <fcntl.h>
 #ifdef __linux__
 #ifdef HAVE_EXT2FS_EXT2_FS_H
 #include <ext2fs/ext2_fs.h>
index 007a37d8b0fbc97171de505be17f4fe4d07e3cdd..1bb5ca3abc3c2512ba76b1cf169173aed7842fd9 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.86 2003/05/12 14:16:39 stelian Exp $";
+       "$Id: main.c,v 1.87 2003/10/26 16:05:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -45,6 +45,7 @@ static const char rcsid[] =
 #include <ctype.h>
 #include <compaterr.h>
 #include <fcntl.h>
+#include <fstab.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,6 +66,7 @@ static const char rcsid[] =
 #include <ext2fs/ext2fs.h>
 #include <sys/stat.h>
 #include <bsdcompat.h>
+#include <linux/fs.h>  /* for definition of BLKFLSBUF */
 #elif defined sunos
 #include <sys/vnode.h>
 
@@ -85,6 +87,8 @@ static const char rcsid[] =
 #define SBOFF (SBLOCK * DEV_BSIZE)
 #endif
 
+int abortifconnerr = 1;                /* set to 1 if lib dumprmt.o should exit on connection errors
+                                otherwise just print a message using msg */
 /*
  * Dump maps used to describe what is to be dumped.
  */
@@ -174,6 +178,8 @@ int compressed = 0; /* use zlib to compress the output, compress level 1-9 */
 long long bytes_written = 0; /* total bytes written */
 long   uncomprblks = 0;/* uncompressed blocks written */
 
+long smtc_errno;
+
 #ifdef __linux__
 char   *__progname;
 #endif
@@ -496,24 +502,36 @@ main(int argc, char *argv[])
                        tsize = cartridge ? 1700L*120L : 2300L*120L;
        }
 
-       if (strchr(tapeprefix, ':')) {
-               host = tapeprefix;
-               tapeprefix = strchr(host, ':');
-               *tapeprefix++ = '\0';
+       {
+               int i;
+               char *n;
+
+               if ((n = strchr(tapeprefix, ':'))) {
+                       for (i = 0; i < (n - tapeprefix); i++) {
+                               if (tapeprefix[i] == '/')
+                                       break;
+                       }
+                       if (tapeprefix[i] != '/') {
+                               host = tapeprefix;
+                               tapeprefix = strchr(host, ':');
+                               *tapeprefix++ = '\0';
 #ifdef RDUMP
-               if (index(tapeprefix, '\n')) {
-                       msg("invalid characters in tape\n");
-                       msg("The ENTIRE dump is aborted.\n");
-                       exit(X_STARTUP);
-               }
-               if (rmthost(host) == 0)
-                       exit(X_STARTUP);
+                               if (index(tapeprefix, '\n')) {
+                                       msg("invalid characters in tape\n");
+                                       msg("The ENTIRE dump is aborted.\n");
+                                       exit(X_STARTUP);
+                               }
+                               if (rmthost(host) == 0)
+                                       exit(X_STARTUP);
 #else
-               msg("remote dump not enabled\n");
-               msg("The ENTIRE dump is aborted.\n");
-               exit(X_STARTUP);
+                               msg("remote dump not enabled\n");
+                               msg("The ENTIRE dump is aborted.\n");
+                               exit(X_STARTUP);
 #endif
+                       }
+               }
        }
+
        (void)setuid(getuid()); /* rmthost() is the only reason to be setuid */
        if (Apath && (Afile = open(Apath, O_WRONLY|O_CREAT|O_TRUNC,
                                   S_IRUSR | S_IWUSR | S_IRGRP |
@@ -688,7 +706,7 @@ main(int argc, char *argv[])
                exit(X_STARTUP);
        }
 #ifdef BLKFLSBUF
-       (void)ioctl(diskfd, BLKFLSBUF);
+       (void)ioctl(diskfd, BLKFLSBUF, 0);
 #endif
        retval = dump_fs_open(disk, &fs);
        if (retval) {
index 1990be91bbb952a43c767f985abb3df27ab01775..a8affbb70817b8954e000d97bfdecf3368b7ad61 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.77 2003/04/18 07:47:57 stelian Exp $";
+       "$Id: tape.c,v 1.78 2003/10/26 16:05:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -60,6 +60,7 @@ int    write(), read();
 #ifdef __linux__
 #include <sys/types.h>
 #include <sys/time.h>
+#include <linux/fs.h>  /* for definition of BLKFLSBUF */
 #include <time.h>
 #endif
 #include <sys/param.h>
@@ -110,6 +111,7 @@ extern      int ntrec;              /* blocking factor on tape */
 extern int cartridge;
 char   *nexttape;
 extern  pid_t rshpid;
+int    eot_code = 1;
 long long tapea_bytes = 0;     /* bytes_written at start of current volume */
 static int magtapeout;         /* output is really a tape */
 
@@ -126,7 +128,8 @@ static      void killall __P((void));
 static void rollforward __P((void));
 #ifdef USE_QFA
 static int GetTapePos __P((long long *));
-static void MkTapeString __P((struct s_spcl *, long long));
+static int MkTapeString __P((struct s_spcl *, long long));
+#define FILESQFAPOS    20
 #endif
 
 /*
@@ -1096,6 +1099,9 @@ doslave(int cmd,
        long long curtapepos;
        union u_spcl *uspclptr;
        struct s_spcl *spclptr;
+       /* long         maxntrecs = 300000000 / (ntrec * 1024);  last tested: 50 000 000 */
+       long            maxntrecs = 50000;      /* every 50MB */
+       long            cntntrecs = maxntrecs;
 #endif /* USE_QFA */
        sigset_t set;
 
@@ -1112,7 +1118,7 @@ doslave(int cmd,
                quit("slave couldn't reopen disk: %s\n", strerror(errno));
 #ifdef __linux__
 #ifdef BLKFLSBUF
-       (void)ioctl(diskfd, BLKFLSBUF);
+       (void)ioctl(diskfd, BLKFLSBUF, 0);
 #endif
        ext2fs_close(fs);
        retval = dump_fs_open(disk, &fs);
@@ -1277,23 +1283,30 @@ doslave(int cmd,
 #ifdef USE_QFA
                if (gTapeposfd >= 0) {
                        int i;
-                       int firstpass = 1;
-                       for (i = 0; i < ntrec; ++i) {
+                       int foundone = 0;
+
+                       for (i = 0; (i < ntrec) && !foundone; ++i) {
                                uspclptr = (union u_spcl *)&slp->tblock[i];
                                spclptr = &uspclptr->s_spcl;
                                if ((spclptr->c_magic == NFS_MAGIC) && 
-                                   (spclptr->c_type == TS_INODE) &&
-                                   ((spclptr->c_dinode.di_mode & S_IFMT) != IFDIR) &&
-                                   (spclptr->c_date == gThisDumpDate)) {
-                                       /* if an error occured previously don't
-                                        * try again */
-                                       if (firstpass) {
-                                               firstpass = 0;
+                                                       (spclptr->c_type == TS_INODE) &&
+                                                       (spclptr->c_date == gThisDumpDate) &&
+                                                       !(spclptr->c_dinode.di_mode & S_IFDIR)
+                                               ) {
+                                       foundone = 1;
+                                       /* if (cntntrecs >= maxntrecs) {         only write every maxntrecs amount of data */
+                                               cntntrecs = 0;
                                                if (gtperr == 0) 
                                                        gtperr = GetTapePos(&curtapepos);
-                                       }
-                                       if (gtperr == 0)
-                                                       MkTapeString(spclptr, curtapepos);
+                                               /* if an error occured previously don't
+                                                * try again */
+                                               if (gtperr == 0) {
+#ifdef DEBUG_QFA
+                                                       msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos);
+#endif
+                                                       gtperr = MkTapeString(spclptr, curtapepos);
+                                               }
+                                       /* } */
                                }
                        }
                }
@@ -1350,6 +1363,11 @@ doslave(int cmd,
                 * Signal the next slave to go.
                 */
                (void) kill(nextslave, SIGUSR2);
+#ifdef USE_QFA
+               if (gTapeposfd >= 0) {
+                       cntntrecs += ntrec;
+               }
+#endif /* USE_QFA */
        }
        if (nread != 0)
                quit("error reading command pipe: %s\n", strerror(errno));
@@ -1386,11 +1404,31 @@ dump_atomic_write(int fd, const void *buf, size_t count)
                while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
                        (char *)buf += got;
        } while (got == -1 && errno == EINTR);
-       return (got < 0 ? got : (ssize_t)count - need);
+       return (got < 0 ? got : count - need);
 }
 
 
+/*
+int
+SetLogicalPos(void)
+{
+       int     err = 0;
+       struct mt_pos buf;
+
+       buf.mt_op = MTSETDRVBUFFER;
+       buf.mt_count = MT_ST_BOOLEANS | MT_ST_SCSI2LOGICAL;
+       if (ioctl(tapefd, MTIOCTOP, &buf) == -1) {
+               err = errno;
+               msg("[%ld] error: %d (setting logical)\n", 
+                       (unsigned long)getpid(), err);
+       }
+       return err;
+}
+*/
+
 #ifdef USE_QFA
+#define LSEEK_GET_TAPEPOS      10
+#define LSEEK_GO2_TAPEPOS      11
 /*
  * read the current tape position
  */
@@ -1401,7 +1439,7 @@ GetTapePos(long long *pos)
 
 #ifdef RDUMP
        if (host) {
-               *pos = (long long) rmtseek(0, SEEK_CUR);
+               *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS);
                err = *pos < 0;
        }
        else 
@@ -1427,8 +1465,10 @@ GetTapePos(long long *pos)
        return err;
 }
 
-static void 
-MkTapeString(struct s_spcl *spclptr, long long curtapepos) {
+static int 
+MkTapeString(struct s_spcl *spclptr, long long curtapepos)
+{
+       int     err = 0;
 
 #ifdef DEBUG_QFA
        msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos);
@@ -1440,7 +1480,9 @@ MkTapeString(struct s_spcl *spclptr, long long curtapepos) {
                 curtapepos);
        gTps[sizeof(gTps) - 1] = '\0';
        if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) {
-               warn("error writing tapepos file.\n");
+               err = errno;
+       warn("error writing tapepos file. (error %d)\n", errno);
        }
+       return err;
 }
 #endif /* USE_QFA */
index 3886b479ae14a0ef354e8db4311c0c372a497922..2142abc0c274d5c481dee154556c7909c28fa1ef 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: traverse.c,v 1.55 2003/03/30 15:40:37 stelian Exp $";
+       "$Id: traverse.c,v 1.56 2003/10/26 16:05:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -1238,7 +1238,7 @@ dumpmap(char *map, int type, dump_ino_t ino)
                writerec(cp, 0);
 }
 
-#if defined __linux__ && !defined(int32_t)
+#if defined(__linux__) && !defined(int32_t)
 #define int32_t __s32
 #endif
 
@@ -1311,7 +1311,7 @@ getino(dump_ino_t inum)
 /*
  * Read a chunk of data from the disk.
  * Try to recover from hard errors by reading in sector sized pieces.
- * Error recovery is attempted at most breademax times before seeking
+ * Error recovery is attempted at most BREADEMAX times before seeking
  * consent from the operator to continue.
  */
 int    breaderrors = 0;
index dc45e7c7545b4b140c415f5f3f6f743e6e2bf149..239248809daf0ac99630721b753c5499ba9e9d24 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: dirs.c,v 1.23 2003/03/30 15:40:38 stelian Exp $";
+       "$Id: dirs.c,v 1.24 2003/10/26 16:05:47 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <sys/types.h>
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/stat.h>
@@ -58,8 +59,13 @@ static const char rcsid[] =
 #endif
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
+#endif
 #endif /* __linux__ */
 #include <protocols/dumprestore.h>
 
@@ -73,8 +79,12 @@ static const char rcsid[] =
 #ifdef __linux__
 #include <endian.h>
 #else
+#ifdef sunos
+#include <arpa/nameser_compat.h>
+#else
 #include <machine/endian.h>
 #endif
+#endif
 
 #include "pathnames.h"
 #include "restore.h"
@@ -151,6 +161,10 @@ static void                 rst_seekdir __P((RST_DIR *, long, long));
 static long             rst_telldir __P((RST_DIR *));
 static struct direct   *searchdir __P((dump_ino_t, char *));
 
+#ifdef sunos
+extern int fdsmtc;
+#endif
+
 /*
  *     Extract directory contents, building up a directory structure
  *     on disk for extraction by name.
@@ -659,8 +673,11 @@ setdirmodes(int flags)
                        if (node.flags)
 #ifdef __linux__
                                (void) fsetflags(cp, node.flags);
+#else
+#ifdef sunos
 #else
                                (void) chflags(cp, node.flags);
+#endif
 #endif
                        utimes(cp, node.timep);
                        ep->e_flags &= ~NEW;
@@ -727,7 +744,7 @@ inodetype(dump_ino_t ino)
  * If requested, save its pertinent mode, owner, and time info.
  */
 static struct inotab *
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
 allocinotab(dump_ino_t ino, struct new_bsd_inode *dip, long seekpt)
 #else
 allocinotab(dump_ino_t ino, struct dinode *dip, long seekpt)
@@ -746,17 +763,17 @@ allocinotab(dump_ino_t ino, struct dinode *dip, long seekpt)
        if (mf == NULL)
                return (itp);
        node.ino = ino;
-#ifdef __linux__
+#if defined(__linux__) || defined(sunos)
        node.timep[0].tv_sec = dip->di_atime.tv_sec;
        node.timep[0].tv_usec = dip->di_atime.tv_usec;
        node.timep[1].tv_sec = dip->di_mtime.tv_sec;
        node.timep[1].tv_usec = dip->di_mtime.tv_usec;
-#else  /* __linux__ */
+#else  /* __linux__  || sunos */
        node.timep[0].tv_sec = dip->di_atime;
        node.timep[0].tv_usec = dip->di_atimensec / 1000;
        node.timep[1].tv_sec = dip->di_mtime;
        node.timep[1].tv_usec = dip->di_mtimensec / 1000;
-#endif /* __linux__ */
+#endif /* __linux__  || sunos */
        node.mode = dip->di_mode;
        node.flags = dip->di_flags;
        node.uid = dip->di_uid;
index bf811091436ad90270b68c0d3fc018344e232db5..e2702ed6587de0b58d6adbe985884c76d8a8691b 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: extern.h,v 1.22 2003/03/30 15:40:38 stelian Exp $
+ *     $Id: extern.h,v 1.23 2003/10/26 16:05:48 stelian Exp $
  */
 
 /*-
 
 #include <config.h>
 #include <compatlfs.h>
+#ifndef __P
+#include <sys/cdefs.h>
+#endif
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
 
 struct entry   *addentry __P((char *, dump_ino_t, int));
 long            addfile __P((char *, dump_ino_t, int));
@@ -131,5 +137,20 @@ int        GetTapePos __P((long long *));
 int    GotoTapePos __P((long long));
 void   ReReadFromTape __P((void));
 void   ReReadInodeFromTape __P((dump_ino_t));
+void    GetPathFile __P((char *, char *, char *));
+
+#ifdef sunos
+int            GetSCSIIDFromPath __P((char *, long *));
+int            OpenSMTCmt(char *);
+#endif
 #endif
 void   RequestVol __P((long));
+
+#ifdef DUMP_MACOSX
+int    extractfinderinfoufs __P((char *));
+int    extractresourceufs __P((char *));
+int    CreateAppleDoubleFileRes __P((char *, FndrFileInfo *, mode_t, int, struct timeval *, u_int32_t, u_int32_t));
+#endif
+
+
+
index 51cacb4d5780a548f03d8ef0e07f9605c0e6983a..ecbffda09e8a3dde54e457f666529feb24fa1253 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: interactive.c,v 1.26 2003/03/30 15:40:38 stelian Exp $";
+       "$Id: interactive.c,v 1.27 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <sys/types.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 
@@ -52,8 +53,13 @@ static const char rcsid[] =
 #endif
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
+#endif
 #endif /* __linux__ */
 #include <protocols/dumprestore.h>
 
@@ -67,6 +73,9 @@ static const char rcsid[] =
 
 #ifdef __linux__
 #include <ext2fs/ext2fs.h>
+#endif
+
+#if defined(__linux__) || defined(sunos)
 extern char * __progname;
 #endif
 
index 98674e4c8fc4c171cbef59a6489e3b436c4160f9..77b9d7daf13fd787e8b72633fa94da618c73ad45 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.44 2003/03/30 15:40:38 stelian Exp $";
+       "$Id: main.c,v 1.45 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #include <compatlfs.h>
+#include <sys/types.h>
 #include <fcntl.h>
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -59,7 +60,15 @@ static const char rcsid[] =
 #include <signal.h>
 #include <string.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <signal.h>
+#include <string.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#include <sys/mtio.h>
+#else
 #include <ufs/ufs/dinode.h>
+#endif
 #endif /* __linux__ */
 #include <protocols/dumprestore.h>
 
@@ -77,6 +86,9 @@ static const char rcsid[] =
 #include "restore.h"
 #include "extern.h"
 
+int abortifconnerr = 1;                /* set to 1 if lib dumprmt.o should exit on connection errors
+                                otherwise just print a message using msg */
+
 int    aflag = 0, bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
 int    hflag = 1, mflag = 1, Mflag = 0, Nflag = 0, Vflag = 0, zflag = 0;
 int    uflag = 0, lflag = 0, Lflag = 0, oflag = 0;
@@ -112,6 +124,8 @@ unsigned long qfadumpdate;
 long long curtapepos;
 #endif /* USE_QFA */
 
+long smtc_errno;
+
 #if defined(__linux__) || defined(sunos)
 char   *__progname;
 #endif
@@ -379,6 +393,18 @@ main(int argc, char *argv[])
                /* end reading header info */
                /* tape position table starts here */
                gSeekstart = ftell(gTapeposfp); /* remember for later use */
+#ifdef sunos
+               if (GetSCSIIDFromPath(inputdev, &scsiid)) {
+                       errx(1, "can't get SCSI-ID for %s\n", inputdev);
+               }
+               if (scsiid < 0) {
+                       errx(1, "can't get SCSI-ID for %s\n", inputdev);
+               }
+               sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+               if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+                       errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno);
+               }
+#endif
        }
 #endif /* USE_QFA */
 
@@ -535,6 +561,11 @@ main(int argc, char *argv[])
                setdirmodes(oflag ? FORCE : 0);
                if (dflag)
                        checkrestore();
+#ifdef sunos
+               if (fdsmtc != -1) {
+                       close(fdsmtc);
+               }
+#endif /* sunos */
 #ifdef DEBUG_QFA
                tiend = time(NULL);
                titaken = tiend - tistart;
@@ -547,6 +578,18 @@ main(int argc, char *argv[])
 #ifdef DEBUG_QFA
                tistart = time(NULL);
 #endif
+#ifdef sunos
+               if (GetSCSIIDFromPath(inputdev, &scsiid)) {
+                       errx(1, "can't get SCSI-ID for %s\n", inputdev);
+               }
+               if (scsiid < 0) {
+                       errx(1, "can't get SCSI-ID for %s\n", inputdev);
+               }
+               sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+               if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+                       errx(1, "can't open smtc device: %s, %d\n", smtcpath, errno);
+               }
+#endif /* sunos */
                setup();
                msg("writing QFA positions to %s\n", gTapeposfile);
                (void) umask(orig_umask);
@@ -556,7 +599,7 @@ main(int argc, char *argv[])
                        errx(1, "can't create tapeposfile\n");
                (void) umask(FORCED_UMASK);
                /* print QFA-file header */
-               sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION,(unsigned long)spcl.c_date);
+               sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
                if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
                        errx(1, "can't write tapeposfile\n");
                sprintf(gTps, "ino\ttapeno\ttapepos\n");
@@ -578,14 +621,19 @@ main(int argc, char *argv[])
                        treescan(name, ino, addfile);
                }
                createfiles();
+#ifdef sunos
+               if (fdsmtc != -1) {
+                       close(fdsmtc);
+               }
+#endif /* sunos */
 #ifdef DEBUG_QFA
                tiend = time(NULL);
                titaken = tiend - tistart;
-               msg("writing QFA positions took %d:%02d:%02d\n", titaken / 3600,
+               msg("writing QFA positions took %d:%02d:%02d\n", titaken / 3600, 
                        (titaken % 3600) / 60, titaken % 60);
 #endif /* DEBUG_QFA */
                break;
-#endif /* USE_QFA */
+#endif /* USE_QFA */
        }
        exit(0);
        /* NOTREACHED */
index 5ac6c870d56949ffe319a22414672f92c05869ce..9d18c6b621a6d491b0ff34428baacea535472636 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: restore.c,v 1.31 2003/03/30 15:40:39 stelian Exp $";
+       "$Id: restore.c,v 1.32 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -54,8 +54,14 @@ static const char rcsid[] =
 #endif
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
+#endif
 #endif /* __linux__ */
+
 #include <protocols/dumprestore.h>
 
 #include <compaterr.h>
@@ -213,8 +219,11 @@ removeoldleaves(void)
                                continue;
 #ifdef __linux__
                        (void)fprintf(stderr, "BUG! Should call delwhiteout\n");
+#else
+#ifdef sunos
 #else
                        delwhiteout(ep);
+#endif
 #endif
                        freeentry(ep);
                }
@@ -799,12 +808,42 @@ createleaves(char *symtabfile)
                        doremove = 0;
                (void) extractfile(ep, doremove);
                ep->e_flags &= ~(NEW|EXTRACT);
+
+finderres:
+               if ((first == curfile.ino) && (spcl.c_flags & DR_EXTATTRIBUTES)) {
+                       switch (spcl.c_extattributes) {
+                       case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+                               (void)extractfinderinfoufs(myname(ep));
+#else
+                               msg("MacOSX not supported in this version, skipping\n");
+#endif
+                               break;
+                       case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+                               (void)extractresourceufs(myname(ep));
+#else
+                               msg("MacOSX not supported in this version, skipping\n");
+#endif
+                               break;
+                       case EXT_ACL:
+                               msg("ACLs not supported in this version, skipping\n");
+                               skipfile();
+                               break;
+                       default:
+                               msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                               skipfile();
+                               break;
+                       }
+                       goto finderres;
+               }
+
                /*
                 * We checkpoint the restore after every tape reel, so
                 * as to simplify the amount of work required by the
                 * 'R' command.
                 */
-       next:
+next:
                if (curvol != volno) {
                        dumpsymtable(symtabfile, volno);
                        skipmaps();
@@ -844,8 +883,9 @@ createfiles(void)
        long curvol;
 #ifdef USE_QFA
        long tnum, tmpcnt;
-       long long tpos, curtpos;
+       long long tpos, curtpos = 0;
        time_t tistart, tiend, titaken;
+       int             volChg;
 #endif
 
        Vprintf(stdout, "Extract requested files\n");
@@ -907,38 +947,41 @@ createfiles(void)
 #ifdef USE_QFA
                tistart = time(NULL);
                if (tapeposflag) {
-                       /* get tape position for inode (position directly) */
-                       (void)Inode2Tapepos(next, &tnum, &tpos, 1);
-                       if (tpos == 0)
-                               /* get tape position for last available inode
-                                * (position before) */
-                               (void)Inode2Tapepos(next, &tnum, &tpos, 0);
+                       /* get tape position for inode */
+                       (void)Inode2Tapepos(next, &tnum, &tpos, 0);
                        if (tpos != 0) {
-                               if (tnum != volno)
+                               if (tnum != volno) {
                                        (void)RequestVol(tnum);
+                                       volChg = 1;
+                               } else {
+                                       volChg = 0;
+                               }
                                if (GetTapePos(&curtpos) == 0) {
                                        /*  curtpos +1000 ???, some drives 
                                         *  might be too slow */
-                                       if (tpos != curtpos) {
+                                       if (((tpos > (curtpos + 1000)) && (volChg == 0)) || ((tpos != curtpos) && (volChg == 1))) {
+                                               volChg = 0;
 #ifdef DEBUG_QFA
-                                               msg("positioning tape %ld from %lld to %lld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
+                                               msg("positioning tape %ld from %lld to %lld for inode %lu ...\n", volno, curtpos, tpos, (unsigned long)next);
 #endif
                                                if (GotoTapePos(tpos) == 0) {
 #ifdef DEBUG_QFA
-                                                       if (GetTapePos(&curtpos) == 0)
-                                                               msg("before resync at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+                                                       if (GetTapePos(&curtpos) == 0) {
+                                                               msg("before resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+                                                       }
 #endif
                                                        ReReadInodeFromTape(next);
 #ifdef DEBUG_QFA
-                                                       if (GetTapePos(&curtpos) == 0)
-                                                               msg("after resync at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+                                                       if (GetTapePos(&curtpos) == 0) {
+                                                               msg("after resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name);
+                                                       }
 #endif
                                                }
-                                       }
+                                       } else {
 #ifdef DEBUG_QFA
-                                       else
-                                               msg("already at tape %ld position %ld for inode %10lu ...\n", volno, tpos, (unsigned long)next);
+                                               msg("already at tape %ld position %ld for inode %lu ...\n", volno, tpos, (unsigned long)next);
 #endif
+                                       }
                                }
                        }
                }
@@ -999,9 +1042,9 @@ createfiles(void)
                                panic("corrupted symbol table\n");
 #ifdef USE_QFA
                        if (!createtapeposflag)
+#endif
                                fprintf(stderr, "%s: (inode %lu) not found on tape\n", 
                                        myname(ep), (unsigned long)next);
-#endif
                        ep->e_flags &= ~NEW;
                        next = lowerbnd(next);
                }
@@ -1020,13 +1063,41 @@ createfiles(void)
 #endif
                                sprintf(gTps, "%ld\t%ld\t%lld\n", (unsigned long)curfile.ino, volno, curtapepos);
                                if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps))
-                                       warn("error writing tapepos file.\n");
+                                       warn("error writing tapepos file.\n");
                                skipfile();
-                       }
-                       else {
-                               msg("restoring %s\n", myname(ep));
+                       } else {
 #endif /* USE_QFA */
                                (void) extractfile(ep, 0);
+
+finderres:
+                               if ((next == curfile.ino) && (spcl.c_flags & DR_EXTATTRIBUTES)) {
+                                       switch (spcl.c_extattributes) {
+                                       case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+                                               (void)extractfinderinfoufs(myname(ep));
+#else
+                                               msg("MacOSX not supported in this version, skipping\n");
+#endif
+                                               break;
+                                       case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+                                               (void)extractresourceufs(myname(ep));
+#else
+                                               msg("MacOSX not supported in this version, skipping\n");
+#endif
+                                               break;
+                                       case EXT_ACL:
+                                               msg("ACLs not supported in this version, skipping\n");
+                                               skipfile();
+                                               break;
+                                       default:
+                                               msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                                               skipfile();
+                                               break;
+                                       }
+                                       goto finderres;
+                               }
+
 #ifdef USE_QFA
                        }
 #endif /* USE_QFA */
@@ -1054,8 +1125,11 @@ createlinks(void)
                                continue;
 #ifdef __linux__
                        (void)fprintf(stderr, "BUG! Should call addwhiteout\n");
+#else
+#ifdef sunos
 #else
                        (void) addwhiteout(myname(ep));
+#endif
 #endif
                        ep->e_flags &= ~NEW;
                }
index 0dea9cad3c8612211e78672b04bc22a4436efdc5..9239b07ea8dc0a576557ab2ee4b283a9fe5cfc27 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
  *
- *     $Id: restore.h,v 1.27 2003/03/30 15:40:40 stelian Exp $
+ *     $Id: restore.h,v 1.28 2003/10/26 16:05:48 stelian Exp $
  */
 
 /*
@@ -180,6 +180,11 @@ extern int gTapeposfd;
 extern int     createtapeposflag;
 extern unsigned long qfadumpdate;
 extern long long curtapepos;
+#ifdef sunos
+int            fdsmtc;
+long   scsiid;
+char   smtcpath[2048];
+#endif
 #endif /* USE_QFA */
 
 #define do_compare_error \
index 5bd5e67c45b8b43958f674ffdf2422fe900c7cc0..3e6d3fc2b6674a31a076dcb2eb3204790e1159d3 100644 (file)
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: symtab.c,v 1.21 2003/03/30 15:40:40 stelian Exp $";
+       "$Id: symtab.c,v 1.22 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 /*
@@ -63,7 +63,12 @@ static const char rcsid[] =
 #endif
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
+#endif
 #endif /* __linux__ */
 
 #include <errno.h>
index 553abbc8e99fef89f0d75fc27bdbd2a612451a3c..b4fa15d93c8cdc9882f6a112524253614c6ee1d2 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.74 2003/03/31 09:42:59 stelian Exp $";
+       "$Id: tape.c,v 1.75 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
 #include <compatlfs.h>
+#include <sys/types.h>
 #include <errno.h>
 #include <compaterr.h>
 #include <system.h>
@@ -72,8 +73,18 @@ static const char rcsid[] =
 #include <ext2fs/ext2fs.h>
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#define quad_t int64_t
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
+#endif
 #endif /* __linux__ */
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
 #include <protocols/dumprestore.h>
 
 #ifdef HAVE_ZLIB
@@ -138,6 +149,10 @@ static int  converthead __P((struct s_spcl *));
 static void     converttapebuf __P((struct tapebuf *));
 static void     readtape __P((char *));
 static void     setdumpnum __P((void));
+#ifdef DUMP_MACOSX
+static void     xtrfilefinderinfo __P((char *, size_t));
+#endif
+
 static u_int    swabi __P((u_int));
 #if 0
 static u_long   swabl __P((u_long));
@@ -179,12 +194,19 @@ static void       xtrcmpskip __P((char *, size_t));
 static int readmapflag;
 static int readingmaps;                /* set to 1 while reading the maps */
 
+#ifdef DUMP_MACOSX
+static DumpFinderInfo  gFndrInfo;
+#endif
+
 /*
  * Set up an input source. This is called from main.c before setup() is.
  */
 void
 setinput(char *source)
 {
+       int i;
+       char *n;
+
        FLUSHTAPEBUF();
        if (bflag)
                newtapebuf(ntrec);
@@ -193,12 +215,18 @@ setinput(char *source)
        terminal = stdin;
 
 #ifdef RRESTORE
-       if (strchr(source, ':')) {
-               host = source;
-               source = strchr(host, ':');
-               *source++ = '\0';
-               if (rmthost(host) == 0)
-                       exit(1);
+       if ((n = strchr(source, ':'))) {
+               for (i = 0; i < (n - source); i++) {
+                       if (source[i] == '/')
+                               break;
+               }
+               if (source[i] != '/') {
+                       host = source;
+                       source = strchr(host, ':');
+                       *source++ = '\0';
+                       if (rmthost(host) == 0)
+                               exit(1);
+               }
        } else
 #endif
        if (strcmp(source, "-") == 0) {
@@ -504,7 +532,7 @@ again:
                                goto again;
                        }
                }
-#endif
+#endif /* USE_QFA */
                return;
        }
        closemt();
@@ -529,9 +557,17 @@ again:
        }
        if (haderror || (bot_code && !Mflag)) {
                haderror = 0;
+#ifdef sunos
                fprintf(stderr, "Mount volume %ld\n", (long)newvol);
-               fprintf(stderr, "Enter ``none'' if there are no more volumes\n");
-               fprintf(stderr, "otherwise enter volume name (default: %s) ", magtape);
+#else
+               fprintf(stderr, "Mount tape volume %ld\n", (long)newvol);
+#endif
+               fprintf(stderr, "Enter ``none'' if there are no more tapes\n");
+#ifdef sunos
+               fprintf(stderr, "then enter volume name (default: %s) ", magtape);
+#else
+               fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape);
+#endif
                (void) fflush(stderr);
                (void) fgets(buf, TP_BSIZE, terminal);
                if (feof(terminal))
@@ -548,6 +584,15 @@ again:
                                magtape[pos - magtape] = '\0';
                }
        }
+#if defined(USE_QFA) && defined(sunos)
+       if (createtapeposflag || tapeposflag) {
+               if (OpenSMTCmt(magtape) < 0) {
+                       volno = -1;
+                       haderror = 1;
+                       goto again;
+               }
+       }
+#endif /* USE_QFA */
 #ifdef RRESTORE
        if (host)
                mt = rmtopen(magtape, O_RDONLY);
@@ -589,7 +634,11 @@ gethdr:
        }
        if (tmpbuf.c_date != dumpdate || tmpbuf.c_ddate != dumptime) {
                fprintf(stderr, "Wrong dump date\n\tgot: %s",
+#ifdef sunos
+                       ctime(&tmpbuf.c_date));
+#else
                        ctime4(&tmpbuf.c_date));
+#endif
                fprintf(stderr, "\twanted: %s", ctime(&dumpdate));
                volno = 0;
                haderror = 1;
@@ -686,17 +735,33 @@ setdumpnum(void)
        tcom.mt_op = MTFSF;
        tcom.mt_count = dumpnum - 1;
 #ifdef RRESTORE
-       if (host)
-               rmtioctl(MTFSF, dumpnum - 1);
-       else
+       if (host) {
+               if (rmtioctl(MTFSF, dumpnum - 1) < 0) {
+                       fprintf(stderr, "rmtioctl MTFSF: %s\n", strerror(errno));
+            exit(1);
+               }
+       } else
 #endif
-               if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0)
-                       warn("ioctl MTFSF");
+               if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) {
+                       fprintf(stderr, "rmtioctl MTFSF: %s\n", strerror(errno));
+                       exit(1);
+                       /* warn("ioctl MTFSF"); */
+               }
 }
 
 void
 printdumpinfo(void)
 {
+#ifdef sunos
+       Vprintf(stdout, "Dump   date: %s", ctime(&spcl.c_date));
+       Vprintf(stdout, "Dumped from: %s",
+           (spcl.c_ddate == 0) ? "the epoch\n" : ctime(&spcl.c_ddate));
+       if (spcl.c_host[0] == '\0')
+               return;
+       Vprintf(stdout, "Level %d dump of %s on %s:%s\n",
+               spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
+       Vprintf(stdout, "Label: %s\n", spcl.c_label);
+#else
        fprintf(stdout, "Dump   date: %s", ctime4(&spcl.c_date));
        fprintf(stdout, "Dumped from: %s",
            (spcl.c_ddate == 0) ? "the epoch\n" : ctime4(&spcl.c_ddate));
@@ -705,6 +770,7 @@ printdumpinfo(void)
        fprintf(stdout, "Level %d dump of %s on %s:%s\n",
                spcl.c_level, spcl.c_filesys, spcl.c_host, spcl.c_dev);
        fprintf(stdout, "Label: %s\n", spcl.c_label);
+#endif
 }
 
 void 
@@ -719,12 +785,6 @@ printvolinfo(void)
        }
 }
 
-#ifdef sunos
-struct timeval
-       time_t          tv_sec;         /* seconds */
-       suseconds_t     tv_usec;        /* and microseconds */
-};
-#endif
 
 int
 extractfile(struct entry *ep, int doremove)
@@ -830,8 +890,15 @@ extractfile(struct entry *ep, int doremove)
                if (flags)
 #ifdef  __linux__
                        (void) fsetflags(name, flags);
+#else
+#ifdef sunos
+                       {
+                       warn("%s: cannot call chflags", name);
+                       /* (void) chflags(name, flags); */
+                       }
 #else
                        (void) chflags(name, flags);
+#endif
 #endif
                skipfile();
                utimes(name, timep);
@@ -862,7 +929,17 @@ extractfile(struct entry *ep, int doremove)
                        (void) fsetflags(name, flags);
                        }
 #else
+#ifdef sunos
+                       {
+                       warn("%s: cannot call chflags on a special file", name);
+                       /* (void) chflags(name, flags); */
+                       }
+#else
+                       {
+                       warn("%s: chflags called on a special file", name);
                        (void) chflags(name, flags);
+                       }
+#endif
 #endif
                skipfile();
                utimes(name, timep);
@@ -897,8 +974,15 @@ extractfile(struct entry *ep, int doremove)
                if (flags)
 #ifdef __linux__
                        (void) fsetflags(name, flags);
+#else
+#ifdef sunos
+                       {
+                       warn("%s: cannot call chflags", name);
+                       /* (void) chflags(name, flags); */
+                       }
 #else
                        (void) chflags(name, flags);
+#endif
 #endif
                utimes(name, timep);
                return (GOOD);
@@ -907,6 +991,180 @@ extractfile(struct entry *ep, int doremove)
        /* NOTREACHED */
 }
 
+#ifdef DUMP_MACOSX
+int
+extractfinderinfoufs(char *name)
+{
+       int err;
+       char                    oFileRsrc[MAXPATHLEN];
+       int flags;
+       mode_t mode;
+       struct timeval timep[2];
+       struct entry *ep;
+       int     sz;
+       attrinfo_block_t gABuf;
+       u_int32_t       uid;
+       u_int32_t       gid;
+       char    path[MAXPATHLEN], fname[MAXPATHLEN];
+
+       curfile.name = name;
+       curfile.action = USING;
+       timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
+       timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
+       timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
+       timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
+       mode = curfile.dip->di_mode;
+       flags = curfile.dip->di_flags;
+        uid = curfile.dip->di_uid;
+        gid =  curfile.dip->di_gid;
+
+       switch (mode & IFMT) {
+
+       default:
+               fprintf(stderr, "%s: (extr. finfoufs) unknown file mode 0%o\n", name, mode);
+               skipfile();
+               return (FAIL);
+
+       case IFDIR:
+               fprintf(stderr, "%s: (extr. finfoufs[IFDIR]) unknown file mode 0%o\n", name, mode);
+               skipfile();
+               return (FAIL);
+
+       case IFLNK:
+               skipfile();
+               return (GOOD);
+
+       case IFREG:
+               Vprintf(stdout, "extract finderinfo file %s\n", name);
+               if (Nflag) {
+                       skipfile();
+                       return (GOOD);
+               }
+               getfile(xtrfilefinderinfo, xtrskip);
+
+               GetPathFile(name, path, fname);
+               strcpy(oFileRsrc, path);
+               strcat(oFileRsrc, "._");
+               strcat(oFileRsrc, fname);
+
+               if ((err = CreateAppleDoubleFileRes(oFileRsrc, &gFndrInfo.fndrinfo,
+                               mode, flags, timep, uid, gid)) != 0) {
+                       fprintf(stderr, "%s: cannot create finderinfo: %s\n",
+                       name, strerror(errno));
+                       skipfile();
+                       return (FAIL);
+               }
+               return (GOOD);
+       }
+       /* NOTREACHED */
+}
+
+
+int
+extractresourceufs(char *name)
+{
+       char                    oFileRsrc[MAXPATHLEN];
+       int flags;
+       mode_t mode;
+       struct timeval timep[2];
+       char    path[MAXPATHLEN], fname[MAXPATHLEN];
+       ASDHeaderPtr    hp;
+       ASDEntryPtr     ep;
+       u_long  loff;
+        u_int32_t      uid;
+       u_int32_t       gid;
+       u_int64_t       di_size;
+       char            *p;
+       char            buf[1024];
+
+       curfile.name = name;
+       curfile.action = USING;
+       timep[0].tv_sec = curfile.dip->di_atime.tv_sec;
+       timep[0].tv_usec = curfile.dip->di_atime.tv_usec;
+       timep[1].tv_sec = curfile.dip->di_mtime.tv_sec;
+       timep[1].tv_usec = curfile.dip->di_mtime.tv_usec;
+       mode = curfile.dip->di_mode;
+       flags = curfile.dip->di_flags;
+       uid = curfile.dip->di_uid;
+       gid =  curfile.dip->di_gid;
+       di_size = curfile.dip->di_size;
+
+       switch (mode & IFMT) {
+
+       default:
+               fprintf(stderr, "%s: (extr. resufs) unknown file mode 0%o\n", name, mode);
+               skipfile();
+               return (FAIL);
+
+       case IFDIR:
+               fprintf(stderr, "%s: (extr. resufs [IFDIR]) unknown file mode 0%o\n", name, mode);
+               skipfile();
+               return (FAIL);
+
+       case IFLNK:
+               skipfile();
+               return (GOOD);
+
+       case IFREG:
+               Vprintf(stdout, "extract resource file %s\n", name);
+               if (Nflag) {
+                       skipfile();
+                       return (GOOD);
+               }
+
+               GetPathFile(name, path, fname);
+               strcpy(oFileRsrc, path);
+               strcat(oFileRsrc, "._");
+               strcat(oFileRsrc, fname);
+
+               if ((ofile = open(oFileRsrc, O_RDONLY, 0)) < 0) {
+                       fprintf(stderr, "%s: cannot read finderinfo: %s\n",
+                           name, strerror(errno));
+                       skipfile();
+                       return (FAIL);
+               }
+               read(ofile, buf, 70);
+               (void) close(ofile);
+               p = buf;
+               hp = (ASDHeaderPtr)p;
+               /* the header */
+               hp->entries++;
+               p += sizeof(ASDHeader) - CORRECT;
+               ep = (ASDEntryPtr)p;
+               /* the finderinfo entry */
+               ep->offset += sizeof(ASDEntry);
+               loff = ep->offset;
+
+               p += sizeof(ASDEntry);
+               /* the finderinfo data */
+               bcopy(p, p + sizeof(ASDEntry), INFOLEN);
+               ep = (ASDEntryPtr)p;
+               /* the new resourcefork entry */
+               ep->entryID = EntryRSRCFork;
+               ep->offset = loff + INFOLEN;
+               ep->len = di_size;
+               /* write the new appledouble entries to the file */
+               if ((ofile = open(oFileRsrc, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+                       fprintf(stderr, "%s: cannot create resource file: %s\n",
+                           name, strerror(errno));
+                       skipfile();
+                       return (FAIL);
+               }
+               write(ofile, buf, 70 + sizeof(ASDEntry));
+               /* and add the resource data from tape */
+               getfile(xtrfile, xtrskip);
+
+               (void) fchown(ofile, uid, gid);
+               (void) fchmod(ofile, mode);
+               (void) close(ofile);
+               (void) fsetflags(oFileRsrc, flags);
+               utimes(oFileRsrc, timep);
+               return (GOOD);
+       }
+       /* NOTREACHED */
+}
+#endif /* DUMP_MACOSX */
+
 /*
  * skip over bit maps on the tape
  */
@@ -1024,6 +1282,16 @@ xtrfile(char *buf, size_t size)
                        (unsigned long)curfile.ino, curfile.name);
 }
 
+#ifdef DUMP_MACOSX
+static void
+xtrfilefinderinfo(char *buf, size_t size)
+{
+       if (Nflag)
+               return;
+       bcopy(buf, &gFndrInfo, size);
+}
+#endif /* DUMP_MACOSX */
+
 /*
  * Skip over a hole in a file.
  */
@@ -2580,7 +2848,132 @@ swabl(u_long x)
 }
 #endif
 
+void
+RequestVol(long tnum)
+{
+       FLUSHTAPEBUF();
+       getvol(tnum);
+}
+
 #ifdef USE_QFA
+#ifdef sunos
+extern int fdsmtc;
+
+struct uscsi_cmd {
+        int     uscsi_flags;            /* read, write, etc. see below */
+        short   uscsi_status;           /* resulting status  */
+        short   uscsi_timeout;          /* Command Timeout */
+        caddr_t uscsi_cdb;              /* cdb to send to target */
+        caddr_t uscsi_bufaddr;          /* i/o source/destination */
+        u_int   uscsi_buflen;           /* size of i/o to take place */
+        u_int   uscsi_resid;            /* resid from i/o operation */
+        u_char  uscsi_cdblen;           /* # of valid cdb bytes */
+        u_char  uscsi_rqlen;            /* size of uscsi_rqbuf */
+        u_char  uscsi_rqstatus;         /* status of request sense cmd */
+        u_char  uscsi_rqresid;          /* resid of request sense cmd */
+        caddr_t uscsi_rqbuf;            /* request sense buffer */
+        void   *uscsi_reserved_5;       /* Reserved for Future Use */
+};
+
+#define CDB_GROUP0      6       /*  6-byte cdb's */
+#define CDB_GROUP1      10      /* 10-byte cdb's */
+#define CDB_GROUP2      10      /* 10-byte cdb's */
+#define CDB_GROUP3      0       /* reserved */
+#define CDB_GROUP4      16      /* 16-byte cdb's */
+#define CDB_GROUP5      12      /* 12-byte cdb's */
+#define CDB_GROUP6      0       /* reserved */
+#define CDB_GROUP7      0       /* reserved */
+
+#define USCSI_WRITE     0x00000 /* send data to device */
+#define USCSI_SILENT    0x00001 /* no error messages */
+#define USCSI_DIAGNOSE  0x00002 /* fail if any error occurs */
+#define USCSI_ISOLATE   0x00004 /* isolate from normal commands */
+#define USCSI_READ      0x00008 /* get data from device */
+#define USCSI_RESET     0x04000 /* Reset target */
+#define USCSI_RESET_ALL 0x08000 /* Reset all targets */
+#define USCSI_RQENABLE  0x10000 /* Enable Request Sense extensions */
+
+#define USCSIIOC        (0x04 << 8)
+#define USCSICMD        (USCSIIOC|201)  /* user scsi command */
+
+#define USCSI_TIMEOUT  30
+#define USCSI_SHORT_TIMEOUT    900
+#define USCSI_LONG_TIMEOUT     14000
+
+#define B(s,i) ((unsigned char)((s) >> i))
+#define B1(s)                           ((unsigned char)(s))
+
+#define MSB4(s,v) *(s)=B(v,24),(s)[1]=B(v,16), (s)[2]=B(v,8), (s)[3]=B1(v)
+
+
+int
+GetTapePos(long long *pos)
+{
+       int                                     err = 0;
+       struct uscsi_cmd        scmd;
+       char                            buf[512];
+       char                            parm[512 * 8];
+       long                            lpos;
+
+       (void)memset((void *)buf, 0, sizeof(buf));
+       (void)memset((void *)&scmd, 0, sizeof(scmd));
+       scmd.uscsi_flags = USCSI_READ|USCSI_SILENT;
+       scmd.uscsi_timeout = USCSI_TIMEOUT;
+       scmd.uscsi_cdb = buf;
+       scmd.uscsi_cdblen = CDB_GROUP1;
+       buf[0] = 0x34;  /* read position */
+       buf[1] = 0;
+       (void)memset((void *)parm, 0, 512);
+       scmd.uscsi_bufaddr = parm;
+       scmd.uscsi_buflen = 56;
+       if (ioctl(fdsmtc, USCSICMD, &scmd) == -1) {
+               err = errno;
+               return err;
+       }
+       (void)memcpy(&lpos, &parm[4], sizeof(long));
+       *pos = lpos;
+       return err;
+}
+
+int
+GotoTapePos(long long pos)
+{
+       int                                     err = 0;
+       struct uscsi_cmd        scmd;
+       char                            buf[512];
+       char                            parm[512 * 8];
+       long                            lpos = (long)pos;
+
+       (void)memset((void *)buf, 0, sizeof(buf));
+       (void)memset((void *)&scmd, 0, sizeof(scmd));
+       scmd.uscsi_flags = USCSI_WRITE|USCSI_SILENT;
+       scmd.uscsi_timeout = 360;       /* 5 Minutes */
+       scmd.uscsi_cdb = buf;
+       scmd.uscsi_cdblen = CDB_GROUP1;
+       buf[0] = 0x2b;  /* locate */
+       buf[1] = 0;
+       MSB4(&buf[3], lpos);
+       (void)memset((void *)parm, 0, 512);
+       scmd.uscsi_bufaddr = NULL;
+       scmd.uscsi_buflen = 0;
+       if (ioctl(fdsmtc, USCSICMD, &scmd) == -1) {
+               err = errno;
+               return err;
+       }
+       return err;
+}
+#endif
+
+#define LSEEK_GET_TAPEPOS      10
+#define LSEEK_GO2_TAPEPOS      11
+
+#ifdef __linux__
+typedef struct mt_pos {
+       short    mt_op;
+       int      mt_count;
+} MTPosRec, *MTPosPtr;
+
+
 /*
  * get the current position of the tape
  */
@@ -2591,7 +2984,7 @@ GetTapePos(long long *pos)
 
 #ifdef RDUMP
        if (host) {
-               *pos = (long long) rmtseek(0, SEEK_CUR);
+               *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS);
                err = *pos < 0;
        }
        else
@@ -2617,11 +3010,6 @@ GetTapePos(long long *pos)
        return err;
 }
 
-typedef struct mt_pos {
-       short    mt_op;
-       int      mt_count;
-} MTPosRec, *MTPosPtr;
-
 /*
  * go to specified position on tape
  */
@@ -2632,7 +3020,7 @@ GotoTapePos(long long pos)
 
 #ifdef RDUMP
        if (host)
-               err = (rmtseek(pos, SEEK_SET) < 0);
+               err = (rmtseek((OFF_T)pos, (int)LSEEK_GO2_TAPEPOS) < 0);
        else
 #endif
        {
@@ -2655,6 +3043,7 @@ GotoTapePos(long long pos)
        }
        return err;
 }
+#endif /* __linux__ */
 
 /*
  * read next data from tape to re-sync
@@ -2676,29 +3065,42 @@ ReReadFromTape(void)
 void
 ReReadInodeFromTape(dump_ino_t theino)
 {
-       long cntloop = 0;
+       long    cntloop = 0;
 
        FLUSHTAPEBUF();
        noresyncmesg = 1;
        do {
                cntloop++;
                gethead(&spcl);
-       } while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate) && (cntloop < ntrec));
+       } while (!(spcl.c_inumber == theino && spcl.c_type == TS_INODE && spcl.c_date == dumpdate));
 #ifdef DEBUG_QFA
-       fprintf(stderr, "%ld reads\n", cntloop);
-       if (cntloop == ntrec) {
-               fprintf(stderr, "DEBUG: bufsize %d\n", bufsize);
-               fprintf(stderr, "DEBUG: ntrec %ld\n", ntrec);
-       }
+       fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
+       fprintf(stderr, "DEBUG: bufsize %ld\n", bufsize);
+       fprintf(stderr, "DEBUG: ntrec %ld\n", ntrec);
+       fprintf(stderr, "DEBUG: %ld reads\n", cntloop);
 #endif
        findinode(&spcl);
        noresyncmesg = 0;
 }
-#endif /* USE_QFA */
 
-void
-RequestVol(long tnum)
+#ifdef sunos
+int
+OpenSMTCmt(char *themagtape)
 {
-       FLUSHTAPEBUF();
-       getvol(tnum);
+       if (GetSCSIIDFromPath(themagtape, &scsiid)) {
+               fprintf(stderr, "can't get SCSI-ID for %s\n", themagtape);
+               return -1;
+       }
+       if (scsiid < 0) {
+               fprintf(stderr, "can't get SCSI-ID for %s\n", themagtape);
+               return -1;
+       }
+       sprintf(smtcpath, "/dev/rsmtc%ld,0", scsiid);
+       if ((fdsmtc = open(smtcpath, O_RDWR)) == -1) {
+               fprintf(stderr, "can't open smtc device: %s, %d\n", smtcpath, errno);
+               return -1;
+       }
+       return 0;
 }
+#endif /* sunos */
+#endif /* USE_QFA */
index 838ebe76ec284e9089a3cdf117a41ae8a2846d10..d0539383a306ab194ae13c51998100acc2c2d5b3 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: utilities.c,v 1.22 2003/03/30 15:40:40 stelian Exp $";
+       "$Id: utilities.c,v 1.23 2003/10/26 16:05:48 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
+#include <compatlfs.h>
+#include <sys/types.h>
 #include <errno.h>
 #include <compaterr.h>
 #include <stdio.h>
@@ -53,6 +55,7 @@ static const char rcsid[] =
 #ifdef __linux__
 #include <sys/time.h>
 #include <time.h>
+#include <fcntl.h>
 #ifdef HAVE_EXT2FS_EXT2_FS_H
 #include <ext2fs/ext2_fs.h>
 #else
@@ -61,10 +64,18 @@ static const char rcsid[] =
 #include <ext2fs/ext2fs.h>
 #include <bsdcompat.h>
 #else  /* __linux__ */
+#ifdef sunos
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <bsdcompat.h>
+#else
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
+#endif
 #endif /* __linux__ */
-
+#ifdef DUMP_MACOSX
+#include "darwin.h"
+#endif
 #include "restore.h"
 #include "extern.h"
 
@@ -251,11 +262,14 @@ linkit(char *existing, char *new, int type)
                         * Most likely, the immutable or append-only attribute
                         * is set. Clear the attributes and try again.
                         */
+#ifdef sunos
+#else
                        if (fgetflags (existing, &s) != -1 &&
                            fsetflags (existing, 0) != -1) {
                                ret = link(existing, new);
                                fsetflags(existing, s);
                        }
+#endif
 #endif
                        if (ret < 0) {
                                warn("warning: cannot create hard link %s->%s",
@@ -467,6 +481,51 @@ panic(fmt, va_alist)
        }
 }
 
+void resizemaps(dump_ino_t oldmax, dump_ino_t newmax)
+{
+       char *map;
+
+       if (usedinomap) {
+               map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
+               if (map == NULL)
+                       errx(1, "no memory for active inode map");
+               memcpy(map, usedinomap, howmany(oldmax, NBBY));
+               free(usedinomap);
+               usedinomap = map;
+       }
+       if (dumpmap) {
+               map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
+               if (map == NULL)
+                       errx(1, "no memory for file dump list");
+               memcpy(map, dumpmap, howmany(oldmax, NBBY));
+               free(dumpmap);
+               dumpmap = map;
+       }
+}
+
+void
+GetPathFile(char *source, char *path, char *fname)
+{
+       char    *p, *s;
+
+       *path = 0;
+       *fname = 0;
+       p = s = source;
+       while (*s) {
+               if (*s == '/') {
+                       p = s + 1;
+               }
+               s++;
+       }
+       if (p == source) {
+               *path = 0;
+       } else {
+               strncpy(path, source, p - source);
+               path[p - source] = 0;
+       }
+       strcpy(fname, p);
+}
+
 #ifdef USE_QFA
 /*
  * search for ino in QFA file
@@ -493,7 +552,11 @@ Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch)
        *tnum = 0;
        if (fseek(gTapeposfp, gSeekstart, SEEK_SET) == -1)
                return errno;
-       while (fgets(gTps, sizeof(gTps), gTapeposfp) != NULL) {
+       while (1) {
+               gSeekstart = ftell(gTapeposfp); /* remember for later use */
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) {
+                       return 0;
+               }
                gTps[strlen(gTps) - 1] = 0;     /* delete end of line */
                p = gTps;
                bzero(numbuff, sizeof(numbuff));
@@ -538,26 +601,123 @@ Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch)
        }
        return 0;
 }
+
+#ifdef sunos
+int
+GetSCSIIDFromPath(char *devPath, long *id)
+{
+       int                             len;
+       char                    fbuff[2048];
+       char                    path[2048];
+       char                    fname[2048];
+       char                    *fpn = fname;
+       char                    idstr[32];
+       char                    *ip = idstr;
+
+       bzero(fbuff, sizeof(fbuff));
+       if ((len = readlink(devPath, fbuff, 2048)) == -1) {
+               return errno;
+       }
+       fbuff[len] = 0;
+       GetPathFile(fbuff, path, fname);
+       (void)memset(idstr, 0, sizeof(idstr));
+       while (*fpn && (*fpn != ',')) {
+               if (*fpn <= '9' && *fpn >= '0') {
+                       *ip = *fpn;
+                       ip++;
+               }
+               fpn++;
+       }
+       if (*idstr) {
+               *id = atol(idstr);
+       } else {
+               *id = -1;
+       }
+       return 0;
+}
+#endif
 #endif /* USE_QFA */
 
-void resizemaps(dump_ino_t oldmax, dump_ino_t newmax)
+#ifdef DUMP_MACOSX
+int
+CreateAppleDoubleFileRes(char *oFile, FndrFileInfo *finderinfo, mode_t mode, int flags,
+               struct timeval *timep, u_int32_t uid, u_int32_t gid)
 {
-       char *map;
+       int                             err = 0;
+       int                             fdout;
+       char                    *p;
+       char                    *f;
+       char                    *pp;
+       ASDHeaderPtr    hp;
+       ASDEntryPtr             ep;
+       long                    thesize;
+       long                    n;
+       long                    loops;
+       long                    remain;
+
+
+       n = 1;  /* number of entries in double file ._ only finderinfo */
+       /*
+       no data fork
+       n++;
+       currently no resource fork
+       n++;
+       */
+
+       thesize = sizeof(ASDHeader) + (n * sizeof(ASDEntry)) + INFOLEN;
+       if ((pp = p = (char *)malloc(thesize)) == NULL) {
+               err = errno;
+               return err;
+       }
 
-       if (usedinomap) {
-               map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
-               if (map == NULL)
-                       errx(1, "no memory for active inode map");
-               memcpy(map, usedinomap, howmany(oldmax, NBBY));
-               free(usedinomap);
-               usedinomap = map;
+       hp = (ASDHeaderPtr)p;
+       p += sizeof(ASDHeader);
+       ep = (ASDEntryPtr)p;
+       p += sizeof(ASDEntry) * n;
+
+       hp->magic = ADOUBLE_MAGIC;
+       hp->version = ASD_VERSION2;
+
+       bzero(&hp->filler, sizeof(hp->filler));
+       hp->entries = (short)n;
+       
+       ep->entryID = EntryFinderInfo;
+       ep->offset = p - pp - CORRECT;
+       ep->len = INFOLEN; /*  sizeof(MacFInfo) + sizeof(FXInfo); */
+       bzero(p, ep->len);
+       bcopy(finderinfo, p, sizeof(FndrFileInfo));
+       p += ep->len;
+       ep++;
+
+       if ((fdout = open(oFile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+               err = errno;
+               free(pp);
+               return err;
        }
-       if (dumpmap) {
-               map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY));
-               if (map == NULL)
-                       errx(1, "no memory for file dump list");
-               memcpy(map, dumpmap, howmany(oldmax, NBBY));
-               free(dumpmap);
-               dumpmap = map;
+
+       /* write the ASDHeader */
+       if (write(fdout, pp, sizeof(ASDHeader) - CORRECT) == -1) {
+               err = errno;
+               close(fdout);
+               free(pp);
+               unlink(oFile);
+               return err;
        }
+       /* write the ASDEntries */
+       if (write(fdout, pp + sizeof(ASDHeader), thesize - sizeof(ASDHeader)) == -1) {
+               err = errno;
+               close(fdout);
+               free(pp);
+               unlink(oFile);
+               return err;
+       }
+
+       (void)fchown(fdout, uid, gid);
+       (void)fchmod(fdout, mode);
+       close(fdout);
+       (void)fsetflags(oFile, flags);
+       utimes(oFile, timep);
+       free(pp);
+       return err;
 }
+#endif /* DUMP_MACOSX */
index 6f01bcce70c78793a6b2dbf87dbbc1458152c4ed..1543a7bca05b51da5efed5cff6c735c0d5c2e88f 100644 (file)
--- a/rmt/rmt.c
+++ b/rmt/rmt.c
@@ -37,7 +37,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: rmt.c,v 1.26 2003/04/08 19:52:37 stelian Exp $";
+       "$Id: rmt.c,v 1.27 2003/10/26 16:05:49 stelian Exp $";
 #endif /* not linux */
 
 /*
@@ -111,9 +111,10 @@ static int rmt_version = 0;
 #define MTS_FLAGS      'f'
 #define MTS_BF         'b'
 
-char   *checkbuf __P((char *, int));
-void    error __P((int));
-void    getstring __P((char *));
+static char    *checkbuf __P((char *, int));
+static void     error __P((int));
+static void     getstring __P((char *));
+static unsigned long swaplong __P((unsigned long inv));
 #ifdef ERMT
 char   *cipher __P((char *, int, int));
 void   decrypt __P((void));
@@ -128,6 +129,8 @@ main(int argc, char *argv[])
        unsigned long block = 0;
        char *cp;
 
+       int magtape = 0;
+
 #ifdef ERMT
        if (argc > 1 && strcmp(argv[1], "-d") == 0)
                decrypt(); /* decrypt stdin to stdout, and exit() */
@@ -176,6 +179,10 @@ top:
                if (tape < 0)
                        goto ioerror;
                block = 0;
+               {
+               struct mtget mt_stat;
+               magtape = ioctl(tape, MTIOCGET, (char *)&mt_stat) == 0;
+               }
                goto respond;
 
        case 'C':
@@ -187,11 +194,59 @@ top:
                block = 0;
                goto respond;
 
+#ifdef USE_QFA
+#define LSEEK_GET_TAPEPOS      10
+#define LSEEK_GO2_TAPEPOS      11
+#endif
+
        case 'L':
                getstring(count);
                getstring(pos);
                DEBUG2("rmtd: L %s %s\n", count, pos);
-               rval = LSEEK(tape, (OFF_T)atoll(count), atoi(pos));
+               if (!magtape) { /* traditional */
+                       rval = LSEEK(tape, (OFF_T)atoll(count), atoi(pos));
+               }
+               else {
+                       switch (atoi(pos)) {
+                       case SEEK_SET:
+                       case SEEK_CUR:
+                       case SEEK_END:
+                               rval = LSEEK(tape, (OFF_T)atoll(count), atoi(pos));
+                               break;
+#ifdef USE_QFA
+                       case LSEEK_GET_TAPEPOS: /* QFA */
+                       case LSEEK_GO2_TAPEPOS:
+                               {
+                               struct mtop buf;
+                               long mtpos;
+
+                               buf.mt_op = MTSETDRVBUFFER;
+                               buf.mt_count = MT_ST_BOOLEANS | MT_ST_SCSI2LOGICAL;
+                               if (ioctl(tape, MTIOCTOP, &buf) < 0) {
+                                       goto ioerror;
+                               }
+
+                               if (atoi(pos) == LSEEK_GET_TAPEPOS) { /* get tapepos */
+                                       if (ioctl(tape, MTIOCPOS, &mtpos) < 0) {
+                                               goto ioerror;
+                                       }
+                                       rval = (OFF_T)mtpos;
+                               } else {
+                                       buf.mt_op = MTSEEK;
+                                       buf.mt_count = atoi(count);
+                                       if (ioctl(tape, MTIOCTOP, &buf) < 0) {
+                                               goto ioerror;
+                                       }
+                                       rval = (OFF_T)buf.mt_count;
+                               }
+                               }
+                               break;
+#endif /* USE_QFA */
+                       default:
+                               errno = EINVAL;
+                               goto ioerror;
+                       }
+               }
                if (rval < 0)
                        goto ioerror;
                goto respond;
@@ -254,7 +309,7 @@ top:
                        struct mtop mtop;
                        mtop.mt_op = -1;
                        if (rmt_version) {
-                               /* rmt version 1, assume UNIX client */
+                               /* rmt version 1, assume UNIX/Solaris/Mac OS X client */
                                switch (atoi(op)) {
 #ifdef  MTWEOF
                                        case 0:
@@ -295,6 +350,21 @@ top:
                                        case 7:
                                                mtop.mt_op = MTNOP;
                                                break;
+#endif
+#ifdef  MTRETEN
+                    case 8:
+                        mtop.mt_op = MTRETEN;
+                        break;
+#endif
+#ifdef  MTERASE
+                    case 9:
+                        mtop.mt_op = MTERASE;
+                        break;
+#endif
+#ifdef  MTEOM
+                    case 10:
+                        mtop.mt_op = MTEOM;
+                        break;
 #endif
                                }
                                if (mtop.mt_op == -1) {
@@ -307,8 +377,9 @@ top:
                                mtop.mt_op = atoi(op);
                        }
                        mtop.mt_count = atoi(count);
-                       if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
+                       if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0) {
                                goto ioerror;
+                       }
                        rval = mtop.mt_count;
                }
                goto respond;
@@ -355,8 +426,9 @@ top:
                                goto ioerror;
                }
                mtop.mt_count = atoi (count);
-               if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0)
+               if (ioctl (tape, MTIOCTOP, (char *) &mtop) < 0) {
                        goto ioerror;
+               }
 
                rval = mtop.mt_count;
 
@@ -366,12 +438,33 @@ top:
        case 'S':               /* status */
                DEBUG("rmtd: S\n");
                { struct mtget mtget;
-                 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0)
+
+                 if (ioctl(tape, MTIOCGET, (char *)&mtget) < 0) {
                        goto ioerror;
-                 rval = sizeof (mtget);
-                 (void)sprintf(resp, "A%lld\n", (long long)rval);
-                 (void)write(1, resp, strlen(resp));
-                 (void)write(1, (char *)&mtget, sizeof (mtget));
+                 }
+
+                 if (rmt_version) {
+                       rval = sizeof(mtget);
+                       /* assume byte order:
+                       Linux on Intel (little), Solaris on SPARC (big), Mac OS X on PPC (big)
+                       thus need byte swapping from little to big
+                       */
+                       mtget.mt_type = swaplong(mtget.mt_type);
+                       mtget.mt_resid = swaplong(mtget.mt_resid);
+                       mtget.mt_dsreg = swaplong(mtget.mt_dsreg);
+                       mtget.mt_gstat = swaplong(mtget.mt_gstat);
+                       mtget.mt_erreg = swaplong(mtget.mt_erreg);
+                       mtget.mt_fileno = swaplong(mtget.mt_fileno);
+                       mtget.mt_blkno = swaplong(mtget.mt_blkno);
+                       (void)sprintf(resp, "A%lld\n", (long long)rval);
+                       (void)write(1, resp, strlen(resp));
+                       (void)write(1, (char *)&mtget, sizeof (mtget));
+                 } else {
+                       rval = sizeof (mtget);
+                       (void)sprintf(resp, "A%lld\n", (long long)rval);
+                       (void)write(1, resp, strlen(resp));
+                       (void)write(1, (char *)&mtget, sizeof (mtget));
+                 }
                  goto top;
                }
 
@@ -379,11 +472,15 @@ top:
        {       char s;
                struct mtget mtget;
  
+               DEBUG ("rmtd: s\n");
+
                if (read (0, &s, 1) != 1)
                        goto top;
+               DEBUG1 ("rmtd: s %d\n", s);
  
-               if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0)
+               if (ioctl (tape, MTIOCGET, (char *) &mtget) < 0) {
                        goto ioerror;
+               }
 
                switch (s) {
                        case MTS_TYPE:
@@ -418,11 +515,11 @@ top:
                goto respond;
        }
 
-        case 'V':               /* version */
-                getstring(op);
-                DEBUG1("rmtd: V %s\n", op);
-                rval = 2;
-                goto respond;
+       case 'V':       /* version */
+               getstring(op);
+               DEBUG1("rmtd: V %s\n", op);
+               rval = 2;
+               goto respond;
 
        default:
                DEBUG1("rmtd: garbage command %c\n", c);
@@ -438,7 +535,7 @@ ioerror:
        goto top;
 }
 
-void getstring(char *bp)
+static void getstring(char *bp)
 {
        int i;
        char *cp = bp;
@@ -452,7 +549,7 @@ void getstring(char *bp)
        cp[i] = '\0';
 }
 
-char *
+static char *
 checkbuf(char *record, int size)
 {
 
@@ -472,7 +569,7 @@ checkbuf(char *record, int size)
        return (record);
 }
 
-void
+static void
 error(int num)
 {
 
@@ -480,3 +577,21 @@ error(int num)
        (void)snprintf(resp, sizeof(resp), "E%d\n%s\n", num, strerror(num));
        (void)write(1, resp, strlen(resp));
 }
+
+static unsigned long
+swaplong(unsigned long inv)
+{
+        union lconv {
+               unsigned long   ul;
+               unsigned char   uc[4];
+       } *inp, outv;
+
+       inp = (union lconv *)&inv;
+
+       outv.uc[0] = inp->uc[3];
+       outv.uc[1] = inp->uc[2];
+       outv.uc[2] = inp->uc[1];
+       outv.uc[3] = inp->uc[0];
+
+       return (outv.ul);
+}