]> git.wh0rd.org - dump.git/blobdiff - restore/interactive.c
Added the prompt command in restore interactive mode.
[dump.git] / restore / interactive.c
index f98ff0f5c68b8a845a9e27ba76533e1f78e2d283..0bd6aaa6d7bc6f367c20e21a83f182b88de9003e 100644 (file)
@@ -2,8 +2,7 @@
  *     Ported to Linux's Second Extended File System as part of the
  *     dump and restore backup suit
  *     Remy Card <card@Linux.EU.Org>, 1994-1997
- *      Stelian Pop <pop@cybercable.fr>, 1999 
- *
+ *     Stelian Pop <pop@cybercable.fr>, 1999-2000
  */
 
 /*
  */
 
 #ifndef lint
-#if 0
-static char sccsid[] = "@(#)interactive.c      8.5 (Berkeley) 5/1/95";
-#endif
 static const char rcsid[] =
-       "$Id: interactive.c,v 1.2 1999/10/11 12:53:23 stelian Exp $";
+       "$Id: interactive.c,v 1.9 2000/02/26 01:35:48 stelian Exp $";
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -60,13 +56,16 @@ static const char rcsid[] =
 #include <protocols/dumprestore.h>
 
 #include <setjmp.h>
-#include <glob.h>
+#include <compaterr.h>
+#include <errno.h>
+#include <compatglob.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #ifdef __linux__
 #include <ext2fs/ext2fs.h>
+extern char * __progname;
 #endif
 
 #include "restore.h"
@@ -80,7 +79,7 @@ static const char rcsid[] =
 static int runshell;
 static jmp_buf reset;
 static char *nextarg = NULL;
-
+static int pflag = 0;          /* prompt mode */
 /*
  * Structure and routines associated with listing directories.
  */
@@ -111,7 +110,7 @@ static void  printlist __P((char *, char *));
  * Read and execute commands from the terminal.
  */
 void
-runcmdshell()
+runcmdshell(void)
 {
        register struct entry *np;
        ino_t ino;
@@ -168,7 +167,8 @@ loop:
                        fprintf(stderr, "%s: not a directory\n", name);
                        break;
                }
-               (void) strcpy(curdir, name);
+               (void) strncpy(curdir, name, sizeof(curdir));
+               curdir[sizeof(curdir) - 1] = '\0';
                break;
        /*
         * Delete elements from the extraction list.
@@ -203,7 +203,7 @@ loop:
                if (strncmp(cmd, "help", strlen(cmd)) != 0)
                        goto bad;
        case '?':
-               fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+               fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                        "Available commands are:\n",
                        "\tls [arg] - list directory\n",
                        "\tcd arg - change directory\n",
@@ -218,6 +218,7 @@ loop:
                        "\twhat - list dump header information\n",
                        "\tverbose - toggle verbose flag",
                        " (useful with ``ls'')\n",
+                       "\tprompt - toggle the prompt display\n",
                        "\thelp or `?' - print this list\n",
                        "If no `arg' is supplied, the current",
                        " directory is used\n");
@@ -234,12 +235,26 @@ loop:
         * Print current directory.
         */
        case 'p':
-               if (strncmp(cmd, "pwd", strlen(cmd)) != 0)
-                       goto bad;
-               if (curdir[1] == '\0')
-                       fprintf(stderr, "/\n");
-               else
-                       fprintf(stderr, "%s\n", &curdir[1]);
+               if (strncmp(cmd, "pwd", strlen(cmd)) == 0) {
+                       if (curdir[1] == '\0')
+                               fprintf(stderr, "/\n");
+                       else
+                               fprintf(stderr, "%s\n", &curdir[1]);
+               }
+       /*
+        * Toggle prompt mode.
+        */
+               else if (strncmp(cmd, "prompt", strlen(cmd)) == 0) {
+                       if (pflag) {
+                               fprintf(stderr, "prompt mode off\n");
+                               pflag = 0;
+                               break;
+                       }
+                       fprintf(stderr, "prompt mode on\n");
+                       pflag++;
+                       break;
+               }
+               else goto bad;
                break;
        /*
         * Quit.
@@ -319,10 +334,7 @@ loop:
  * eliminate any embedded ".." components.
  */
 static void
-getcmd(curdir, cmd, name, size, ap)
-       char *curdir, *cmd, *name;
-       struct arglist *ap;
-       int size;
+getcmd(char *curdir, char *cmd, char *name, int size, struct arglist *ap)
 {
        register char *cp;
        static char input[BUFSIZ];
@@ -340,7 +352,13 @@ getcmd(curdir, cmd, name, size, ap)
         * Read a command line and trim off trailing white space.
         */
        do      {
-               fprintf(stderr, "restore > ");
+               if (pflag)
+                       fprintf(stderr, "%s:%s:%s > ", 
+                               __progname,
+                               spcl.c_filesys, 
+                               curdir[1] ? &curdir[1] : "/");
+               else
+                       fprintf(stderr, "%s > ", __progname);
                (void) fflush(stderr);
                (void) fgets(input, BUFSIZ, terminal);
        } while (!feof(terminal) && input[0] == '\n');
@@ -408,8 +426,7 @@ retnext:
  * Strip off the next token of the input.
  */
 static char *
-copynext(input, output)
-       char *input, *output;
+copynext(char *input, char *output)
 {
        register char *cp, *bp;
        char quote;
@@ -458,9 +475,7 @@ copynext(input, output)
  * remove any embedded "." and ".." components.
  */
 void
-canon(rawname, canonname, len)
-       char *rawname, *canonname;
-       int len;
+canon(char *rawname, char *canonname, int len)
 {
        register char *cp, *np;
 
@@ -470,10 +485,8 @@ canon(rawname, canonname, len)
                (void) strcpy(canonname, ".");
        else
                (void) strcpy(canonname, "./");
-       if (strlen(canonname) + strlen(rawname) >= len) {
-               fprintf(stderr, "canonname: not enough buffer space\n");
-               done(1);
-       }
+       if (strlen(canonname) + strlen(rawname) >= len)
+               errx(1, "canonname: not enough buffer space");
                
        (void) strcat(canonname, rawname);
        /*
@@ -514,11 +527,9 @@ canon(rawname, canonname, len)
  * Do an "ls" style listing of a directory
  */
 static void
-printlist(name, basename)
-       char *name;
-       char *basename;
+printlist(char *name, char *basename)
 {
-       register struct afile *fp, *list, *listp=NULL;
+       register struct afile *fp, *list, *listp = NULL;
        register struct direct *dp;
        struct afile single;
        RST_DIR *dirp;
@@ -554,9 +565,9 @@ printlist(name, basename)
                fprintf(stderr, "%s:\n", name);
                entries = 0;
                listp = list;
-               (void) strncpy(locname, name, MAXPATHLEN);
-               (void) strncat(locname, "/", MAXPATHLEN);
-               namelen = strlen(locname);
+               namelen = snprintf(locname, sizeof(locname), "%s/", name);
+               if (namelen >= sizeof(locname))
+                       namelen = sizeof(locname) - 1;
                while ((dp = rst_readdir(dirp))) {
                        if (dp == NULL)
                                break;
@@ -567,12 +578,12 @@ printlist(name, basename)
                             strcmp(dp->d_name, "..") == 0))
                                continue;
                        locname[namelen] = '\0';
-                       if (namelen + dp->d_namlen >= MAXPATHLEN) {
+                       if (namelen + strlen(dp->d_name) >= MAXPATHLEN) {
                                fprintf(stderr, "%s%s: name exceeds %d char\n",
                                        locname, dp->d_name, MAXPATHLEN);
                        } else {
                                (void) strncat(locname, dp->d_name,
-                                   (int)dp->d_namlen);
+                                   (int)strlen(dp->d_name));
                                mkentry(locname, dp, listp++);
                                entries++;
                        }
@@ -598,10 +609,7 @@ printlist(name, basename)
  * Read the contents of a directory.
  */
 static void
-mkentry(name, dp, fp)
-       char *name;
-       struct direct *dp;
-       register struct afile *fp;
+mkentry(char *name, struct direct *dp, struct afile *fp)
 {
        char *cp;
        struct entry *np;
@@ -642,9 +650,12 @@ mkentry(name, dp, fp)
                fp->postfix = '#';
                break;
 
+#ifndef __linux__
+       /* no need for this */
        case DT_WHT:
                fp->postfix = '%';
                break;
+#endif
 
        case DT_UNKNOWN:
        case DT_DIR:
@@ -661,13 +672,11 @@ mkentry(name, dp, fp)
  * Print out a pretty listing of a directory
  */
 static void
-formatf(list, nentry)
-       register struct afile *list;
-       int nentry;
+formatf(struct afile *list, int nentry)
 {
        register struct afile *fp, *endlist;
        int width, bigino, haveprefix, havepostfix;
-       int i, j, w, precision=0, columns, lines;
+       int i, j, w, precision = 0, columns, lines;
 
        width = 0;
        haveprefix = 0;
@@ -702,7 +711,7 @@ formatf(list, nentry)
                for (j = 0; j < columns; j++) {
                        fp = &list[j * lines + i];
                        if (vflag) {
-                               fprintf(stderr, "%*ld ", precision, fp->fnum);
+                               fprintf(stderr, "%*ld ", precision, (long)fp->fnum);
                                fp->len += precision + 1;
                        }
                        if (haveprefix) {
@@ -728,27 +737,20 @@ formatf(list, nentry)
  * Skip over directory entries that are not on the tape
  *
  * First have to get definition of a dirent.
+ *
+ * For Linux the dirent struct is now included from bsdcompat.h
  */
-#ifdef __linux__
-struct dirent {
-       off_t           d_off;          /* offset of next disk dir entry */
-        unsigned long   d_fileno;       /* file number of entry */
-        unsigned short  d_reclen;       /* length of this record */
-        unsigned short  d_namlen;       /* length of string in d_name */
-        char            d_name[255+1];  /* name (up to MAXNAMLEN + 1) */
-};
-#else  /* __linux__ */
+#ifndef        __linux__
 #undef DIRBLKSIZ
 #include <dirent.h>
 #undef d_ino
-#endif /* __linux__ */
+#endif /* __linux__ */
 
 struct dirent *
-glob_readdir(dirp)
-       RST_DIR *dirp;
+glob_readdir(RST_DIR *dirp)
 {
        struct direct *dp;
-       static struct dirent adirent;
+       static struct dirent adirent; 
 
        while ((dp = rst_readdir(dirp)) != NULL) {
                if (!vflag && dp->d_ino == WINO)
@@ -759,7 +761,6 @@ glob_readdir(dirp)
        if (dp == NULL)
                return (NULL);
        adirent.d_fileno = dp->d_ino;
-       adirent.d_namlen = dp->d_namlen;
        memmove(adirent.d_name, dp->d_name, dp->d_namlen + 1);
        return (&adirent);
 }
@@ -768,12 +769,9 @@ glob_readdir(dirp)
  * Return st_mode information in response to stat or lstat calls
  */
 static int
-glob_stat(name, stp)
-       const char *name;
-       struct stat *stp;
+glob_stat(const char *name, struct stat *stp)
 {
        register struct direct *dp;
-
        dp = pathsearch(name);
        if (dp == NULL || (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) ||
            (!vflag && dp->d_ino == WINO))
@@ -789,8 +787,7 @@ glob_stat(name, stp)
  * Comparison routine for qsort.
  */
 static int
-fcmp(f1, f2)
-       register const void *f1, *f2;
+fcmp(const void *f1, const void *f2)
 {
        return (strcmp(((struct afile *)f1)->fname,
            ((struct afile *)f2)->fname));
@@ -800,11 +797,13 @@ fcmp(f1, f2)
  * respond to interrupts
  */
 void
-onintr(signo)
-       int signo;
+onintr(int signo)
 {
+       int save_errno = errno;
+
        if (command == 'i' && runshell)
                longjmp(reset, 1);
        if (reply("restore interrupted, continue") == FAIL)
-               done(1);
+               exit(1);
+       errno = save_errno;
 }