blob: c3c22a305a352489b4439e1560809d95f0254173 [file] [log] [blame]
#ifdef lint
static char RCSid[] = "$RCSfile: dsplit.c,v $ $Revision: 1.9 $ $Date: 1995/03/12 01:31:03 $";
#endif
/*
Program dsplit: Splits a large file into pieces.
Usage:
dsplit [-size nnn] [input_file [output_base]]
Size is size of each output file, in bytes. The default is 1457000,
enough to fill a "1.44MB" diskette, save 152 bytes.
input_file is the name of the file to split up. A dash (-) indicates
standard input. Defaults to standard input.
output_base is the name of the output files to be written, minus the
extension. Dsplit adds suffixes 000, 001, ...
The default base name is dsplit.
*/
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if (defined (__MSDOS__) || defined (WIN32))
#include <io.h>
#include <fcntl.h>
#endif /* __MSDOS__ or WIN32 */
#ifndef FILENAME_MAX
#define FILENAME_MAX 1024
#endif
#define DEFAULT_NAME "dsplit"
#define DEFAULT_SIZE 1457000L
#if (defined (__MSDOS__) || defined (WIN32))
# define READ_OPTIONS "rb"
# define WRITE_OPTIONS "wb"
#else
# define READ_OPTIONS "r"
# define WRITE_OPTIONS "w"
#endif /* __MSDOS__ or WIN32 */
#ifndef MIN
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#endif
static unsigned long output_size = DEFAULT_SIZE;
static char* base_name = DEFAULT_NAME;
static FILE* input_handle;
static char* input_name = "-";
#ifdef __STDC__
static void init (int argc, char* argv[]);
static int write_one (int count);
static void ToLower (char* string);
static void usage_error (void);
#else /* not __STDC__ */
static void init (/* int argc, char* argv[] */);
static int write_one (/* int count */);
static void ToLower (/* char* string */);
static void usage_error (/* void */);
#endif /* __STDC__ */
#ifdef __STDC__
int main (int argc, char* argv[])
#else
int main (argc, argv)
int argc;
char* argv[];
#endif
{
int count;
/* Process command line arguments, open input file. */
init (argc, argv);
/* Write the output files */
for (count = 0 ; write_one (count) ; ++count)
;
/* Close input file (a matter of style) */
if (fclose (input_handle) != 0)
{
(void)fprintf (stderr, "Could not close file \"%s\" for input\n",
input_name);
return 1;
}
/* Normal successful conclusion */
return 0;
}
#ifdef __STDC__
static void init (int argc, char* argv[])
#else
static void init (argc, argv)
int argc;
char* argv[];
#endif
{
int iarg;
int name_count;
/* Initialize the input file handle to standard input. IBM's Toolset++
won't let me do this statically, unfortunately. */
input_handle = stdin;
/* Initialize for following loop */
name_count = 0;
/* Loop over command line arguments */
for (iarg = 1 ; iarg < argc ; ++iarg)
{
/* Point to argument,for convenience */
char* arg = argv[iarg];
/* If this argument is an option */
if (arg[0] == '-' && arg[1] != '\0')
{
/* Process option if recognized */
ToLower (arg+1);
if (strcmp (arg+1, "size") != 0)
usage_error ();
++iarg;
if (iarg >= argc)
usage_error ();
arg = argv[iarg];
if (sscanf (arg, "%ld", &output_size) != 1)
{
(void)fprintf (stderr, "Illegal numeric expression \"%s\"\n", arg);
exit (1);
}
}
else /* argument is not an option */
{
/* Argument is a name string. Determine which one. */
switch (name_count)
{
case 0:
input_name = argv[iarg];
break;
case 1:
base_name = argv[iarg];
break;
default:
usage_error ();
break;
}
++name_count;
} /* End if this argument is an option */
} /* End loop over command line arguments */
/* Open the input file */
if (strcmp (input_name, "-") == 0)
{
# if (defined (__MSDOS__) || defined (WIN32))
if (setmode (0, O_BINARY) == -1)
{
perror ("dsplit: setmode");
exit (1);
}
# endif
}
else
{
if ((input_handle = fopen (input_name, READ_OPTIONS)) == NULL)
{
(void)fprintf (stderr, "Could not open file \"%s\" for input\n",
input_name);
exit (1);
}
}
}
#ifdef __STDC__
static int write_one (int count)
#else
static int write_one (count)
int count;
#endif
{
char output_name[FILENAME_MAX];
int bytes_written;
unsigned long total_written;
FILE* output_handle;
/* Read the first buffer full now, just to see if any data is left */
static char buff[1024];
int to_read = MIN (sizeof(buff), output_size);
int bytes_read = fread (buff, 1, to_read, input_handle);
if (bytes_read <= 0)
return 0;
/* Open file for output */
sprintf (output_name, "%s.%03d", base_name, count);
output_handle = fopen (output_name, WRITE_OPTIONS);
if (output_handle == NULL)
{
(void)fprintf (stderr,
"Could not open file \"%s\" for output\n", output_name);
exit (1);
}
/* Write the first output buffer */
bytes_written = fwrite (buff, 1, bytes_read, output_handle);
if (bytes_written != bytes_read)
{
(void)fprintf (stderr, "Error writing to file \"%s\"\n", output_name);
exit (1);
}
total_written = bytes_written;
/* Write output file */
while (total_written < output_size)
{
to_read = MIN (sizeof(buff), output_size-total_written);
bytes_read = fread (buff, 1, to_read, input_handle);
if (bytes_read <= 0)
break;
bytes_written = fwrite (buff, 1, bytes_read, output_handle);
if (bytes_written != bytes_read)
{
(void)fprintf (stderr, "Error writing to file \"%s\"\n", output_name);
exit (1);
}
total_written += bytes_written;
}
/* Close the output file, it is complete */
if (fclose (output_handle) != 0)
{
(void)fprintf (stderr,
"Could not close file \"%s\" for output\n", output_name);
exit (1);
}
/* Indicate whether more data remains to be transferred */
return (bytes_read == to_read);
}
#ifdef __STDC__
static void ToLower (char* string)
#else
static void ToLower (string)
char* string;
#endif
{
while (*string != '\0')
tolower (*string++);
}
#ifdef __STDC__
static void usage_error (void)
#else
static void usage_error ()
#endif
{
(void)fprintf (stderr,
"Usage: dsplit [-size nnn] [input_file [output_base]]\n");
exit (1);
}