Mail Archives: djgpp-workers/2001/02/16/05:27:23
Here is an updated patch, which does:
1) All entries in file name mapping file without destination
will be skipped
2) Multiple -o options allowed
3) New -x option
4) Minor cleanup: consolidate all malloc() error checking into djtmalloc().
This is still implemented with linked lists and not struct CHANGE. I still
maintain the point it's the better way. Criticism is welcome, as always :)
Index: docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.53
diff -p -u -r1.53 wc204.txi
--- wc204.txi 2001/02/09 12:38:40 1.53
+++ wc204.txi 2001/02/16 10:24:30
@@ -317,3 +317,10 @@ namespace.
@findex setjmp AT r{, also a macro}
@code{setjmp} is now a macro as well as a function. This is required by
the C AT t{++} standard, and also recommended by the C standard.
+
+@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: utils/utils.tex
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/utils.tex,v
retrieving revision 1.13
diff -p -u -r1.13 utils.tex
--- utils.tex 2001/01/20 09:20:39 1.13
+++ utils.tex 2001/02/16 10:24:48
@@ -125,9 +125,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
@@ -253,11 +254,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.
+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
@@ -288,6 +291,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}.
@@ -296,7 +306,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
+few different directories and files.
@item -i
Index: utils/djtar/djtar.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/utils/djtar/djtar.c,v
retrieving revision 1.7
diff -p -u -r1.7 djtar.c
--- djtar.c 1999/11/14 14:19:17 1.7
+++ djtar.c 2001/02/16 10:24:50
@@ -24,6 +24,15 @@ Fatal(const char *msg)
exit(1);
}
+static void *
+djtmalloc(const size_t size)
+{
+ void * ptr = malloc(size);
+ 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,9 +76,7 @@ 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 *ce = (CE *)djtmalloc(sizeof(CE));
ce->from = strdup(from);
ce->to = strdup(to);
ce->next = htab[h];
@@ -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 = djtmalloc(sizeof(struct skip_dir_list));
+ new_entry->skip_dir = strdup(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,9 +206,7 @@ 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 *)djtmalloc(sizeof(CHANGE));
ch->next = change_root;
change_root = ch;
ch->old = strdup(fname);
@@ -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 *)djtmalloc(strlen(new) + (pos-fname) + 2);
*pos = 0;
sprintf(ch->new, "%s/%s", fname, new);
}
@@ -294,13 +318,39 @@ 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)))
+ 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))
@@ -478,12 +528,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]));
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);
}
@@ -495,6 +547,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])
@@ -524,8 +577,17 @@ main(int argc, char **argv)
if (argv[i][2] == '.')
dot_switch = 0;
break;
+ case 'e':
+ skip_entry = djtmalloc(sizeof(struct skip_dir_list));
+ skip_entry->skip_dir = strdup(argv[++i]);
+ skip_entry->next = skip_dirs;
+ skip_dirs = skip_entry;
+ break;
case 'o':
- only_dir = strdup(argv[++i]);
+ only_entry = djtmalloc(sizeof(struct only_dir_list));
+ only_entry->only_dir = strdup(argv[++i]);
+ only_entry->next = only_dirs;
+ only_dirs = only_entry;
break;
case 'p':
to_stdout = 1;
- Raw text -