home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.2 / util-lin / util-linux-2.2 / misc-utils / dsplit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-22  |  6.3 KB  |  272 lines

  1. #ifdef lint
  2.    static char RCSid[] = "dsplit.c,v 1.1.1.1 1995/02/22 19:09:14";
  3. #endif
  4. /*
  5.    Program dsplit:  Splits a large  file into pieces.
  6.  
  7.    Usage:
  8.         dsplit [-size nnn] [input_file [output_base]]
  9.    Size        is size of each output file, in bytes.  The default is 1457000,
  10.            enough to fill a "1.44MB" diskette, save 152 bytes.
  11.    input_file  is the name of the file to split up.  A dash (-) indicates 
  12.                   standard input.  Defaults to standard input.
  13.    output_base is the name of the output files to be written, minus the
  14.                   extension.  Dsplit adds suffixes 000, 001, ...
  15.                   The default base name is dsplit.
  16. */
  17. #include <ctype.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #if (defined (__MSDOS__) || defined (WIN32))
  22. #include <io.h>
  23. #include <fcntl.h>
  24. #endif /* __MSDOS__ or WIN32 */
  25. #ifndef FILENAME_MAX
  26. #define FILENAME_MAX 1024
  27. #endif
  28.  
  29. #define DEFAULT_NAME "dsplit"
  30. #define DEFAULT_SIZE 1457000L
  31. #if (defined (__MSDOS__) || defined (WIN32))
  32. #   define READ_OPTIONS  "rb"
  33. #   define WRITE_OPTIONS "wb"
  34. #else
  35. #   define READ_OPTIONS  "r"
  36. #   define WRITE_OPTIONS "w"
  37. #endif /* __MSDOS__ or WIN32 */
  38.  
  39. #ifndef MIN
  40. #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
  41. #endif
  42.  
  43. static unsigned long output_size = DEFAULT_SIZE;
  44. static char* base_name = DEFAULT_NAME;
  45. static FILE* input_handle;
  46. static char* input_name = "-";
  47.  
  48. #ifdef __STDC__
  49. static void init (int argc, char* argv[]);
  50. static int write_one (int count);
  51. static void ToLower (char* string);
  52. static void usage_error (void);
  53. #else /* not __STDC__ */
  54. static void init (/* int argc, char* argv[] */);
  55. static int write_one (/* int count */);
  56. static void ToLower (/* char* string */);
  57. static void usage_error (/* void */);
  58. #endif /* __STDC__ */
  59.  
  60.  
  61.  
  62. #ifdef __STDC__
  63. int main (int argc, char* argv[])
  64. #else
  65. int main (argc, argv)
  66. int argc;
  67. char* argv[];
  68. #endif
  69. {
  70.    int count;
  71.  
  72.    /* Process command line arguments, open input file. */
  73.    init (argc, argv);
  74.  
  75.    /* Write the output files */
  76.    for (count = 0 ; write_one (count) ; ++count)
  77.       ;
  78.  
  79.    /* Close input file (a matter of style) */
  80.    if (fclose (input_handle) != 0)
  81.    {
  82.       (void)fprintf (stderr, "Could not close file \"%s\" for input\n",
  83.      input_name);
  84.       return 1;
  85.    }
  86.  
  87.    /* Normal successful conclusion */
  88.    return 0;
  89. }
  90.  
  91.  
  92.  
  93. #ifdef __STDC__
  94. static void init (int argc, char* argv[])
  95. #else
  96. static void init (argc, argv)
  97. int argc;
  98. char* argv[];
  99. #endif
  100. {
  101.    int iarg;
  102.    int name_count;
  103.  
  104.    /* Initialize the input file handle to standard input.  IBM's Toolset++
  105.    won't let me do this statically, unfortunately. */
  106.    input_handle = stdin;
  107.  
  108.    /* Initialize for following loop */
  109.    name_count = 0;
  110.  
  111.    /* Loop over command line arguments */
  112.    for (iarg = 1 ; iarg < argc ; ++iarg)
  113.    {
  114.       /* Point to argument,for convenience */
  115.       char* arg = argv[iarg];
  116.  
  117.       /* If this argument is an option */
  118.       if (arg[0] == '-' && arg[1] != '\0')
  119.       {
  120.          /* Process option if recognized */
  121.          ToLower (arg+1);
  122.          if (strcmp (arg+1, "size") != 0)
  123.             usage_error ();
  124.      ++iarg;
  125.      if (iarg >= argc)
  126.         usage_error ();
  127.      arg = argv[iarg];
  128.      if (sscanf (arg, "%ld", &output_size) != 1)
  129.      {
  130.         (void)fprintf (stderr, "Illegal numeric expression \"%s\"\n", arg);
  131.         exit (1);
  132.      }
  133.       } 
  134.       else /* argument is not an option */
  135.       {
  136.          /* Argument is a name string.  Determine which one. */
  137.          switch (name_count)
  138.          {
  139.          case 0:
  140.             input_name = argv[iarg];
  141.             break;
  142.      case 1:
  143.             base_name = argv[iarg];
  144.         break;
  145.      default:
  146.         usage_error ();
  147.         break;
  148.          }
  149.          ++name_count;
  150.  
  151.       } /* End if this argument is an option */
  152.  
  153.    }  /* End loop over command line arguments */
  154.  
  155.    /* Open the input file */
  156.    if (strcmp (input_name, "-") == 0)
  157.    {
  158. #  if (defined (__MSDOS__) || defined (WIN32))
  159.       if (setmode (0, O_BINARY) == -1)
  160.       {
  161.          perror ("dsplit: setmode");
  162.          exit (1);
  163.       }
  164. #  endif
  165.    }
  166.    else
  167.    {
  168.       if ((input_handle = fopen (input_name, READ_OPTIONS)) == NULL)
  169.       {
  170.      (void)fprintf (stderr, "Could not open file \"%s\" for input\n",
  171.         input_name);
  172.      exit (1);
  173.       }
  174.    }
  175. }
  176.  
  177.  
  178.  
  179. #ifdef __STDC__
  180. static int write_one (int count)
  181. #else
  182. static int write_one (count)
  183. int count;
  184. #endif
  185. {
  186.    char output_name[FILENAME_MAX];
  187.    int bytes_written;
  188.    unsigned long total_written;
  189.    FILE* output_handle;
  190.  
  191.    /* Read the first buffer full now, just to see if any data is left */
  192.    static char buff[1024];
  193.    int to_read = MIN (sizeof(buff), output_size);
  194.    int bytes_read = fread (buff, 1, to_read, input_handle);
  195.    if (bytes_read <= 0)
  196.       return 0;
  197.  
  198.    /* Open file for output */
  199.    sprintf (output_name, "%s.%03d", base_name, count);
  200.    output_handle = fopen (output_name, WRITE_OPTIONS);
  201.    if (output_handle == NULL)
  202.    {
  203.       (void)fprintf (stderr,
  204.          "Could not open file \"%s\" for output\n", output_name);
  205.       exit (1);
  206.    }
  207.  
  208.    /* Write the first output buffer */
  209.    bytes_written = fwrite (buff, 1, bytes_read, output_handle);
  210.    if (bytes_written != bytes_read)
  211.    {
  212.       (void)fprintf (stderr, "Error writing to file \"%s\"\n", output_name);
  213.       exit (1);
  214.    }
  215.    total_written = bytes_written;
  216.  
  217.    /* Write output file */
  218.    while (total_written < output_size)
  219.    {
  220.       to_read = MIN (sizeof(buff), output_size-total_written);
  221.       bytes_read = fread (buff, 1, to_read, input_handle);
  222.       if (bytes_read <= 0)
  223.          break;
  224.       bytes_written = fwrite (buff, 1, bytes_read, output_handle);
  225.       if (bytes_written != bytes_read)
  226.       {
  227.          (void)fprintf (stderr, "Error writing to file \"%s\"\n", output_name);
  228.          exit (1);
  229.       }
  230.       total_written += bytes_written;
  231.    }
  232.  
  233.    /* Close the output file, it is complete */
  234.    if (fclose (output_handle) != 0)
  235.    {
  236.       (void)fprintf (stderr,
  237.          "Could not close file \"%s\" for output\n", output_name);
  238.       exit (1);
  239.    }
  240.  
  241.    /* Indicate whether more data remains to be transferred */
  242.    return (bytes_read == to_read);
  243. }
  244.  
  245.  
  246.  
  247. #ifdef __STDC__
  248. static void ToLower (char* string)
  249. #else
  250. static void ToLower (string)
  251. char* string;
  252. #endif
  253. {
  254.    
  255.    while (*string != '\0')
  256.       tolower (*string++);
  257. }
  258.  
  259.  
  260.  
  261. #ifdef __STDC__
  262. static void usage_error (void)
  263. #else
  264. static void usage_error ()
  265. #endif
  266. {
  267.    (void)fprintf (stderr, 
  268.       "Usage: dsplit [-size nnn] [input_file [output_base]]\n");
  269.    exit (1);
  270. }
  271.  
  272.