/* ** TARSCAN ** News archive tape scanner/splitter. ** ** Reads a tar news archive, optionally splitting it into smaller ** archives or listing the contained files and their Subject lines ** on stdout. Useful for creating a multi-floppy archive when ** you might want to retrieve just one file from the 27th floppy ** of an archive. Each volume is a complete stand-alone tar archive. ** ** Arguments: ** ** One or more of: ** ** -v Write file names and Subject lines on stdout. ** (Mainly for news articles or mail.) If the ** -s switch is present, tarscan will announce ** volume changes on stdout. ** ** -f filename Copy the input tarfile to the named file. ** ** -s size Only used with -f. Break the tarfile into ** individual tarfiles that don't exceed 'size' ** tape blocks. If 'filename' is a device, ** the user will be prompted to change media ** when appropriate. If 'filename' is not a ** device, then the input tarfile is copied ** into a series of files with 'filename' as ** a base and sequential numbers as a suffix. ** (Beware of 14-character filenames!) ** */ #include #include #include #define TBLOCK 512 #define NAMSIZ 100 #define CLUMP 1 extern char *strcpy(); extern char *optarg; extern int optind; typedef union { char dummy[TBLOCK]; struct { char name[NAMSIZ]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char chksum[8]; char linkflag; char linkname[NAMSIZ]; } D; } HEADER; #define OCTAL(x) (((x) >= '0') && ((x) <= '7')) void usage () { fprintf (stderr, "Usage: tarscan [-v] [-f filename [-s size] ] D.name, q=p+TBLOCK, start=1; pD.name[0]) { if (H->D.name[NAMSIZ - 1]) { H->D.name[NAMSIZ - 1] = 0; fprintf(stderr, "Name \"%s\" is more than %d bytes long, I give up!\n", H->D.name, NAMSIZ); exit(1); } size = 0; if (H->D.linkflag != '1') for (p = H->D.size,q=H->D.size+12; p 0); first = Nblocks > 0; if (make_copy && ((outblocks+Nblocks+3) > volume_size)) { if (outfile > 0) { write (outfile, zbuff, TBLOCK); write (outfile, zbuff, TBLOCK); close (outfile); } if (device) { outfile = open (outname, O_RDONLY); } else { sprintf (t_outname, "%s%03d", outname , outvol); outfile=creat(t_outname, 0777); } if (outfile == -1) { perror ("open output file"); exit(1); } if (verbose && limit_size) if (device) printf ("\n\nVolume %d on %s\n\n", outvol, outname); else printf ("\n\nTarfile: %s\n\n", t_outname); outvol++; outblocks = 0; } printf ("%s", H->D.name); } if (make_copy) { if (write(outfile, (char *) H, TBLOCK) != TBLOCK) { perror ("write tape block"); exit (1); } outblocks++; } } exit(0); }