home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************/
- /* */
- /* Splitf.c */
- /* Part of Splitf and Joinf distribution */
- /* version 1.13, © 1993-1995 Adam Hamilton */
- /* See the README file for copyright information */
- /* */
- /********************************************************************************/
-
-
- /*********************************/
- /* Include required header files */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "config.h"
-
-
- /**********************************/
- /* Program macros and definitions */
-
- #ifndef Bool
- # define Bool char
- #endif
-
- #define False 0
- #define True !False
- #define MIN(a, b) (a < b ? a : b)
- #define MAX(a, b) (a > b ? a : b)
-
- #ifndef LEAFNAME_MAX
- # define LEAFNAME_MAX FILENAME_MAX
- #endif
-
-
-
- /********************************************************************************/
- /* */
- /* Function : usage */
- /* Description : Displays program usage to standard error, and exits. */
- /* Arguments : progname - pointer to character string containing the program */
- /* name. */
- /* Returns : None. */
- /* */
- /********************************************************************************/
-
-
- void usage (char *progname)
- {
- fprintf (stderr, "File splitter. Version 1.13 - 4th Feburary 1995 by A.Hamilton\n\n");
- fprintf (stderr, "Usage : %s [options] <filename>\n\n", progname);
- fprintf (stderr, "Options (can be abbreviated) :\n");
- fprintf (stderr, " -filesize [filesize in K] default = 1423\n");
- #ifndef PC
- fprintf (stderr, " -buffersize [buffersize in K] default = 32\n");
- #endif
- fprintf (stderr, " -path [new path]\n");
- fprintf (stderr, " -interactive\n");
-
- exit (EXIT_FAILURE);
- }
-
-
-
- /********************************************************************************/
- /* */
- /* Function : examine_filename */
- /* Description : Splits filename into component parts. */
- /* Arguments : original_name - character array, filename to be examined. */
- /* name - pointer to a character array in which to store */
- /* file leafname (excluding extention). */
- /* ext - pointer to a character array in which to store */
- /* the source files extention (if any). */
- /* Returns : If the source file has an extention, then return ".spt", */
- /* otherwise return "". */
- /* */
- /********************************************************************************/
-
-
- char *examine_filename (char original_name[], char *name, char *ext)
- {
- char main_name[256]; /* Temporary store for leafname. */
- char *original; /* Pointer to start of leafname. */
- char *pointer; /* Pointer to any ':' characters found. */
- register int i = -1, n; /* Pointer & counter. */
-
-
- if (COLON) /* If our system uses ':' in */
- pointer = strrchr (original_name, ':'); /* the file path, then remember */
- else /* where it is. */
- pointer = NULL;
-
- original = strrchr (original_name, SEPARATOR_SEARCH); /* Find the address where the */
- if ((original = MAX (original, pointer)) == NULL) /* leafname starts. */
- original = original_name;
- else {
- original++;
- }
-
- do {
- i++;
- main_name[i] = original[i]; /* Get files leafname */
- } while (main_name[i] != '.' && main_name[i] != '\0'); /* (excluding any extention). */
-
- for (n = 0; (ext[n] = original[i]) != '\0'; n++, i++) ; /* Now copy any extention. */
-
- if (main_name[i - n] == '\0') { /* If the file doesn't have an */
- strcpy (name, main_name); /* extention, copy the leafname */
- return (""); /* and return an empty string. */
- }
- main_name[i - n] = '\0'; /* Otherwise, terminate the */
- strcpy (name, main_name); /* leafname, copy it, and */
- return (".spt"); /* the output extention to use. */
- }
-
-
-
- /********************************************************************************/
- /* */
- /* Function : numtostr */
- /* Description : Converts a number into a 2 didget character string. */
- /* Arguments : number - number to be converted. */
- /* name - pointer to a character array to store the number. */
- /* Returns : None. */
- /* */
- /********************************************************************************/
-
-
- void numtostr (short number, char *name)
- {
- name[0] = (short) (number / 10) + '0';
- name[1] = (number % 10) + '0';
- name[2] = '\0';
- }
-
-
-
- /********************************************************************************/
- /* */
- /* Function : main */
- /* Description : Main control function. */
- /* Arguments : Command line parameters. */
- /* Returns : Exit status. */
- /* */
- /********************************************************************************/
-
-
- int main (int argc, char **argv)
- {
- char source_filename[256]; /* Source filename. */
- char out_filename[256]; /* Output leafname. */
- char out_path[256]; /* Output path. */
- char file_ext[32]; /* Output extention. */
- char out_name[256]; /* Full output filename. */
- char header[50]; /* Output file header. */
- char fnum[3]; /* Output part number. */
- char *progname; /* Program name. */
- char string[256]; /* Input string. */
- char type[5]; /* Filetype (Acorn systems only). */
- char interactive = 0; /* Interactive status flag. */
- char orig_ext[20]; /* Original filename extention. */
-
- short file_number = 0; /* Current part number. */
- long disk_size = 1423 * 1024; /* Output part size (default 1423K). */
- long read_size = 32 * 1024; /* Buffer size (default 32K). */
- long data_size;
- long out_position; /* Position within output file. */
- long in_position; /* Position within input file. */
- long bytes_read; /* Number of bytes read. */
- long bytes_written; /* Number of bytes written. */
- long file_length; /* Length of source file. */
- long *buffer; /* Pointer to buffer. */
- int args; /* Number of command line arguments. */
- int i; /* Counter. */
- FILE *source_file; /* Source file ID. */
- FILE *out_file; /* Output file ID. */
-
-
- #ifdef ACORN
- _kernel_swi_regs regs;
- _kernel_oserror *err;
- #endif
-
- progname = *argv; /* Get the program name. */
-
- out_path[0] = '\0'; /* Set path to CWD. */
- source_filename[0] = '\0'; /* Clear source filename. */
- strcpy (type, "0"); /* No filetype set. */
-
- args = argc - 1; /* Initialise count of arguments. */
- if (!args) usage (progname); /* If no arguments supplied, show usage.*/
-
- while (args--) {
- argv++; /* Look at next argument. */
-
- if (!strncmp ("-filesize", *argv, MAX (2, strlen (*argv)))) { /* -filesize */
- if (!args) {
- fprintf (stderr, "File size required.\n\n");
- usage (progname);
- }
- disk_size = (long) atoi (*++argv) * 1024; /* Read file size. */
- args--;
- }
-
- #ifndef PC
- else if (!strncmp ("-buffersize", *argv, MAX (2, strlen (*argv)))) { /* -buffersize */
- if (!args) {
- fprintf (stderr, "Buffer size required\n\n");
- usage (progname);
- }
- read_size = (long) atoi (*++argv) * 1024; /* Read buffer size. */
- args--;
- }
- #endif
-
- else if (!strncmp ("-path", *argv, MAX (2, strlen (*argv)))) { /* -path */
- if (!args) {
- fprintf (stderr, "Path required\n\n");
- usage (progname);
- }
- sprintf (out_path, "%s%c", *++argv, FILE_SEPARATOR); /* Read new output path.*/
- args--;
- }
-
- else if (!strncmp ("-interactive", *argv, MAX (2, strlen (*argv)))) /* -interactive */
- interactive = 1;
-
- else {
- strcpy (source_filename, *argv); /* Read source filename.*/
- if (args) usage (progname);
- }
- }
-
- if (source_filename[0] == NULL) {
- fprintf (stderr, "Source filename required\n\n");
- usage (progname);
- }
-
- /* Get file detail from source filename.*/
- strcpy (file_ext, examine_filename (source_filename, out_filename, orig_ext));
- out_filename[MIN (LEAFNAME_MAX, 256) - 2] = '\0'; /* and reduce if necessary. */
-
- source_file = fopen (source_filename, "rb"); /* Open read binary source file. */
- if (source_file == NULL) { /* Report if error, and stop. */
- fprintf (stderr, "Fatal error opening %s for input.\n", source_filename);
- exit (EXIT_FAILURE);
- }
-
- printf ("Using file size of %ld bytes.\n", disk_size);
- fseek (source_file, 0L, SEEK_END); /* Set file pointer to end of file, */
- file_length = ftell (source_file); /* get file length */
- fseek (source_file, 0L, SEEK_SET); /* and reset pointer to the start. */
- if (file_length <= disk_size) {
- fprintf (stderr, "No need to split file.\n");
- fclose (source_file);
- exit (EXIT_SUCCESS);
- }
-
- buffer = (long *) malloc ((size_t) read_size); /* Allocate memory for a buffer. */
- if (buffer == NULL) {
- fprintf (stderr, "Fatal error, unable to allocate memory block of %ld bytes\n", read_size);
- exit (EXIT_FAILURE);
- }
-
- printf ("Using buffer size of %ld bytes.\n", read_size);
-
- #ifdef ACORN
- regs.r[0] = 5; /* Perform an OS_File to read file data. */
- regs.r[1] = (int) source_filename;
- err = _kernel_swi (SWI_OS_File, ®s, ®s);
- if (err != NULL || (regs.r[0] != 1 && regs.r[0] != 3)) {
- fprintf (stderr, "Fatal error, %s is not a file\n", source_filename);
- exit (EXIT_FAILURE);
- }
- sprintf (type, "t%x", (0xFFF & regs.r[2] >> 8));
- #endif
-
- sprintf (header, "Split:%s%s=%d=%s|", out_filename, orig_ext, /* Create the output */
- (int) (file_length / (disk_size - 7 - strlen (out_filename) - /* file header. */
- strlen (orig_ext)) + 1), type);
-
- file_number = 0; /* Initialise file number counter. */
- in_position = 0; /* Initialise source file position pointer. */
-
- while (file_length - in_position > 0) { /* If any data left to transfer */
- file_number++; /* increment file number counter. */
- numtostr (file_number, fnum); /* Convert to a number. */
-
- while (interactive == 1) { /* If interactive option selected, ask for */
- printf ("Enter path for %s%s%s (Return for %s) :\n", /* destination of output file. */
- out_filename, fnum, file_ext,
- out_path[0] == '\0' ? "current directory" : out_path);
-
- gets (string); /* Get output destination. */
- if (strchr (string, ' ') != NULL) {
- printf ("Invalid path name.\n");
- continue;
- }
- if (string[0] != '\0') { /* If nothing entered, then use the default. */
- strcpy (out_path, string);
- i = strlen (out_path);
- if (out_path[i - 1] != FILE_SEPARATOR)
- if (!COLON || (COLON && out_path[i - 1] != ':')) {
- out_path[i] = FILE_SEPARATOR;
- out_path[i + 1] = '\0';
- }
-
- }
- interactive = interactive | 2; /* Set flag to say data has been accepted. */
- }
-
- interactive = interactive & 1; /* Mask off unrequired data. */
-
- /* Create the full output filename. */
- sprintf (out_name, "%s%s%s%s", out_path, out_filename, fnum, file_ext);
-
- if (file_number > 1) { /* If it's not the first part, */
- numtostr (file_number, fnum); /* create a smaller header. */
- sprintf (header, "Sp:%s%s=%s|", out_filename, orig_ext, fnum);
- }
-
- #ifdef ACORN
- regs.r[0] = 7; /* Create the file with SWI */
- regs.r[1] = (int) out_name; /* OS_File 7 */
- regs.r[2] = 0xdeaddead;
- regs.r[3] = 0xdeaddead;
- regs.r[4] = 0;
- regs.r[5] = (int) MIN (file_length - in_position + strlen (header), disk_size);
- if ((err = _kernel_swi (SWI_OS_File, ®s, ®s)) != NULL) {
- fprintf (stderr, "Fatal error opening %s for output:\n-- %s\n", out_name, err->errmess);
- exit (EXIT_FAILURE);
- }
- #endif
-
- out_file = fopen (out_name, "wb"); /* Open output file. */
- if (out_file == NULL) { /* Report if error, and stop. */
- fprintf (stderr, "Fatal error opening %s for output.\n", out_name);
- exit (1);
- }
-
- out_position = 0; /* Initialise output file position pointer. */
- printf ("Writing data to %s\n", out_name);
-
- fprintf (out_file, header); /* Write the header information, */
- out_position = (long) strlen (header); /* and update the output file pointer. */
-
- if (disk_size > file_length - in_position + out_position) /* Set the size of the file we */
- disk_size = file_length - in_position + out_position; /* want to write. */
-
- while (disk_size - out_position > 0) { /* While there's any data left */
- if (disk_size - out_position < read_size) /* to transfer */
- data_size = disk_size - out_position;
- else
- data_size = read_size;
-
- bytes_read = fread (buffer, 1, (size_t) data_size, source_file); /* read */
- bytes_written = fwrite (buffer, 1, (size_t) bytes_read, out_file); /* and write. */
-
- /* Check to see that all the data has been transfered ok. */
- if (bytes_written < data_size && bytes_written < file_length - out_position) {
- fprintf (stderr, "Fatal error while writing %s\n", out_name);
- exit (EXIT_FAILURE); /* If unsucessfull, stop. */
- }
- in_position += bytes_read; /* Update the file position */
- out_position += bytes_written; /* pointers. */
- }
-
- fclose (out_file); /* Close output file. */
-
- #ifdef ACORN
- regs.r[0] = 18; /* Set the filetype with SWI */
- regs.r[1] = (int) out_name; /* OS_File 18 */
- regs.r[2] = SPLIT_FILETYPE;
- err = _kernel_swi (SWI_OS_File, ®s, ®s);
- #endif
-
- }
-
- fclose (source_file); /* Close source file */
- free (buffer); /* and free buffer. */
-
- fprintf (stderr, "%ld bytes written to %d %s.\n", in_position +
- (int) (file_number * (7 + strlen (source_filename))) + 4 + strlen (type),
- file_number, (file_number == 1) ? "file" : "files"); /* Report status. */
- fprintf (stderr, "Use : joinf %s01%s \nto restore file.\n",
- out_filename, (file_ext[0] == '\0') ? "" : ".spt");
-
- exit (EXIT_SUCCESS); /* and finish. */
- }
-