Date: Thu, 24 Jan 91 12:05:17 CST
From: [email protected] (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
              [email protected]  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