Date: Thu, 24 Jan 91 12:05:17 CST
From: 231b3679@fergvax.unl.edu (CS 231 section 2)
Subject: macbin.shar

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./Macbin`
then
  mkdir ./Macbin
  echo "mkdir ./Macbin"
fi
if `test ! -s ./Macbin/macbin_readme`
then
echo "writing ./Macbin/macbin_readme"
cat > ./Macbin/macbin_readme << '\End\Of\Shar\'
Macbin Documentation
--------------------
 
   Purpose:  Convert .data, .info, and .rsrc files into one .bin
      file for easy downloading (etc).
      
            MyMacFile.data  \
            MyMacFile.info   >  MyMacFile.bin
            MyMacFile.rsrc  /
 
   How to Use:
      Compile the macbin.c source code file.  The easiest way to do
      that would be to use the included Makefile.  Just type "Make"
      at your unix host's prompt, and that should do it.
           [Power user's note: if you have the Gnu C compiler
            available, try to use it.  It will produce a substantially
            smaller executable.  Type "make gcc" for that version.]
      Ok, now let's assume after a "ls" you have this stuff in the
      current directory:
 
      % ls
      Makefile   a.sit.bin  macbin     macbin.c
 
      Let's also assume you have the nifty "unsit" executable to
      decompress Stuffit files, and you type:
 
      % unsit a.sit.bin
      % ls
      Makefile                      Validator_documentation.info
      Validator_1.11.data           Validator_documentation.rsrc
      Validator_1.11.info           a.sit.bin
      Validator_1.11.rsrc           macbin
      Validator_documentation.data  macbin.c
 
      Now you want to download the decompressed files... but, you
      need to combine Validator_1.11.data, Validator_1.11.info,
      and Validator_1.11.rsrc into a single file, not 3 files.
      Here's where macbin comes in.
 
      % macbin -d *
 
      You'll get a few messages from macbin, mostly telling you
      that it didn't macbin-ize some files because there weren't
      corresponding .data, .info., and .rsrc files:
 
      No Makefile.info file!
      No a.sit.bin.info file!
      No macbin.info file!
      No macbin.c.info file!
 
      Those files won't be altered by macbin.  Do a "ls" however,
      and you will find that those .data, .info, and .rsrc files
      have been combined into one .bin file.  Those three files
      were also deleted afterwards, since you passed "-d". I
      recommend passing "-d" since you really have no use for those
      other files anyway.
 
      % ls
      Makefile                     a.sit.bin
      Validator_1.11.bin           macbin
      Validator_documentation.bin  macbin.c
 
      Notice now how we have our unstuffed files in .bin form, so
      we can download them (or whatever).
 
   Version History:
      1.0      Jim Budler        First release.  Handled one file
               jimb@amdcad.UUCP  only, and didn't have the ability
                                 to delete the .d, .i, .r files.
      
      2.0      Mike Gleason      Added batch files, option to delete
                                 the .d, .i, .r, files after
                                 processing.
                           
      3.0      Mike Gleason      Improved batch file handling, so
                                 the user wouldn't need to type
                                 "macbin file1 file2 file3 .. filen"
                                 but instead "macbin *". Obviously,
                                 in previous versions using "macbin *"
                                 would assume we had files like
                                 file1.data.data, file1.data.info,
                                 file1.data.rsrc, file1.info.data...
                                 One would realize the great
                                 convenience of this feature if you
                                 have had to unsit a whole buttload
                                 of files, and then type in mile-long
                                 command lines.
 
      3.0.1    Mike Gleason      Fixed silly bug to work with old
                                 style function declarations, so one
                                 could compile with cc instead of gcc.
                        
*/
 
                        
/* structure of the info file - from MacBin.C
   char zero1;
   char nlen;
   char name[63];
   char type[4];     65 0101
   char creator[4];  69
   char flags;    73
   char zero2;    74 0112
   char location[6]; 80
   char protected;      81 0121
   char zero3;    82 0122
   char dflen[4];
   char rflen[4];
   char cdate[4];
   char mdate[4];
*/

/* eof */
\End\Of\Shar\
else
  echo "will not over write ./Macbin/macbin_readme"
fi
if `test ! -s ./Macbin/macbin.c`
then
echo "writing ./Macbin/macbin.c"
cat > ./Macbin/macbin.c << '\End\Of\Shar\'
 
/* #define SYSV */
/* 
   Note:  to run this program on a System V Unix system, remove all calls to
   the bzero() procedure.  It doesn't exist on System V, and isn't needed.
   [To do this easily, just uncomment the above line, and the lines
    containing bzero() will not be compiled. --MG] */
 
#include <stdio.h>
 
 
main (argc, argv)
   int argc;
   char **argv;
{
   int i, deleteOn = 0;
   
   if (argc < 2) 
   {
		fprintf(stderr, "\nUsage: %s [-d] <list of files>\n", argv[0]);
		fprintf(stderr, "\nPurpose: merges <prefix>.info, <prefix>.data, <prefix>.rsrc");
		fprintf(stderr, "\n  into a valid macbinary file, <prefix>.bin, and optionally");
		fprintf(stderr, "\n  deletes the .info, .data, .rsrc files (the -d).\n\n");
      exit(1);
   }
   
   if (argc > 3)
      FilterArgumentList(argc, argv);
   
   for (i=1; i<argc; i++)
      if (argv[i][0] == '-' && argv[i][1] == 'd')
         deleteOn = !deleteOn;   /* you can toggle delete mode on/off */
      else
         if (argv[i][0] != '\0')  /* if the first character is not 0 */
            macbin(argv[i], deleteOn);
}  /* main */
 
 
 
 
 
FilterArgumentList(argc, argv)
   int argc;
   char **argv;
{
   register int i;
   
   for (i=1; i<argc-2; i++)
   {
		/* Compare the last five characters of the arguments to tell if
			the user passed a generic wildcard. */
      if    (LastFive(argv[i], ".data") &&
				 LastFive(argv[i+1], ".info") &&
				 LastFive(argv[i+2], ".rsrc")
				 )
      {
         /* if 3 successive arguments contain .data,
            .info, and .rsrc, (i.e. we have MyFkey.data,
            MyFkey.info, and MyFkey.rsrc) then let's really
            only pass the prefix (i.e. "MyFkey") */
            
         argv[i][ strlen(argv[i]) - 5 ] = 
            argv[i+1][0] = argv[i+2][0] = '\0';
            
         /* we'll use the first character of an argument as a
            signal to ignore it. It's a kludge, but it works. */
      }
   }
}  /* FilterArgumentList */
 
 
 
LastFive(a, b)
	char *a, *b;
{
   register char *c = a;

	/* this oddball routine compares the last five characters of a with
		the first 5 characters of b. */
	while (*c) c++;  /* find the end of the string */

	if (*(c-5) == *(b)   &&
		 *(c-4) == *(b+1) &&
		 *(c-3) == *(b+2) &&
		 *(c-2) == *(b+3) &&
		 *(c-1) == *(b+4)
		 )
			 return (1);  /* yup, they were equal */
	else
			 return (0);  /* nope, at least one was different */
} /* LastFive */




macbin (prefix, delete)
   char *prefix;
   int  delete;
{
   FILE *fd, *ofd;
   char oname[128];
   char iname[128];
   char dname[128];
   char rname[128];
   char buf[128];
   
#ifndef SYSV
   bzero(buf, 128);
#endif
 
   strcpy(oname, prefix);
   strcat(oname, ".bin");
   
   if ((ofd = fopen( oname, "w")) == NULL)
   {
      fprintf(stderr, "\n Cannot open %s for writing.\n", oname);
      return(1);
   }
   
   strcpy(iname, prefix);
   strcat(iname, ".info");
   if ((fd = fopen(iname, "r")) == NULL)
   {
      fprintf(stderr, "No %s file!\n", iname);
      fclose(ofd);
      unlink(oname);
      return(1);
   }
   
   if (fread(buf, sizeof(*buf), 128, fd) > 0)
   {
      if (buf[74] & 0x40) buf[81] = '\1'; /* protected */
      buf[74] = '\0'; /* clear zero2 */
      fwrite(buf, sizeof(*buf), 128, ofd);
#ifndef SYSV
      bzero(buf, 128);
#endif
   }
   fclose(fd);
   
   strcpy(dname, prefix);
   strcat(dname, ".data");
   if ((fd = fopen(dname, "r")) == NULL)
   {
      fprintf(stderr, "No %s file!\n", dname);
      fclose(ofd);
      unlink(oname);
      return(1);
   }
   
   while (fread(buf, sizeof(*buf), 128, fd) > 0)
   {
      fwrite(buf, sizeof(*buf), 128, ofd);
#ifndef SYSV
      bzero(buf, 128);
#endif
   }
   fclose(fd);
   
   strcpy(rname, prefix);
   strcat(rname, ".rsrc");
   if ((fd = fopen(rname, "r")) == NULL)
   {
      fprintf(stderr, "No %s file!\n", rname);
      fclose(ofd);
      unlink(oname);
      return(1);
   }
   while (fread(buf, sizeof(*buf), 128, fd) > 0)
   {
      fwrite(buf, sizeof(*buf), 128, ofd);
#ifndef SYSV
      bzero(buf, 128);
#endif
   }
   fclose(fd);
   
   if (delete)
   {
      unlink(iname);
      unlink(rname);
      unlink(dname);
   }
}  /* macbin */
 
/* EOF */
\End\Of\Shar\
else
  echo "will not over write ./Macbin/macbin.c"
fi
if `test ! -s ./Macbin/Makefile`
then
echo "writing ./Macbin/Makefile"
cat > ./Macbin/Makefile << '\End\Of\Shar\'

# Compile with Gnu C, if possbile; it produced 20% smaller code in this case.

all:
	cc -O macbin.c -o macbin

cc:
	cc -O macbin.c -o macbin

gcc:
	gcc -O macbin.c -o macbin

shar:
	shar -f macbin_readme macbin.c Makefile > macbin.shar

\End\Of\Shar\
else
  echo "will not over write ./Macbin/Makefile"
fi
echo "Finished archive 1 of 1"
exit

