home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / FILE / CHOP1191.ZIP / CHOP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-25  |  17.3 KB  |  519 lines

  1. /* This program splits the input file into smaller files.
  2.  
  3.    USAGE: CHOP FILENAME SIZE [OUTPATH] -SWITCHES
  4.    Version 1.22.  Written by W. J. Kennamer and released into the public domain.
  5.                   Enhanced by Edgar Swank         "           "         "
  6.      Enhancements/Changes:
  7.       1)Performance improvement by reading/writing in large blocks.
  8.       2)Support for non-ASCII files with -b option.
  9.       3)Add optional disk/path for output files.
  10.       4)Add -w option to wait after each output file (except last).
  11.       Note: this source is now for IBM/MS C Compiler.
  12.             Compile with HUGE memory model /AH.
  13.      FILENAME is any valid MS-DOS filename.  Wildcards are not supported.
  14.      Output file names will be FILENAME.1, FILENAME.2, etc.
  15.      Output files are always terminated with a carriage return and
  16.      a <ctrl>Z, UNLESS -b is specified.
  17.      SIZE is the desired file size for each new file.
  18.      OUTPATH is an optional disk/pathname (A: or \path\ or a:\path\)
  19.      to put output files on a different disk and/or directory from input file.
  20.      If using -p with OUTPATH, enter some dummy argument for SIZE.
  21.      SWITCHES must follow the FILENAME,SIZE and OUTPATH parameters,
  22.        and may be entered in any order.  Switches may be combined.
  23.      Valid SWITCHES are:
  24.        -b  binary    ║ do not add cr/lf/^z to output files.
  25.                      ║   forces -s.
  26.        -s  strict    ║ chop file at exact SIZE boundary.
  27.        -w  wait      ║ wait after closing each output file.
  28.                      ║  can change output diskette if separate from input.
  29.        -r  return    ║ chop file at first carriage return
  30.                      ║   following SIZE characters (default).
  31.        -px partition ║ partition file into x equal units.
  32.                      ║   SIZE is ignored (and may be omitted) if
  33.                      ║   you choose this option.
  34.  
  35. File pointer fp1 is the input file.  fp2 is always the output
  36.    file, though its name changes as new output files are
  37.    opened.
  38.  
  39. */
  40.  
  41. #include  <stdio.h>
  42. #include  <ctype.h>
  43. #include  <string.h>
  44. #include  <malloc.h>
  45.  
  46. #define VERSION "1.22"
  47. #define PROGNAME "CHOP"
  48. #define CTRL_Z   0x1a
  49. #define VOID     int
  50. #define CR       0x0d
  51. #define LF       0x0a
  52. #define OFF   0
  53. #define ON   1
  54.  
  55. int binary = OFF;                   /* do not add CR,LF,EOF             */
  56. int wait   = OFF;                   /* Wait after each output file close*/
  57. int count;                          /* no. of digits in size            */
  58. int c;                              /* current character                */
  59. int j;                              /* index                            */
  60. long inpleft;                       /* Bytes input left to read         */
  61. long inplimit;                      /* Bytes input left to read low lim */
  62. long bfsiz;                         /* I/O buffer size                  */
  63. long bread;                         /* Bytes read into buffer           */
  64. long pbread;                        /* Bytes read this partition        */
  65. long bwrit;                         /* Bytes written from buffer        */
  66. long pbwrit;                        /* Bytes written this partition     */
  67.  
  68. long size = 0;                      /* partition value -- file size     */
  69. long byte_count = 0;                /* total bytes in original file     */
  70. long inpfz = 0;                     /* total bytes in original file     */
  71. long out_file_size = 0;             /* total bytes in output file       */
  72.  
  73. char *bfpa[20];                     /* I/O buffer pointer array         */
  74.  
  75. FILE *fp1,*fp2;                     /* fp1=input, fp2=output            */
  76.  
  77.  int bfx;                           /* buffer array index               */
  78.  int num_output_files = 0;          /* no of files successfully created */
  79.  int length;                        /* length of matching string        */
  80.  int normal = ON;                   /* normal CR breaks                 */
  81.  int strict = OFF;                  /* break exactly at boundary        */
  82.  int partition = OFF;               /* strict or normal                 */
  83.  int num_part;                      /* number of partitions             */
  84.  int int_size;                      /* integer for file size            */
  85.  int nmb;                           /* number of 16k blocks IO          */
  86.  unsigned int  w;
  87.  
  88.  char *p;                           /* pointer to switch string         */
  89.  char *period_p;                    /* location of period in filename   */
  90.  char *output_file;                 /* output file name                 */
  91.  char filename[80];                 /* original file name               */
  92.  char fnwork[80];                   /* workarea for file name           */
  93.  
  94.  char outpath[64];                  /* optional output disk/path        */
  95.  char line1[80];                    /* data buffer                      */
  96.  char line2[30];                    /* data buffer                      */
  97.  char *switches;                    /* string to hold switches          */
  98.  
  99.  VOID help();
  100.  VOID close_out();
  101.  VOID block_read();
  102.  VOID block_write();
  103.  VOID copy_to_eol();
  104.  VOID construct_output_filename();
  105.  
  106. main(argc,argv)
  107. int argc;
  108. char *argv[];
  109.    {
  110.  
  111.  
  112.    /* test code to prints args **********
  113.    printf("ARGC=%d\n",argc);
  114.    for (j=0;j<argc ;j++ )
  115.    {
  116.    printf("ARGV[%d]=%s\n",j,argv[j]);
  117.    }
  118.    ***************************************/
  119.    bfsiz=0;
  120.    for (nmb=1;nmb<=20 ;nmb++ )
  121.    {
  122.    bfpa[nmb-1]=malloc(16384);
  123.    if (bfpa[nmb-1]==NULL)
  124.     {
  125.    break;
  126.     }
  127.     else
  128.     {
  129.    bfsiz=(long)nmb*16384;
  130.     }
  131.    } /*for (nmb=1;nmb<=10 ;nmb++ )*/
  132.    nmb--;
  133.    if (nmb==0)
  134.    {
  135.     printf ("Insufficient Memory for I/O Buffer.\n");
  136.     exit(8);
  137.    }
  138.    else
  139.     printf ("%ld (%u*16384) bytes allocated for I/O Buffers.\n",bfsiz,nmb);
  140.  
  141.  
  142.    if( argc > 5 || argc < 3 || strcmp(argv[2],"-?")==0
  143.                             || strcmp(argv[3],"-?")==0
  144.                             || strcmp(argv[4],"-?")==0 )
  145.       {
  146.       help();
  147.       exit(1);
  148.       }
  149.  
  150.    /* see which argument is the switch */
  151.    switches = line2;
  152.    strcpy(switches,"");
  153.    for (j=2;j<argc;j++)
  154.    {
  155.    if( argv[j][0]=='-')
  156.       {
  157.       strcpy(switches,argv[j]);
  158.       break;
  159.       }
  160.     } /*for*/
  161.     if (j>3)
  162.      strcpy(outpath,argv[3]);
  163.     else
  164.      outpath[0]=0;
  165.  
  166.      set_switches();
  167.  
  168.    if( (fp1 = fopen(argv[1],"rb") ) == NULL)
  169.       {
  170.       printf("Cannot open %s for input.\n",argv[1]);
  171.       exit(1);
  172.       }
  173.  
  174.       if( fseek(fp1,0L,2) == -1)            /* position at EOF */
  175.          {
  176.          printf("Error seeking end of input file.\n");
  177.          exit(1);
  178.          }
  179.  
  180.       inpfz = ftell(fp1);                   /* tell EOF  */
  181.       rewind(fp1);                          /* back to beginning of file */
  182.       printf("  Input file size = %ld bytes\n",inpfz);
  183.  
  184.    /* determine file size */
  185.    if(partition == ON)
  186.       {
  187.  
  188.       /* each partition requires 3 extra bytes -- CTRL_Z, newline */
  189.       size = ((inpfz + 3*(long)num_part) / (long)num_part ) + 1 ;
  190.  
  191.       printf("   Partition size = %ld bytes\n",size);
  192.       printf("No. of partitions = %ld\n\n",(long)num_part);
  193.  
  194.       }
  195.    else                                 /* partition is not ON */
  196.       {                                 /* read SIZE from command line */
  197.  
  198.       count = sscanf(argv[2],"%D",&size); /* convert string to long integer */
  199.       if(count == 0)
  200.          {
  201.          printf("Invalid size\n");
  202.          exit(1);
  203.          }
  204.       } /*else*/
  205.       if (size>inpfz)
  206.         {
  207.         printf("Requested Size > Input File Size.\n");
  208.         exit(1);
  209.         }
  210.  
  211.    strcpy(filename,argv[1]);
  212.  
  213.    period_p = strchr(filename,'.');         /* locate the period, if any */
  214.  
  215.    if( period_p != NULL )
  216.       *period_p = '\0';                     /* chop off the period  */
  217.  
  218.    if (outpath[0]!=0)                       /* if outpath specified */
  219.      construct_output_filename();
  220.  
  221.    inpleft=inpfz;
  222.    if (binary==ON)
  223.     inplimit=0;
  224.    else
  225.     inplimit=3;
  226.    bread=0;pbread=0;w=16384;
  227.    bwrit=0;pbwrit=0;bfx=0;
  228.    while (inpleft>inplimit)
  229.     {
  230.       block_read();
  231.  
  232.       if (pbwrit==0)
  233.       {
  234.       (num_output_files)++;
  235.       if(num_output_files > 127)
  236.          {
  237.          printf("Too many files--%d.\nExiting program\n.",num_output_files);
  238.          exit(1);
  239.          }
  240.  
  241.       output_file = line1;                /* initialize output_file pointer */
  242.  
  243.       /* create the next filename */
  244.       sprintf(output_file,"%s.%-d",filename,num_output_files);
  245.  
  246.       fp2 = fopen(output_file,"wb");
  247.       if (fp2 == NULL)
  248.          {
  249.          printf("Cannot open %s for output\n",output_file);
  250.          printf("Exiting the program.\n");
  251.          printf("%d files created.\n",(num_output_files) - 1 );
  252.          printf("Actual original filesize = %u bytes.\n",byte_count);
  253.          exit(1);
  254.          }
  255.        } /*pbwrit==0 */
  256.  
  257.       block_write();
  258.  
  259.          if( inpleft == 0 )
  260.             {
  261.             close_out(fp2,output_file);
  262.             exit(0);
  263.             }
  264.       if (pbwrit>=size)
  265.        {
  266.       if( normal == ON )
  267.        copy_to_eol();
  268.  
  269.         close_out(fp2,output_file);
  270.         pbwrit=0;pbread=0;
  271.        } /*if (pbwrit>=size)*/
  272.    bfx=0;bread=0;w=16384;
  273.    bwrit=0;
  274.       } /*while (inpleft>inplimit)*/
  275.    while(1)
  276.       {
  277.       c = getc(fp1);
  278.       if( c == EOF )
  279.          {
  280.          close_out(fp2,output_file);
  281.          exit(0);
  282.          }
  283.      inpleft--;
  284.      if (binary==ON || (c != CR && c !=LF && c != CTRL_Z))
  285.      {
  286.       putc(c,fp2);
  287.      }
  288.     } /*while(1)*/
  289.    } /*main(argc,argv)*/
  290. /***************************************************************************/
  291.  VOID set_switches()
  292.   {
  293.    for( p = switches ; (p - switches) < strlen(switches)  ; p++ )
  294.       {
  295.       if( *p == 's' )
  296.          {
  297.          strict = ON;
  298.          normal = OFF;
  299.          }
  300.       else if( *p == 'b' )
  301.          {
  302.          strict = ON;
  303.          normal = OFF;
  304.          binary = ON;
  305.          }
  306.       else if ( *p == 'r' || *p == 'n')
  307.          {
  308.          normal = ON;
  309.          strict = OFF;
  310.          binary = OFF;
  311.          }
  312.       else if ( *p == 'p')
  313.          {
  314.          partition = ON;
  315.          if(sscanf((p+1),"%d",&num_part) == 0 || num_part<=0)
  316.             {
  317.             printf("Invalid number of partitions.\n");
  318.             exit(1);
  319.             }
  320.          }
  321.       else if ( *p == 'w')
  322.          {
  323.          wait = ON;
  324.          }
  325.       } /*for( p = switches ...*/
  326.   } /*VOID set_switches()*/
  327. /***************************************************************************/
  328.  VOID construct_output_filename()
  329.     {
  330.      p=outpath+strlen(outpath)-1;           /* ensure outpath properly terminated*/
  331.      if (*p!='\\' && strchr(outpath,'\\')!=0)
  332.       {
  333.        *(p+1)='\\';
  334.        *(p+2)=0;
  335.       }
  336.  
  337.      if (filename[1]==':')                  /* strip disk/path from input filename*/
  338.       {
  339.       strcpy(fnwork,(filename+2));
  340.       strcpy(filename,fnwork);
  341.       }
  342.     for (p=filename+strlen(filename);p>=filename;p--)
  343.      {
  344.       if (*p=='\\')
  345.        {
  346.        strcpy(fnwork,p+1);
  347.        strcpy(filename,fnwork);
  348.        break;
  349.        } /*if*/
  350.      } /* for (p=filename+strlen(filename),p>=filename,p--)*/
  351.      if (strlen(outpath)+strlen(filename)<75)
  352.      {
  353.      strcpy(fnwork,outpath);
  354.      strcat(fnwork,filename);
  355.      strcpy(filename,fnwork);
  356.      }
  357.      else
  358.       {
  359.       printf("Syntax Error generating output filename\n");
  360.       exit(8);
  361.       }
  362.     } /*VOID construct_output_filename()*/
  363. /***************************************************************************/
  364. VOID block_read()
  365.    {
  366.       while (pbread<size && bread<bfsiz && inpleft>inplimit && w==16384)
  367.       {
  368.        if (bfsiz>=bread+16384 && size>=pbread+16384 && inpleft>inplimit+16384)
  369.         {
  370.         w=fread(bfpa[bfx],1,16384,fp1);
  371.         }
  372.        else
  373.        if (size-pbread>bfsiz-bread && inpleft-inplimit>bfsiz-bread)
  374.        {
  375.         w=fread(bfpa[bfx],1,(int)(bfsiz-bread),fp1);
  376.        }
  377.        else
  378.        if (inpleft-inplimit>size-pbread)
  379.        {
  380.         w=fread(bfpa[bfx],1,(int)(size-pbread),fp1);
  381.        }
  382.        else
  383.        {
  384.         w=fread(bfpa[bfx],1,(int)(inpleft-inplimit),fp1);
  385.        }
  386.        if (ferror(fp1))
  387.         {
  388.          printf("File read error.\n");
  389.          exit(8);
  390.         }
  391.        bfx++;
  392.        bread+=(long)w;
  393.        pbread+=(long)w;
  394.        inpleft-=(long)w;
  395.       } /* while (pbread<size && bread<bfsiz && inpleft>inplimit && w==16384)*/
  396.    }/* VOID block_read()*/
  397. /***************************************************************************/
  398.  VOID block_write()
  399.   {
  400.       bfx=0;w=16384;
  401.       pbwrit=0;bwrit=0;
  402.       while (pbwrit<size && bwrit<bread && w==16384)
  403.       {
  404.        if (bread>=bwrit+16384 && size>=pbwrit+16384)
  405.        {
  406.         w=fwrite(bfpa[bfx],1,16384,fp2);
  407.        }
  408.        else
  409.        if ((size-pbwrit)>(bread-bwrit))
  410.         {
  411.         w=fwrite(bfpa[bfx],1,(int)(bread-bwrit),fp2);
  412.         }
  413.        else
  414.         {
  415.         w=fwrite(bfpa[bfx],1,(int)(size-pbwrit),fp2);
  416.         }
  417.        if (ferror(fp2))
  418.         {
  419.          printf("File write error.\n");
  420.          exit(8);
  421.         } /*ferror(fp2)*/
  422.        bfx++;
  423.        bwrit+=(long)w;
  424.        pbwrit+=(long)w;
  425.       } /*while (pbwrit<size && bwrit<bread && w==16384)*/
  426.   } /*VOID block_write()*/
  427. /***************************************************************************/
  428.  VOID copy_to_eol()
  429.          {
  430.          while(1)
  431.           {
  432.             c = getc(fp1);
  433.             if( c == EOF )
  434.                {
  435.                close_out(fp2,output_file);
  436.                exit(0);
  437.                }
  438.            inpleft--;
  439.            if (c == LF) break;
  440.            if (c != CR)
  441.            {
  442.             putc(c,fp2);
  443.             pbwrit++;
  444.            }
  445.           } /*while(1)*/
  446.          } /*VOID copy_to_eol()*/
  447. /***************************************************************************/
  448. VOID help()
  449.    {
  450.    printf("Version %s -- 09/25/89\n",VERSION);
  451.    printf("USAGE: %s FILENAME SIZE [OUTPATH] -SWITCHES\n\n",PROGNAME);
  452.    printf("Written by W. J. Kennamer (74025,514) and released into the public domain.\n");
  453.    printf("Enhanced by Edgar Swank.\n");
  454.    printf("  FILENAME is any valid MS-DOS filename.  Wildcards are not supported.\n");
  455.    printf("  Output file names will be FILENAME.1, FILENAME.2, etc.\n");
  456.    printf("  Output files are always terminated with a carriage return and\n");
  457.    printf("  a <ctrl>Z, UNLESS -b is specified.\n");
  458.    printf("  SIZE is the desired file size for each new file.\n");
  459.    printf("  OUTPATH is an optional disk/pathname (A: or \path\ or a:\path\)\n");
  460.    printf("  to put output files on a different disk and/or directory from input file.\n");
  461.    printf("  If using -p with OUTPATH, enter some dummy argument for SIZE.\n");
  462.    printf("  SWITCHES must follow the FILENAME,SIZE and OUTPATH parameters,\n");
  463.    printf("    and may be entered in any order.  Switches may be combined.\n");
  464.    printf("Press any key to continue:\n");
  465.     getchar();
  466.    printf("  Valid SWITCHES are:\n");
  467.    printf("╔═════════════════╤═══════════════════════════════════════════════╗\n");
  468.    printf("║   -b  binary    │ do not add cr/lf/^z to output files.          ║\n");
  469.    printf("║                 │   forces -s.                                  ║\n");
  470.    printf("╟─────────────────┼───────────────────────────────────────────────╢\n");
  471.    printf("║   -s  strict    │ chop file at exact SIZE boundary.             ║\n");
  472.    printf("╟─────────────────┼───────────────────────────────────────────────╢\n");
  473.    printf("║   -w  wait      │ wait after closing each output file.          ║\n");
  474.    printf("║                 │ can change output diskette if separate        ║\n");
  475.    printf("║                 │ from input.                                   ║\n");
  476.    printf("╟─────────────────┼───────────────────────────────────────────────╢\n");
  477.    printf("║   -r  return    │ chop file at first carriage return            ║\n");
  478.    printf("║                 │   following SIZE characters (default).        ║\n");
  479.    printf("╟─────────────────┼───────────────────────────────────────────────╢\n");
  480.    printf("║   -px partition │ partition file into x equal units.            ║\n");
  481.    printf("║                 │   SIZE is ignored (and may be omitted) if     ║\n");
  482.    printf("║                 │   you choose this option.                     ║\n");
  483.    printf("╚═════════════════╧═══════════════════════════════════════════════╝\n");
  484.    }
  485.  
  486. /***************************************************************************/
  487.  
  488. VOID close_out(fp,filename)
  489.  
  490. FILE *fp;
  491. char *filename;                    /* output file name                 */
  492.  
  493.    {
  494.    long file_size;
  495.  
  496.    if (binary==OFF)
  497.    {
  498.    putc(CR,fp);                    /* terminating CR */
  499.    putc(LF,fp);                    /* terminating LF */
  500.    putc(CTRL_Z,fp);                /* terminate file with EOF mark    */
  501.    }
  502.  
  503.    if( fseek(fp,0L,2) == -1 )         /* position at EOF                 */
  504.                 {
  505.                 printf("Error seeking end of output file.\n");
  506.                 exit(1);
  507.                 }
  508.    file_size = ftell(fp);          /* report EOF position             */
  509.    fclose(fp);
  510.    printf("Created %s -- %ld bytes\n" , filename , file_size);
  511.    if (wait==ON && inpleft>0)
  512.     {
  513.      printf("Press any key to continue.\n");
  514.      getchar();
  515.     }
  516.    }
  517.  
  518. /***************************************************************************/
  519.