www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/09/16/11:20:04

From: lauras AT softhome DOT net
Message-ID: <20010916143811.19992.qmail@softhome.net>
To: djgpp-workers AT delorie DOT com
Subject: Patch: skipping paths in djtar (3rd try)
Date: Sun, 16 Sep 2001 14:38:11 GMT
Mime-Version: 1.0
X-Sender: lauras AT softhome DOT net
Reply-To: djgpp-workers AT delorie DOT com


I've dug up my old patch, if somebody remembers that; cleared up
all issues raised by Eli back in February, and here is what I believe
is the final form ready for CVS:

Laurynas

Index: djgpp/src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.96
diff -u -p -r1.96 wc204.txi
--- djgpp/src/docs/kb/wc204.txi	2001/08/26 10:41:18	1.96
+++ djgpp/src/docs/kb/wc204.txi	2001/09/16 15:10:32
@@ -613,3 +613,10 @@ correct read/write permissions in @code{
 in @code{st_dev} members of @code{struct stat}.  This was known to fail
 functions like @code{link} and programs like GNU @code{cp} which tested
 files for being on the same filesystem by calling @code{fstat}.
+
+@pindex djtar AT r{, new option -e}
+@pindex djtar AT r{, multiple -o and -e options}
+New option @samp{-e} has been added to @code{djtar} to skip specified
files 
+and directories when extracting.  Also @code{djtar} can accept multiple 
+@samp{-o} and @samp{-e} options in a single command line.  Finally, the
file
+name change file format allows skipping files and directories.
Index: djgpp/src/utils/utils.tex
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/utils.tex,v
retrieving revision 1.17
diff -u -p -r1.17 utils.tex
--- djgpp/src/utils/utils.tex	2001/07/03 17:15:37	1.17
+++ djgpp/src/utils/utils.tex	2001/09/16 15:10:49
@@ -127,9 +127,10 @@ package is built.
 @node djtar, dtou, djecho, Top
 @chapter djtar
 
-Usage: @code{djtar} [@code{-n} @file{changeFile}] [@code{-o} @file{dir}]
-[@code{-t}|@code{-x}] [@code{-i}] [@code{-v}] [@code{-p}]
-[@code{-.}|@code{-!.}] [@code{-d}|@code{-u}|@code{-b}] @file{tarfile}
+Usage: @code{djtar} [@code{-n} @file{changeFile}] [@code{-e} @file{dir}]
+[@code{-o} @file{dir}] [@code{-t}|@code{-x}] [@code{-i}] [@code{-v}] 
+[@code{-p}] [@code{-.}|@code{-!.}] [@code{-d}|@code{-u}|@code{-b}] 
+@file{tarfile}
 
 @code{djtar} is a program that is designed to ease the problems related
 to extracting Unix tar files on a DOS machine.  The long file names and
@@ -262,11 +263,13 @@ The format of the @file{changeFile} file
 @example
 dir/dir/dir/old.name.here  dir/dir/dir/newname.hre
 dir/dir/dir/old2.name.here  dir/dir/dir/newname2.hre
+dir/dir/dir.to.skip.here
 @end example
 
-The directories must be complete, not relative.  The "old" directories
-must match the complete path in the tar file, and the "new" directories
-indicate where the file goes on the DOS disk.
+The directories must be complete, not relative.  The ``old'' directories
+must match the complete path in the tar file, and the ``new'' directories
+indicate where the file goes on the DOS disk.  If there is no ``new''
directory
+specified, the ``old'' one and all its siblings will be not extracted.
 
 @item -d
 
@@ -297,6 +300,13 @@ written in text mode, so this option doe
 with @samp{-p}, unless the output of @code{djtar} is redirected to a file
 or a pipe.
 
+@item -e @var{string}
+
+Only extract files whose full path names do @strong{not} begin with
@var{string}.
+This option can be used to skip portions of archive.  If both this
+and @samp{-o} options are specified, then this option has precendence.  In
+other ways @samp{-e} is similar to @samp{-o} option.
+
 @item -o @var{string}
 
 Only extract files whose full path names begin with @var{string}.
@@ -305,7 +315,8 @@ extracted will still be shown, but with 
 appended to their names.  When given the @samp{-o} option, @code{djtar}
 actually checks if @var{string} is the initial substring of each filename,
 so you can specify incomplete file names, thus using @samp{-o} as a poor
man's
-wildcard facility.
+wildcard facility.  You may specify multiple @samp{-o} options to extract
+several different directories and files.
 
 @item -i
 
@@ -515,10 +526,10 @@ hours:minutes:seconds.
 
 @end table
 
-Options are processed in the order they are encountered.  Thus, "-o foo
--eo" means "redirect output to foo, then redirect errors there also",
-whereas "-eo -o foo" means "send errors to where output was going, then
-move output to foo".
+Options are processed in the order they are encountered.  Thus, ``-o foo
+-eo'' means ``redirect output to foo, then redirect errors there also'',
+whereas ``-eo -o foo'' means ``send errors to where output was going, then
+move output to foo''.
 
 
 Examples:
Index: djgpp/src/utils/djtar/djtar.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/djtar/djtar.c,v
retrieving revision 1.8
diff -u -p -r1.8 djtar.c
--- djgpp/src/utils/djtar/djtar.c	2001/03/21 17:01:58	1.8
+++ djgpp/src/utils/djtar/djtar.c	2001/09/16 15:10:51
@@ -24,6 +24,15 @@ Fatal(const char *msg)
   exit(1);
 }
 
+static char *
+xstrdup(const char * source)
+{
+  char * ptr = strdup(source);
+  if (!ptr)
+     Fatal("Out of memory");
+  return ptr;
+}
+

/*------------------------------------------------------------------------*/
 
 typedef struct CE {
@@ -32,6 +41,21 @@ typedef struct CE {
   char *to;
 } CE;
 
+/* Do not extract files and directories starting with prefixes in this
list. */
+/* It has precendence over only_dir below.  */
+struct skip_dir_list
+{
+   char *skip_dir;
+   struct skip_dir_list * next;
+} * skip_dirs;
+
+/* Extract only files and directories starting with prefixes in this list.
*/
+struct only_dir_list
+{
+   char *only_dir;
+   struct only_dir_list * next;
+} * only_dirs;
+
 #define HASHSIZE 2048
 #define HASHMASK 2047
 #define HASHBITS 11
@@ -52,11 +76,9 @@ static void
 store_entry(char *from, char *to)
 {
   unsigned long h = hash(from);
-  CE *ce = (CE *)malloc(sizeof(CE));
-  if (ce == 0)
-    Fatal("Out of memory");
-  ce->from = strdup(from);
-  ce->to = strdup(to);
+  CE *ce = (CE *)xmalloc(sizeof(CE));
+  ce->from = xstrdup(from);
+  ce->to = xstrdup(to);
   ce->next = htab[h];
   htab[h] = ce;
 }
@@ -76,6 +98,7 @@ get_entry(char *from)
 static void
 DoNameChanges(char *fname)
 {
+  struct skip_dir_list * new_entry; 
   FILE *f = fopen(fname, "r");
   char from[PATH_MAX], to[PATH_MAX];
   char line[PATH_MAX*2 + 10];
@@ -93,6 +116,13 @@ DoNameChanges(char *fname)
     sscanf(line, "%s %s", from, to);
     if (to[0])
       store_entry(from, to);
+    else
+    {
+      new_entry = xmalloc(sizeof(struct skip_dir_list));
+      new_entry->skip_dir = xstrdup(from);
+      new_entry->next = skip_dirs;
+      skip_dirs = new_entry;
+    }
   }
   fclose(f);
 }
@@ -112,8 +142,6 @@ int ignore_csum = 0;
 int list_only = 1;
 char skipped_str[] = "[skipped]";
 
-char *only_dir;
-

/*------------------------------------------------------------------------*/
 
 typedef struct CHANGE {
@@ -178,12 +206,10 @@ change(char *fname, const char *problem,
   if ((strcmp(new, "") == 0) && (isadir == 2))
     return 0;
   if (isadir) isadir=1;
-  ch = (CHANGE *)malloc(sizeof(CHANGE));
-  if (ch == 0)
-    Fatal("Out of memory");
+  ch = (CHANGE *)xmalloc(sizeof(CHANGE));
   ch->next = change_root;
   change_root = ch;
-  ch->old = strdup(fname);
+  ch->old = xstrdup(fname);
   pos = strrchr(fname, '/');
   if (pos && (strchr(new, '/') == 0))
   {
@@ -191,9 +217,7 @@ change(char *fname, const char *problem,
       ch->new = skipped_str;
     else
     {
-      ch->new = (char *)malloc(strlen(new) + (pos-fname) + 2);
-      if (ch->new == 0)
-        Fatal("Out of memory");
+      ch->new = (char *)xmalloc(strlen(new) + (pos-fname) + 2);
       *pos = 0;
       sprintf(ch->new, "%s/%s", fname, new);
     }
@@ -201,7 +225,7 @@ change(char *fname, const char *problem,
   else if (new[0] == 0)
     ch->new = skipped_str;
   else
-    ch->new = strdup(new);
+    ch->new = xstrdup(new);
   ch->isdir = isadir;
   strcpy(fname, ch->new);
   if (new[0] == 0)
@@ -294,14 +318,45 @@ char *
 get_new_name(char *name_to_change, int *should_be_written)
 {
   char *changed_name;
+  struct skip_dir_list * skip_dir_entry;
+  struct only_dir_list * only_dir_entry;
 
   /* ONLY_DIR says to extract only files which are siblings
      of that directory.  */
   *should_be_written = list_only == 0;
-  if (*should_be_written &&
-      only_dir && strncmp(only_dir, name_to_change, strlen(only_dir)))
-    *should_be_written = 0;
 
+  if (*should_be_written)
+  {
+     skip_dir_entry = skip_dirs;
+     while (skip_dir_entry)
+     {
+        if (!strncmp(skip_dir_entry->skip_dir, name_to_change, 
+                     strlen(skip_dir_entry->skip_dir)))
+        {
+           char * following_char = name_to_change +
strlen(name_to_change);
+           if ((*following_char == '\0') || (*following_char == '/') ||
+               (*following_char == '\\'))
+              break;
+        } 
+        skip_dir_entry = skip_dir_entry->next;
+     }
+     if (skip_dir_entry)
+        *should_be_written = 0;
+     else if (only_dirs)
+     {
+        only_dir_entry = only_dirs;
+        while (only_dir_entry)
+        {
+           if (!strncmp(only_dir_entry->only_dir, name_to_change,
+                        strlen(only_dir_entry->only_dir)))
+              break;
+           only_dir_entry = only_dir_entry->next;
+        }
+        if (!only_dir_entry)
+           *should_be_written = 0;
+     }
+  }
+
   changed_name = get_entry(name_to_change);
   if (*should_be_written && !to_stdout && NO_LFN(changed_name))
   {
@@ -498,12 +553,14 @@ main(int argc, char **argv)
   int i = 1;
   char *tp;
   char *xp;
+  struct skip_dir_list * skip_entry;
+  struct only_dir_list * only_entry;
 
-  progname = strlwr(strdup(argv[0]));
+  progname = strlwr(xstrdup(argv[0]));
 
   if (argc < 2)
   {
-    fprintf(stderr, "Usage: %s [-n changeFile] [-p] [-i] [-t|x] [-o dir]
[-v] [-u|d|b] [-[!].] tarfile...\n", progname);
+    fprintf(stderr, "Usage: %s [-n changeFile] [-p] [-i] [-t|x] [-e dir]
[-o dir] [-v] [-u|d|b] [-[!].] tarfile...\n", progname);
     exit(1);
   }
 
@@ -515,6 +572,7 @@ main(int argc, char **argv)
     list_only = 1;
   else if (xp && (xp[sizeof(djtarx)-1] == '\0' || xp[sizeof(djtarx)-5] ==
'\0'))
     list_only = 0;
+
   while ((argc > i) && (argv[i][0] == '-') && argv[i][1])
   {
     switch (argv[i][1])
@@ -544,8 +602,17 @@ main(int argc, char **argv)
 	if (argv[i][2] == '.')
 	  dot_switch = 0;
 	break;
+      case 'e':
+        skip_entry = xmalloc(sizeof(struct skip_dir_list));
+        skip_entry->skip_dir = xstrdup(argv[++i]);
+        skip_entry->next = skip_dirs;
+        skip_dirs = skip_entry;
+	break;
       case 'o':
-        only_dir = strdup(argv[++i]);
+        only_entry = xmalloc(sizeof(struct only_dir_list));
+        only_entry->only_dir = xstrdup(argv[++i]);
+        only_entry->next = only_dirs;
+        only_dirs = only_entry;
         break;
       case 'p':
         to_stdout = 1;

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019