home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
djsrc106.arj
/
DJTARX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-18
|
6KB
|
281 lines
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include "oread.h"
void Fatal(char *msg)
{
fprintf(stderr, "Fatal! %s!\n", msg);
exit(1);
}
/*------------------------------------------------------------------------*/
typedef struct CE {
struct CE *next;
char *from;
char *to;
} CE;
#define HASHSIZE 2048
#define HASHMASK 2047
#define HASHBITS 11
CE *htab[HASHSIZE];
unsigned long hash(unsigned char *cp)
{
unsigned long rv = 0;
while (*cp)
rv += *cp++;
while (rv > HASHMASK)
rv = (rv & HASHMASK) + (rv >> HASHBITS);
return rv;
}
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->next = htab[h];
htab[h] = ce;
}
char *get_entry(char *from)
{
CE *ce;
for (ce = htab[hash(from)]; ce; ce=ce->next)
{
if (strcmp(ce->from, from) == 0)
return ce->to;
}
return from;
}
void DoNameChanges(char *fname)
{
FILE *f = fopen(fname, "r");
char from[100], to[100];
char line[250];
if (f == 0)
{
perror(fname);
exit(1);
}
while (1)
{
fgets(line, 250, f);
if (feof(f))
break;
to[0] = 0;
sscanf(line, "%s %s", from, to);
if (to[0])
store_entry(from, to);
}
fclose(f);
}
/*------------------------------------------------------------------------*/
FILE *change_file;
main(int argc, char **argv)
{
int i = 1;
if (argc < 2)
{
fprintf(stderr, "djtarx [-n changeFile] tarfile . . .\n");
exit(1);
}
while ((argc > i) && (argv[i][0] == '-'))
{
switch (argv[i][1])
{
case 'n':
DoNameChanges(argv[i+1]);
i++;
break;
}
i++;
}
for (; i < argc; i++)
tarread(argv[i]);
change_file = fopen("/tarchange.lst", "w");
dump_changes();
fclose(change_file);
}
/*------------------------------------------------------------------------*/
typedef struct CHANGE {
struct CHANGE *next;
char *old;
char *new;
int isdir; /* 0=file, 1=dir, 2=skip */
} CHANGE;
CHANGE *change_root = 0;
dump_changes()
{
CHANGE *c;
for (c=change_root; c; c=c->next)
fprintf(change_file, "%s -> %s\n", c->old, c->new);
}
int change(char *fname, char *problem, int isadir)
{
CHANGE *ch;
char new[200];
char *pos;
for (ch=change_root; ch; ch = ch->next)
if ((strncmp(fname, ch->old, strlen(ch->old)) == 0) && ch->isdir)
{
if (ch->isdir == 2)
{
printf(" [ skipping %s ]\n", fname);
return 0;
}
/* printf(" [ changing %s to ", fname); */
sprintf(new, "%s%s", ch->new, fname+strlen(ch->old));
strcpy(fname, new);
/* printf("%s ]\n", fname); */
return 1;
}
printf(" %s %s\n new name : ", problem, fname);
gets(new);
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->next = change_root;
change_root = ch;
ch->old = strdup(fname);
pos = strrchr(fname, '/');
if (pos && (strchr(new, '/') == 0))
{
ch->new = (char *)malloc(strlen(new) + (pos-fname) + 2);
if (ch->new == 0)
Fatal("Out of memory");
*pos = 0;
sprintf(ch->new, "%s/%s", fname, new);
}
else
ch->new = strdup(new);
ch->isdir = isadir;
strcpy(fname, ch->new);
if (new[0] == 0)
{
ch->isdir = 2;
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
typedef struct {
char name[100];
char operm[8];
char ouid[8];
char ogid[8];
char osize[11];
char otime[12];
char ocsum[8];
char flags[1];
char filler[356];
} TARREC;
char buf[512];
tarread(char *fname)
{
TARREC header;
int r;
void *f;
long perm, uid, gid, size, time, csum;
int dsize;
char *changed_name;
long posn=0;
f = oread_open(fname);
while (1)
{
oread_read(f, &header);
if (header.name[0] == 0)
break;
sscanf(header.operm, "%lo", &perm);
sscanf(header.ouid, "%lo", &uid);
sscanf(header.ogid, "%lo", &gid);
sscanf(header.osize, "%lo", &size);
sscanf(header.otime, "%lo", &time);
changed_name = get_entry(header.name);
printf("%08lx %6lo %12ld %s", posn, perm, size, changed_name);
if (header.flags[1] == 0x32)
printf(" -> %s", header.filler);
printf("\n");
posn += 512 + (size+511) & ~511;
/* printf("%6lo %02x %12ld %s\n", perm, header.flags[0], size, changed_name); */
if (changed_name[strlen(changed_name)-1] == '/')
{
changed_name[strlen(changed_name)-1] = 0;
do {
printf("Making directory %s\n", changed_name);
r = mkdir(changed_name
#ifdef GNUDOS
,0
#endif
);
if (r && (errno==EACCES))
{
change(changed_name, "Duplicate directory name", 2);
break;
}
if (r)
r = change(changed_name, "Unable to create directory", 1);
} while (r);
}
else
{
open_file:
r = open(changed_name, O_WRONLY|O_BINARY|O_CREAT|O_EXCL,
S_IWRITE|S_IREAD);
if (r < 0)
if (change(changed_name, "Cannot exclusively open file", 0))
goto open_file;
else
{
oread_skip(f, (size+511) & ~511);
}
else
{
while (size)
{
if (size < 512)
dsize = size;
else
dsize = 512;
oread_read(f, buf);
if (write(r, buf, dsize) < dsize)
{
printf("Out of disk space\n");
exit(1);
}
size -= dsize;
}
close(r);
}
}
}
oread_close(f);
}