131535Sminshall /* tarread.c */
231535Sminshall /* Copyright (c) 1985, by Carnegie-Mellon University */
331535Sminshall
431535Sminshall #include <stdio.h>
531535Sminshall #include <v2tov3.h>
631535Sminshall #include <sys\types.h>
731535Sminshall #include <sys\stat.h>
831535Sminshall #include "tar.h"
931535Sminshall
1031535Sminshall char usage[] = "tarread: usage: tarread tx[vwz] tarfile\n";
1131535Sminshall union hblock hbuf;
1231535Sminshall
1331535Sminshall int verbose = 0;
1431535Sminshall int confirm = 0;
1531535Sminshall int binary = 0;
1631535Sminshall char cmd;
1731535Sminshall
main(argc,argv)1831535Sminshall main(argc, argv)
1931535Sminshall int argc;
2031535Sminshall char *argv[];
2131535Sminshall {
2231535Sminshall FILE *fp;
2331535Sminshall char *cp;
2431535Sminshall
2531535Sminshall if (argc != 3) {
2631535Sminshall fprintf(stderr, usage);
2731535Sminshall exit(1);
2831535Sminshall }
2931535Sminshall
3031535Sminshall for (cp = argv[1]; *cp; cp++)
3131535Sminshall switch (*cp) {
3231535Sminshall case 't':
3331535Sminshall case 'x':
3431535Sminshall cmd = *cp;
3531535Sminshall break;
3631535Sminshall
3731535Sminshall case 'v':
3831535Sminshall verbose++;
3931535Sminshall break;
4031535Sminshall case 'z':
4131535Sminshall binary++;
4231535Sminshall break;
4331535Sminshall case 'w':
4431535Sminshall confirm++;
4531535Sminshall break;
4631535Sminshall default:
4731535Sminshall fprintf(stderr, "tarread: unknown switch %c\n", *cp);
4831535Sminshall fprintf(stderr, usage);
4931535Sminshall exit(1);
5031535Sminshall }
5131535Sminshall
5231535Sminshall if ((fp = fopen(argv[2], "rb")) == NULL) {
5331535Sminshall fprintf(stderr, "tarrread: cannot open %s\n", argv[2]);
5431535Sminshall exit(1);
5531535Sminshall }
5631535Sminshall
5731535Sminshall for (;;) {
5831535Sminshall if (fread(&hbuf, sizeof(hbuf), 1, fp) != 1) {
5931535Sminshall perror("fread");
6031535Sminshall exit(1);
6131535Sminshall }
6231535Sminshall if (!proc_file(fp))
6331535Sminshall break;
6431535Sminshall }
6531535Sminshall }
6631535Sminshall
6731535Sminshall
proc_file(fp)6831535Sminshall int proc_file(fp)
6931535Sminshall FILE *fp;
7031535Sminshall {
7131535Sminshall char name[NAMSIZ];
7231535Sminshall unsigned short mode;
7331535Sminshall short uid, gid;
7431535Sminshall long size, mtime;
7531535Sminshall char c;
7631535Sminshall int confrmd;
7731535Sminshall long skip;
7831535Sminshall
7931535Sminshall if (hbuf.dbuf.name[0] == '\0')
8031535Sminshall return (NULL);
8131535Sminshall
8231535Sminshall strcpy(name, hbuf.dbuf.name);
8331535Sminshall if (sscanf(hbuf.dbuf.mode, "%o", &mode) != 1)
8431535Sminshall fprintf("Couldn't read mode\n");
8531535Sminshall if (sscanf(hbuf.dbuf.uid, "%o", &uid) != 1)
8631535Sminshall fprintf("Couldn't read uid\n");
8731535Sminshall if (sscanf(hbuf.dbuf.gid, "%o", &gid) != 1)
8831535Sminshall fprintf("Couldn't read gid\n");
8931535Sminshall if (sscanf(hbuf.dbuf.size, "%12lo %12lo", &size, &mtime) != 2)
9031535Sminshall fprintf("Couldn't read size or mtime\n");
9131535Sminshall
9231535Sminshall skip = (size + TBLOCK - 1) / TBLOCK * TBLOCK;
9331535Sminshall
9431535Sminshall switch (cmd) {
9531535Sminshall case 't':
9631535Sminshall if (verbose)
9731535Sminshall printf("%8o %d/%d\t %6ld %.24s %s\n", mode,
9831535Sminshall uid, gid, size, ctime(&mtime), name);
9931535Sminshall else
10031535Sminshall printf("%s\n", name);
10131535Sminshall
10231535Sminshall break;
10331535Sminshall
10431535Sminshall case 'x':
10531535Sminshall if (verbose)
10631535Sminshall printf("x %s: ", name);
10731535Sminshall confrmd = 1;
10831535Sminshall
10931535Sminshall if (confirm) {
11031535Sminshall confrmd = 0;
11131535Sminshall if ((c = getchar()) == 'y')
11231535Sminshall confrmd++;
11331535Sminshall while (c != '\n')
11431535Sminshall c = getchar();
11531535Sminshall if(!confrmd)
11631535Sminshall break;
11731535Sminshall }
11831535Sminshall
11931535Sminshall if(extract(name, size, mode, mtime, fp))
12031535Sminshall skip = 0;
12131535Sminshall
12231535Sminshall if (verbose)
12331535Sminshall printf("\n");
12431535Sminshall break;
12531535Sminshall }
12631535Sminshall if (fseek(fp, skip, 1)) {
12731535Sminshall perror("fseek");
12831535Sminshall exit(1);
12931535Sminshall }
13031535Sminshall return (1);
13131535Sminshall }
13231535Sminshall
13331535Sminshall
extract(fname,size,mode,mtime,ifp)13431535Sminshall int extract(fname, size, mode, mtime, ifp)
13531535Sminshall char *fname;
13631535Sminshall long size;
13731535Sminshall unsigned short mode;
13831535Sminshall long mtime;
13931535Sminshall FILE *ifp;
14031535Sminshall {
14131535Sminshall FILE *ofp;
14231535Sminshall char fbuf[TBLOCK];
14331535Sminshall long copied, left;
14431535Sminshall char *s, *np, *strchr();
14531535Sminshall struct stat sbuf;
14631535Sminshall
14731535Sminshall for(np = fname; s = strchr(np, '/'); np = s+1) {
14831535Sminshall *s = '\0';
14931535Sminshall if(stat(fname, &sbuf)) {
15031535Sminshall if(mkdir(fname))
15131535Sminshall perror("mkdir");
15231535Sminshall } else if(!(sbuf.st_mode & S_IFDIR)) {
15331535Sminshall fprintf(stderr, "\n%s: Not a directory", fname);
15431535Sminshall *s = '/';
15531535Sminshall fprintf(stderr, "\ntar: %s - cannot create", fname);
15631535Sminshall return (0);
15731535Sminshall }
15831535Sminshall *s = '/';
15931535Sminshall }
16031535Sminshall if(!*np)
16131535Sminshall return (0);
16231535Sminshall
16331535Sminshall if (binary) {
16431535Sminshall if ((ofp = fopen(fname, "wb")) == NULL) {
16531535Sminshall perror("extract:");
16631535Sminshall return (0);
16731535Sminshall }
16831535Sminshall } else {
16931535Sminshall if ((ofp = fopen(fname, "w")) == NULL) {
17031535Sminshall perror("extract:");
17131535Sminshall return (0);
17231535Sminshall }
17331535Sminshall }
17431535Sminshall
17531535Sminshall for(copied = 0; copied < size; copied += TBLOCK) {
17631535Sminshall if(fread(fbuf, TBLOCK, 1, ifp) != 1) {
17731535Sminshall perror("fread");
17831535Sminshall exit(1);
17931535Sminshall }
18031535Sminshall left = size - copied;
18131535Sminshall if(fwrite(fbuf, (int)min(left, TBLOCK), 1, ofp) != 1) {
18231535Sminshall perror("fwrite");
18331535Sminshall exit(1);
18431535Sminshall }
18531535Sminshall }
18631535Sminshall
18731535Sminshall if(fclose(ofp)) {
18831535Sminshall perror("fclose");
18931535Sminshall exit(1);
19031535Sminshall }
191*31536Sminshall
192*31536Sminshall /*
193*31536Sminshall * Now, set modification time.
194*31536Sminshall */
195*31536Sminshall {
196*31536Sminshall #include <sys\utime.h>
197*31536Sminshall struct utimbuf utim;
198*31536Sminshall
199*31536Sminshall utim.modtime = mtime;
200*31536Sminshall
201*31536Sminshall if (utime(fname, &utim) == -1) {
202*31536Sminshall perror("utime");
203*31536Sminshall exit(1);
204*31536Sminshall }
205*31536Sminshall }
206*31536Sminshall
20731535Sminshall return (1);
20831535Sminshall }
209