home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / utilities / split / Support / Source / Joinf_c < prev    next >
Encoding:
Text File  |  1994-04-24  |  9.6 KB  |  330 lines

  1. /* Joinf.c                                       */
  2. /* Part of splitf and joinf distribution         */
  3. /* version 1.12, © 1993,1994 Adam Hamilton       */
  4. /* See the README file for copyright information */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10.  
  11. #ifdef ACORN
  12. #include "os.h"
  13. #endif
  14.  
  15. #define TITLE "File joiner.  Version 1.12 - 30 March 1994 by A.Hamilton\n\n"
  16. #define Bool char
  17. #define False 0
  18. #define True 1
  19. #define MAX(a, b) (a > b ? a : b)
  20.  
  21. void usage (char *progname)
  22. {
  23.   fprintf (stderr, TITLE);
  24.   fprintf (stderr, "Usage : %s [options] <filename>\n\n", progname);
  25.   fprintf (stderr, "Options (can be abbreviated) :\n");
  26. #ifndef PC
  27.   fprintf (stderr, "    -buffersize   [buffersize in K]        default = 32\n");
  28. #endif
  29.   fprintf (stderr, "    -filename     [new filename]\n");
  30.   fprintf (stderr, "    -interactive\n");
  31.   fprintf (stderr, "    -info\n");
  32.   exit (1);
  33. }
  34.  
  35. char *examine_filename (char original_name[], char *name, char *path)
  36. {
  37.   char main_name[256], *original, ext[20], *pointer; 
  38.   int i = -1,n;
  39.  
  40.   if (COLON)
  41.     pointer = strrchr (original_name, ':');
  42.   else
  43.     pointer = NULL;
  44.  
  45.   original = strrchr (original_name, SEPARATOR_SEARCH);
  46.   if ((original = MAX (original, pointer)) == NULL)
  47.     original = original_name;
  48.   else {
  49.     original++;
  50.     strncpy (path, original_name, original - original_name);
  51.     path[original - original_name] = '\0';
  52.   }
  53.   
  54.   do {
  55.     i++;
  56.     main_name[i] = original[i];                         /* get name */
  57.   } while (main_name[i] != '.' && main_name[i] != '\0');
  58.   if (main_name[i] == '\0') {
  59.     main_name[i-2] = '\0';
  60.     strcpy (name, main_name);
  61.     return ("");
  62.   }
  63.   main_name[i-2] = '\0';
  64.   strcpy (name, main_name);
  65.  
  66.   for (n = 0; (ext[n] = original[i]) != '\0'; n++, i++) ;
  67.   return (ext);
  68. }
  69.  
  70. void numtostr (short number, char *name)
  71. {
  72.   name[0] = (short) (number / 10) + '0';
  73.   name[1] = (number % 10) + '0';
  74.   name[2] = '\0';
  75. }
  76.  
  77. int main (int argc, char *argv[])
  78. {
  79.   char source_filename[256], out_filename[256], file_ext[20], type[5];
  80.   char out_name[256], source_name[256], header[50], fnum[3], in_path[256];
  81.   char check_name[256], *progname, interactive = 0, command[256];
  82.   static char splith1[]="Split:", splith2[]="Sp:";
  83.   short file_number = 0, check_number;
  84.   long read_size=32*1024, out_position, in_position, bytes_read, bytes_written;
  85.   long file_length, *buffer;
  86.   int total_number, i, n, args;
  87.   Bool info = False;
  88.   FILE *source_file, *out_file;
  89.  
  90. #ifdef ACORN
  91.   os_filestr filedata;
  92. #endif
  93.  
  94.   progname = *argv;
  95.   in_path[0] = '\0';
  96.   out_filename[0] = '\0';
  97.   source_filename[0] = '\0';
  98.   args = argc - 1 ;
  99.   if (!args) usage (progname);
  100.   while (args--) {
  101.     argv++;
  102.     if (!strncmp ("-filename", *argv, MAX (2, strlen (*argv)))) {
  103.       if (!args) {
  104.         fprintf (stderr, "Filename required\n\n");
  105.         usage (progname);
  106.       }
  107.       strcpy (out_filename, *++argv);  /* output filename */
  108.       args--;
  109.     }
  110. #ifndef PC
  111.     else if (!strncmp ("-buffersize", *argv, MAX (2, strlen (*argv)))) {
  112.       if (!args) {
  113.     fprintf (stderr, "Buffer size required\n\n");
  114.     usage (progname);
  115.       }
  116.       read_size = (long) atoi (*++argv) * 1024;   /* buffer size */
  117.       args--;
  118.     }
  119. #endif
  120.     else if (!strncmp ("-interactive", *argv, MAX (2, strlen (*argv))))
  121.       interactive = 1;
  122.     else if (!strncmp ("-info", *argv, MAX (3, strlen (*argv))))
  123.       info = True;
  124.     else {
  125.       strcpy (source_filename, *argv);              /* source file */
  126.       if (args) usage (progname);
  127.     }
  128.   }
  129.   if (source_filename[0] == NULL) {
  130.     fprintf (stderr, "Source filename required\n\n");
  131.     usage (progname);
  132.   }
  133.   strcpy (file_ext, examine_filename (source_filename, source_name, in_path));
  134.  
  135.   source_file = fopen (source_filename, "rb");     /* open read binary file */
  136.   if (source_file == NULL) {                    /* report if error, and stop. */
  137.     fprintf (stderr, "Fatal error opening %s for input.\n", source_filename);
  138.     exit (1);
  139.   }
  140.   i=0;
  141.   while ((header[i++] = fgetc (source_file)) != '|' && i<300) ;
  142.   for (i = 0; i < 6; i++) if (header[i] != splith1[i]) {
  143.     fprintf (stderr,"Fatal error, no split header in file %s\n",
  144.         source_filename);
  145.     fclose (source_file);
  146.     exit (1);
  147.   }
  148.  
  149.   n=0;
  150. #ifdef ACORN
  151.   while (header[i] != '=') {
  152.     out_name[n++] = (header[i] == '.' ? '/' : header[i]);
  153.     i++;
  154.   }
  155.   n++;
  156.   i++;
  157. #else
  158.   while ((out_name[n++] = header[i++]) != '=') ;
  159. #endif
  160.  
  161.   out_name[--n] = '\0';  
  162.   if (out_filename[0] == '\0') strcpy (out_filename, out_name);
  163.   n = 0;
  164.   while ((fnum[n++] = header[i++]) != '=') ;
  165.   fnum[--n] = '\0';
  166.   total_number = atoi (fnum);
  167.   n = 0;
  168.   while ((type[n++] = header[i++]) != '|') ;
  169.   type[--n] = '\0';
  170.  
  171.   if (info) {
  172.     printf (TITLE);
  173.     printf ("Information :\n\n");
  174.     printf ("    Output filename is %s", out_filename);
  175.  
  176. #ifdef ACORN
  177.     if (type[0] == 't') {
  178.       printf (", filetype ");
  179.       for (n = 1; type[n] != '\0'; n++)
  180.         printf ("%c", toupper(type[n]));
  181.     }
  182. #endif
  183.  
  184.     printf ("\n");
  185.     bytes_read = 0;
  186.   }
  187.   else {
  188.  
  189.     buffer = (long *) malloc ((size_t) read_size);  /* allocate memory for    */
  190.     if (buffer == NULL) {                           /* a buffer.*/
  191.       fprintf (stderr,
  192.           "Fatal error, unable to allocate memory block of %ld bytes\n",
  193.           read_size);
  194.       exit (1);
  195.     }
  196.     printf ("Using buffer size of %ld bytes.\n", read_size);
  197.  
  198.     out_file = fopen (out_filename, "wb");       /* open output file */
  199.     if (out_file == NULL) {                      /* report if error, and stop */
  200.       fprintf (stderr, "Fatal error opening %s for output.\n", out_filename);
  201.       exit (1);
  202.     }
  203.   }
  204.  
  205.   out_position = 0;
  206.   for (file_number = 1; file_number <= total_number; file_number++) {
  207.     numtostr (file_number, fnum);
  208.     while (interactive == 1 && file_number > 1) {
  209.       printf ("Enter path for %s%s%s (Return for %s) :\n", source_name,
  210.           fnum, file_ext, in_path[0] == '\0' ? "current directory" : in_path);
  211.       gets (command);
  212.       if (strchr (command, ' ') != NULL) {
  213.         printf ("Invalid path name.\n");
  214.         continue;
  215.       }
  216.       if (command[0] != '\0') {
  217.         strcpy (in_path, command);
  218.         i = strlen (in_path);
  219.         if (in_path[i - 1] != FILE_SEPARATOR)
  220.           if (!COLON || (COLON && in_path[i - 1] != ':')) {
  221.             in_path[i] = FILE_SEPARATOR;
  222.             in_path[i + 1] = '\0';
  223.           }
  224.  
  225.       }
  226.       interactive = interactive | 2;
  227.     }
  228.     interactive = interactive & 1;
  229.     sprintf (source_filename, "%s%s%s%s", in_path, source_name, fnum, file_ext);
  230.  
  231.     if (file_number != 1) {
  232.       source_file = fopen (source_filename, "rb");  /* open read binary file  */
  233.       if (source_file == NULL) {                /* report if error, and stop. */
  234.         fprintf (stderr, "Fatal error opening %s for input.\n",
  235.             source_filename);
  236.         exit (1);
  237.       }
  238.       i = 0;
  239.       while ((header[i++] = fgetc (source_file)) != '|' && i<300) ;
  240.       for (i = 0; i < 3; i++) if (header[i] != splith2[i]) {
  241.         fprintf (stderr,"Fatal error, bad header in file %s\n",
  242.             source_filename);
  243.         fclose (source_file);
  244.         exit (1);
  245.       }
  246.  
  247.       n = 0;
  248. #ifdef ACORN
  249.       while (header[i] != '=') {
  250.         check_name[n++] = (header[i]=='.' ? '/' : header[i]);
  251.         i++;
  252.       }
  253.       n++;
  254.       i++;
  255. #else
  256.       while ((check_name[n++] = header[i++]) != '=') ;
  257. #endif
  258.  
  259.       check_name[--n] = '\0';  
  260.       if (strcmp (out_name, check_name)) {
  261.         fprintf (stderr,"Fatal error, split file %s does not match.\n",
  262.             source_filename);
  263.         fclose (source_file);
  264.         exit (1);
  265.       }
  266.       n = 0;
  267.       while ((fnum[n++] = header[i++]) != '|') ;
  268.       fnum[--n] = '\0';
  269.       check_number = atoi (fnum);
  270.       if (check_number != file_number) {
  271.         fprintf (stderr,"Fatal error, incorrect part.\n");
  272.         fclose (source_file);
  273.         exit (1);
  274.       }
  275.     }
  276.     in_position = (long) i;
  277.  
  278.     fseek (source_file, 0L, SEEK_END);          /* set file pointer to end of */
  279.     file_length = ftell (source_file);          /* file, and get file length. */
  280.     fseek (source_file, in_position, SEEK_SET);    /* reset pointer to start. */
  281.  
  282.     if (info) {
  283.       printf ("    %s...%ld bytes\n", source_filename,
  284.           file_length - in_position);
  285.       bytes_read += file_length - in_position;
  286.     }
  287.     else {
  288.       printf ("Reading data from %s.....%ld bytes\n", source_filename,
  289.           file_length - in_position);
  290.       while (file_length - in_position > 0) {
  291.     bytes_read = fread (buffer, 1, (size_t) read_size, source_file);
  292.     bytes_written = fwrite (buffer, 1, (size_t) bytes_read, out_file);
  293.  
  294.         if (bytes_written < read_size &&
  295.             bytes_written < file_length-in_position) {
  296.           fprintf (stderr, "Fatal error while writing %s\n", out_filename);
  297.           exit (1);                                  /* if unsucessfull, stop */
  298.         }
  299.         in_position += bytes_read;
  300.         out_position += bytes_written;
  301.       }
  302.     }
  303.     fclose (source_file);
  304.     if (!info && (bytes_written < bytes_read)) {    
  305.       fprintf (stderr, "Fatal error while writing %s\n", out_filename);
  306.       exit (1);                                      /* if unsucessfull, stop */
  307.     }
  308.   }
  309.   if (info)
  310.     printf ("\nTotal of %ld bytes contained in %d files.\n", bytes_read,
  311.         total_number);
  312.   else {
  313.     fclose (out_file);                             /* tidy up*/
  314.     free (buffer);
  315.  
  316. #ifdef ACORN
  317.   if (type[0] == 't') {
  318.     filedata.action = 18;
  319.     filedata.name = out_filename;
  320.     sscanf (type, "t%x", &filedata.loadaddr);
  321.     os_file (&filedata);
  322.   }
  323. #endif
  324.  
  325.     fprintf (stderr, "%ld bytes written to file %s\n", out_position,
  326.         out_filename);
  327.   }
  328.   exit (0);                                      /* and finish */
  329. }
  330.