[net.sources] yasa.c

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