home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <string.h>
- #include <errno.h>
-
- FILE *change_file;
-
- main(int argc, char **argv)
- {
- int i;
- for (i=1; 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));
- 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);
- *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 f, r;
- long perm, uid, gid, size, time, csum;
- int dsize;
- f = open(fname, O_RDONLY|O_BINARY);
-
- while (1)
- {
- if (read(f, &header, 512) < sizeof(header))
- break;
- 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);
- printf("%6lo %02x %12ld %s\n", perm, header.flags[0], size, header.name);
- if (header.name[strlen(header.name)-1] == '/')
- {
- header.name[strlen(header.name)-1] = 0;
- do {
- printf("Making directory %s\n", header.name);
- r = mkdir(header.name
- #ifdef GNUDOS
- ,0
- #endif
- );
- if (r && (errno==EACCES))
- {
- change(header.name, "Duplicate directory name", 2);
- break;
- }
- if (r)
- r = change(header.name, "Unable to create directory", 1);
- } while (r);
- }
- else
- {
- open_file:
- r = open(header.name, O_WRONLY|O_BINARY|O_CREAT|O_EXCL, S_IWRITE|S_IREAD);
- if (r < 0)
- if (change(header.name, "Cannot exclusively open file", 0))
- goto open_file;
- else
- {
- lseek(f, (size+511) & ~511, 1);
- }
- else
- {
- while (size)
- {
- if (size < 512)
- dsize = size;
- else
- dsize = 512;
- read(f, buf, 512);
- if (write(r, buf, dsize) < dsize)
- {
- printf("Out of disk space\n");
- exit(1);
- }
- size -= dsize;
- }
- close(r);
- }
- }
- }
- close(f);
- }
-