/* Split
 *
 * by Thies Wellpott
 *
 * Usage: Split <infile> <outfile> size1 [size2 [size3] ...]
 * Splits infile
 * sizes in byte (e. g. "1204"), or KB (e. g. "4K")
 *
 * compile (SAS C V5.10a):
 *   LC -cisu -rr -v -O Split
 * link:
 *   BLink FROM LIB:c.o,Split.o TO Split SC SD ND LIB LIB:lcr.lib
 *
 *
 * HISTORY
 *
 * V1.00  28.6.92
 *   first version
 *
 *
 * TODO
 *
 * -
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <exec/memory.h>
#include <dos/dos.h>

#define VERSION "1.00"
#define DATE "28.06.92"
#define BUFMIN (4 * 1024)        /* 4 KB */
#define BUFMAX (128 * 1024)      /* 128 KB */


/* for DOS-command Version (OS 2.0) */
char version[] = "$VER: Split V"VERSION" ("DATE")";
UBYTE *buf = NULL;
int buflen = BUFMAX;
BPTR infhd = NULL, outfhd = NULL;


void close_all(char *s, int err)
/* close/free all and exit */
{
   if (outfhd) Close(outfhd);
   if (infhd) Close(infhd);
   if (buf) FreeMem(buf, buflen);

   if (s) printf("%s!\n", s);
   exit(err);
}


void usage(void)
/* print usage and exit */
{
   printf("\2334m%s\2330m by Thies Wellpott\n\n", &version[6]);
   printf("Usage: Split <infile> <outfile> size1 [size2 [size3] ...]\n");

   exit(5);
}


void main(int argc, char *argv[])
{
   int i, mul, sizes;
   long size[17], num_to_read, read, to_read;
   char outname[128];

   if ((argc < 4) || (*argv[1] == '?'))      /* print usage? */
      usage();

   sizes = min(argc-3, 16);                  /* get sizes */
   for (i = 0; i < sizes; i++)
   {
      mul = 1;
      if (toupper(argv[i+3][strlen(argv[i+3])-1]) == 'K')
      {
	 argv[i+3][strlen(argv[i+3])-1] == 0;
	 mul = 1024;
      }
      size[i] = atoi(argv[i+3]) * mul;
   }

   size[sizes] = 1<<31 - 1;		     /* = 2^31-1, rest of infile */

   while (buflen >= BUFMIN)                  /* get buffer */
   {
      if (buf = AllocMem(buflen, MEMF_CLEAR))
	 break;
      buflen /= 2;			     /* try half size */
   }
   if (!buf)                                 /* got buffer? */
      close_all("Out of memory", 20);

   if (!(infhd = Open(argv[1], MODE_OLDFILE)))
      close_all("Can`t open infile", 20);

   for (i = 0; i <= sizes; i++)
   {
      sprintf(outname, "%s.%d", argv[2], i);
      if (!(outfhd = Open(outname, MODE_NEWFILE)))
	 close_all("Can`t open outfile", 20);

      to_read = size[i];

      while (to_read != 0)
      {
	 num_to_read = min(buflen, to_read);
	 to_read -= num_to_read;

	 read = Read(infhd, buf, num_to_read);
	 if (read == -1)
	    close_all("infile: read error", 20);
	 if (read < num_to_read)
	 {
	    if (i != sizes)
	    {
	       printf("outfile %d truncated!\n", i);
	       i = sizes+1;			      /* break loop */
	    }
	    else
	       to_read = 0;
	 }

	 if (Write(outfhd, buf, read) != read)
	    close_all("outfile: write error", 20);
      } /* while (to_read > 0) */

      Close(outfhd);
      outfhd = NULL;
   } /* for (i) */

   close_all(NULL, 0);
}

