/***********************************************************************
Split a binary file into pieces of a specified (or default) size.

Usage:
        bsplit [[-nnn] [-] filename]

A -nnn bytecount option sets the split piece size for subsequent
files.  Stdin is assumed if a bare - is given, or if no files are
specified.  Multiple filenames may be specified.

No check is made to see whether the output files (named with the input
file name and the suffixes "-001", "-002", etc.) exist.

[29-Aug-1990]
***********************************************************************/
#include <stdio.h>
#include <string.h>

#ifdef __STDC__

#ifndef __GNUC__
#include <stdlib.h>
#endif                          /* __GNUC__ */

#ifdef __COMPILER_KCC__
#define WB_FLAGS "wb8"
#define RB_FLAGS "rb8"
void bsplit();
#else                           /* NOT __COMPILER_KCC__ */
void bsplit(int size, char *name);
#endif                          /* __COMPILER_KCC__ */

#else                           /* NOT __STDC__ */
void bsplit();
#endif                          /* __STDC__ */

#ifdef VMS
#define RB_FLAGS        "rb","rfm=fix","bls=512","mrs=512"
#define WB_FLAGS        "wb","rfm=fix","bls=512","mrs=512"
#endif

#ifndef RB_FLAGS
#define RB_FLAGS "r"
#endif

#ifndef WB_FLAGS
#define WB_FLAGS "w"
#endif

#ifdef ABS
#undef ABS
#endif
#define ABS(n)          ( ((n) < 0) ? -(n) : (n) )
#define ROUNDABSUP(n)   ((ABS(n) + 511) & ~0x1ff)

#define DEFAULT_SIZE    32768

int
main(argc, argv)
    int argc;
    char *argv[];
{
    int size;
    int k;
    int nfiles;

    size = DEFAULT_SIZE;

    for (nfiles = 0, k = 1; k < argc; ++k)
    {
        if (strcmp(argv[k], "-") == 0) /* bsplit stdin */
        {
            bsplit(ROUNDABSUP(size), (char *) NULL);
            nfiles++;
        }
        else if (*argv[k] == '-')       /* expect -nnn */
        {
            (void) sscanf(&argv[1][1], "%d", &size);
            if (size < 512)     /* prevent nonsense values */
                size = DEFAULT_SIZE;
        }
        else
        {
            bsplit(ROUNDABSUP(size), argv[k]);
            nfiles++;
        }
    }
    if (nfiles == 0)                    /* just process stdin */
        bsplit(ROUNDABSUP(size), (char *) NULL);
    exit(0);
    return (0);                 /* keep compilers happy */
}

void
bsplit(size, inname)
    int size;
    char *inname;
{
    register FILE *in;
    register FILE *out;
    char outname[512];
    register int n;
    int npart;
    register int c;

    if (inname == (char *) NULL)
    {
        in = stdin;
        inname = "stdin";
    }
    else
        in = fopen(inname, RB_FLAGS);
    if (in == (FILE *) NULL)
    {
        (void) fprintf(stderr, "?Cannot open file [%s]\n", inname);
        return;
    }
    (void) fprintf(stderr, "[%s]\n", inname);
    for (npart = 1; !feof(in); ++npart)
    {
        sprintf(outname, "%s-%03d", inname, npart);
        out = fopen(outname, WB_FLAGS);
        if (out == (FILE *) NULL)
        {
            (void) fprintf(stderr,
                           "?Cannot open file [%s]\n", outname);
            return;
        }
        (void) fprintf(stderr, "\t[%s]", outname);
        for (n = 0; n < size; ++n)
        {
            c = getc(in);
            if ((c == EOF) && feof(in))
                break;
            putc(c, out);
        }
        (void) fclose(out);
        (void) fprintf(stderr, " %d bytes [OK]\n", n);
    }
}
