derek@uwvax.UUCP (Derek Zahn) (12/12/84)
Here's a modified version of the C sharchiver that appeared a while back. It recursively descends the directory structure and then rebuilds it upon extraction. derek #!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # This is a shell archive. # Run the following text with /bin/sh to extract. echo shar: extracting yasa.c cat - << \Funky!Stuff! > yasa.c #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/dir.h> /* * yasa.c (Yet Another Shell Archiver) * * Modified from a program by Gary Perlman * * This version recursively descends directories and rebuilds the directory * structure later. At times this is quite handy. * * Derek Zahn @ wisconsin * ...!{allegra,heurikon,ihnp4,seismo,sfwin,ucbvax,uwm-evax}!uwvax!derek * derek@wisc-rsch.arpa * */ #define READ_PERMISSION 4 #define DELIM "Funky!Stuff!" struct stat *buf; char SHAR[20]; int Verbose = 0; char *malloc(); /* * The main program. See if we are Verbose, then check and process the inputs. */ main (argc, argv) int argc; char **argv; { int status = 0; strcpy(SHAR, argv[0]); /* Are we verbose today? */ if (!strcmp (argv[1], "-v")) { Verbose = 1; argc--; argv++; } /* Make sure we have files to process */ if (argc == 1) { fprintf (stderr, "%s: No input files\n", SHAR); fprintf (stderr, "USAGE: %s [-v] files > archive\n", SHAR); exit (1); } buf = (struct stat *)malloc(sizeof (struct stat)); /* See if the specified files are legal and print the header. */ if (header (argc, argv)) exit (2); /* Archive the files. Rah. */ while (--argc) status += shar (*++argv); exit (status); } /* This here thing checks for bad input and prints the header of the */ /* archive */ header (argc, argv) char **argv; { int i, problems = 0; for (i = 1; i < argc; i++) if (access (argv[i], READ_PERMISSION)) { fprintf (stderr, "%s: Can't read %s\n", SHAR, argv[i]); problems++; } if (problems) return (problems); puts ("#!/bin/sh-----cut here-----cut here-----cut here-----cut here-----"); puts ("# This is a shell archive."); puts ("# Run the following text with /bin/sh to extract.\n"); return (0); } /* Here the work is done. Process the given file. */ shar (file) char *file; { char line[BUFSIZ]; FILE *ioptr; DIR *dirp; char pathname[80]; char filename[80]; struct direct *name; int numentries, count; getwd(pathname); sprintf(filename, "%s/%s",pathname, file); /* If the file is not funky.... */ if(stat(filename, buf) != -1) { /* If this entry is a directory... */ if((buf->st_mode) & S_IFDIR) { /* First, change to the directory and make the new one */ chdir(filename); printf("mkdir %s\n",file); printf("cd %s\n", file); if(Verbose) { printf("echo %s: creating directory %s\n", SHAR, file); fprintf(stderr, "%s: moving to directory %s\n", SHAR, filename); } /* Call shar again for each entry in this directory */ dirp = opendir(filename); while(name = readdir(dirp)) if(strcmp(name->d_name, ".") && strcmp(name->d_name, "..")) shar(name->d_name); closedir(dirp); /* Go back to where we started. */ chdir(pathname); printf("cd ..\n"); if(Verbose) { fprintf(stderr, "%s: done with directory %s\n", SHAR, filename); printf("echo %s: leaving directory %s\n", SHAR, file); } } else { if (ioptr = fopen (file, "r")) { if (Verbose) { fprintf (stderr, "%s: appending %s\n", SHAR, file); printf ("echo %s: extracting %s\n", SHAR, file); } /* Archive the file. */ printf ("cat - << \\%s > %s\n", DELIM, file); while (fgets (line, BUFSIZ, ioptr)) fputs (line, stdout); (void) fclose (ioptr); puts (DELIM); return (0); } else { fprintf (stderr, "%s: Can't open %s\n", SHAR, file); return (1); } } } else { fprintf(stderr, "%s: unable to access %s\n", SHAR, file); return(1); } } Funky!Stuff! -- Derek Zahn @ wisconsin ...!{allegra,heurikon,ihnp4,seismo,sfwin,ucbvax,uwm-evax}!uwvax!derek derek@wisc-rsch.arpa