home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <errno.h>
- #include <dos.h>
- #include <time.h>
- #include <io.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;
-
- int v_switch = 0;
-
- main(int argc, char **argv)
- {
- int i = 1;
- if (argc < 2)
- {
- fprintf(stderr, "djtarx [-n changeFile] [-v] tarfile . . .\n");
- exit(1);
- }
- while ((argc > i) && (argv[i][0] == '-'))
- {
- switch (argv[i][1])
- {
- case 'n':
- DoNameChanges(argv[i+1]);
- i++;
- break;
- case 'v':
- v_switch = 1;
- 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, *info;
-
- 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;
- }
- info = strstr(fname, ".info-");
- if (info)
- {
- strcpy(new, fname);
- info = strstr(new, ".info-");
- strcpy(info+2, info+6);
- printf("[ changing %s to %s ]\n", fname, new);
- }
- else
- {
- char *plus = strstr(fname, "++"), *plus2;
- if (plus)
- {
- strcpy(new, fname);
- plus2 = strstr(new, "++");
- strcpy(plus2, "plus");
- strcpy(plus2+4, plus+2);
- }
- else
- {
- 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, ftime, csum;
- int dsize;
- char *changed_name;
- long posn=0;
- struct tm tm;
-
- 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", &ftime);
- changed_name = get_entry(header.name);
- if (v_switch)
- printf("%08lx %6lo ", posn, perm);
- else
- printf("%c%c%c%c ",
- perm & 040000 ? 'd' : '-',
- perm & 000400 ? 'r' : '-',
- perm & 000200 ? 'w' : '-',
- perm & 000100 ? 'x' : '-');
- printf("%.20s %9ld %s", ctime(&ftime)+4, 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 {
- r = mkdir(changed_name
- #ifdef __GO32__
- ,0
- #endif
- );
- if (r && (errno==EACCES))
- {
- change(changed_name, "Duplicate directory name", 2);
- continue;
- }
- if (r)
- r = change(changed_name, "Unable to create directory", 1);
- else
- printf("Making directory %s\n", changed_name);
- } 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
- {
- long ftv;
- struct ftime ftimes;
- struct tm *tm;
- 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);
- r = open(changed_name, O_RDONLY);
- tm = localtime(&ftime);
- ftimes.ft_tsec = tm->tm_sec / 2;
- ftimes.ft_min = tm->tm_min;
- ftimes.ft_hour = tm->tm_hour;
- ftimes.ft_day = tm->tm_mday;
- ftimes.ft_month = tm->tm_mon+1;
- ftimes.ft_year = tm->tm_year - 80;
- setftime(r, &ftimes);
- close(r);
- if (!(perm & 0200))
- _chmod(changed_name, 1, FA_RDONLY);
- }
- }
- }
- oread_close(f);
- }
-