/* This program splits the input file into smaller files. USAGE: CHOP FILENAME SIZE [OUTPATH] -SWITCHES Version 1.22. Written by W. J. Kennamer and released into the public domain. Enhanced by Edgar Swank " " " Enhancements/Changes: 1)Performance improvement by reading/writing in large blocks. 2)Support for non-ASCII files with -b option. 3)Add optional disk/path for output files. 4)Add -w option to wait after each output file (except last). Note: this source is now for IBM/MS C Compiler. Compile with HUGE memory model /AH. FILENAME is any valid MS-DOS filename. Wildcards are not supported. Output file names will be FILENAME.1, FILENAME.2, etc. Output files are always terminated with a carriage return and a Z, UNLESS -b is specified. SIZE is the desired file size for each new file. OUTPATH is an optional disk/pathname (A: or \path\ or a:\path\) to put output files on a different disk and/or directory from input file. If using -p with OUTPATH, enter some dummy argument for SIZE. SWITCHES must follow the FILENAME,SIZE and OUTPATH parameters, and may be entered in any order. Switches may be combined. Valid SWITCHES are: -b binary º do not add cr/lf/^z to output files. º forces -s. -s strict º chop file at exact SIZE boundary. -w wait º wait after closing each output file. º can change output diskette if separate from input. -r return º chop file at first carriage return º following SIZE characters (default). -px partition º partition file into x equal units. º SIZE is ignored (and may be omitted) if º you choose this option. File pointer fp1 is the input file. fp2 is always the output file, though its name changes as new output files are opened. */ #include #include #include #include #define VERSION "1.22" #define PROGNAME "CHOP" #define CTRL_Z 0x1a #define VOID int #define CR 0x0d #define LF 0x0a #define OFF 0 #define ON 1 int binary = OFF; /* do not add CR,LF,EOF */ int wait = OFF; /* Wait after each output file close*/ int count; /* no. of digits in size */ int c; /* current character */ int j; /* index */ long inpleft; /* Bytes input left to read */ long inplimit; /* Bytes input left to read low lim */ long bfsiz; /* I/O buffer size */ long bread; /* Bytes read into buffer */ long pbread; /* Bytes read this partition */ long bwrit; /* Bytes written from buffer */ long pbwrit; /* Bytes written this partition */ long size = 0; /* partition value -- file size */ long byte_count = 0; /* total bytes in original file */ long inpfz = 0; /* total bytes in original file */ long out_file_size = 0; /* total bytes in output file */ char *bfpa[20]; /* I/O buffer pointer array */ FILE *fp1,*fp2; /* fp1=input, fp2=output */ int bfx; /* buffer array index */ int num_output_files = 0; /* no of files successfully created */ int length; /* length of matching string */ int normal = ON; /* normal CR breaks */ int strict = OFF; /* break exactly at boundary */ int partition = OFF; /* strict or normal */ int num_part; /* number of partitions */ int int_size; /* integer for file size */ int nmb; /* number of 16k blocks IO */ unsigned int w; char *p; /* pointer to switch string */ char *period_p; /* location of period in filename */ char *output_file; /* output file name */ char filename[80]; /* original file name */ char fnwork[80]; /* workarea for file name */ char outpath[64]; /* optional output disk/path */ char line1[80]; /* data buffer */ char line2[30]; /* data buffer */ char *switches; /* string to hold switches */ VOID help(); VOID close_out(); VOID block_read(); VOID block_write(); VOID copy_to_eol(); VOID construct_output_filename(); main(argc,argv) int argc; char *argv[]; { /* test code to prints args ********** printf("ARGC=%d\n",argc); for (j=0;j 5 || argc < 3 || strcmp(argv[2],"-?")==0 || strcmp(argv[3],"-?")==0 || strcmp(argv[4],"-?")==0 ) { help(); exit(1); } /* see which argument is the switch */ switches = line2; strcpy(switches,""); for (j=2;j3) strcpy(outpath,argv[3]); else outpath[0]=0; set_switches(); if( (fp1 = fopen(argv[1],"rb") ) == NULL) { printf("Cannot open %s for input.\n",argv[1]); exit(1); } if( fseek(fp1,0L,2) == -1) /* position at EOF */ { printf("Error seeking end of input file.\n"); exit(1); } inpfz = ftell(fp1); /* tell EOF */ rewind(fp1); /* back to beginning of file */ printf(" Input file size = %ld bytes\n",inpfz); /* determine file size */ if(partition == ON) { /* each partition requires 3 extra bytes -- CTRL_Z, newline */ size = ((inpfz + 3*(long)num_part) / (long)num_part ) + 1 ; printf(" Partition size = %ld bytes\n",size); printf("No. of partitions = %ld\n\n",(long)num_part); } else /* partition is not ON */ { /* read SIZE from command line */ count = sscanf(argv[2],"%D",&size); /* convert string to long integer */ if(count == 0) { printf("Invalid size\n"); exit(1); } } /*else*/ if (size>inpfz) { printf("Requested Size > Input File Size.\n"); exit(1); } strcpy(filename,argv[1]); period_p = strchr(filename,'.'); /* locate the period, if any */ if( period_p != NULL ) *period_p = '\0'; /* chop off the period */ if (outpath[0]!=0) /* if outpath specified */ construct_output_filename(); inpleft=inpfz; if (binary==ON) inplimit=0; else inplimit=3; bread=0;pbread=0;w=16384; bwrit=0;pbwrit=0;bfx=0; while (inpleft>inplimit) { block_read(); if (pbwrit==0) { (num_output_files)++; if(num_output_files > 127) { printf("Too many files--%d.\nExiting program\n.",num_output_files); exit(1); } output_file = line1; /* initialize output_file pointer */ /* create the next filename */ sprintf(output_file,"%s.%-d",filename,num_output_files); fp2 = fopen(output_file,"wb"); if (fp2 == NULL) { printf("Cannot open %s for output\n",output_file); printf("Exiting the program.\n"); printf("%d files created.\n",(num_output_files) - 1 ); printf("Actual original filesize = %u bytes.\n",byte_count); exit(1); } } /*pbwrit==0 */ block_write(); if( inpleft == 0 ) { close_out(fp2,output_file); exit(0); } if (pbwrit>=size) { if( normal == ON ) copy_to_eol(); close_out(fp2,output_file); pbwrit=0;pbread=0; } /*if (pbwrit>=size)*/ bfx=0;bread=0;w=16384; bwrit=0; } /*while (inpleft>inplimit)*/ while(1) { c = getc(fp1); if( c == EOF ) { close_out(fp2,output_file); exit(0); } inpleft--; if (binary==ON || (c != CR && c !=LF && c != CTRL_Z)) { putc(c,fp2); } } /*while(1)*/ } /*main(argc,argv)*/ /***************************************************************************/ VOID set_switches() { for( p = switches ; (p - switches) < strlen(switches) ; p++ ) { if( *p == 's' ) { strict = ON; normal = OFF; } else if( *p == 'b' ) { strict = ON; normal = OFF; binary = ON; } else if ( *p == 'r' || *p == 'n') { normal = ON; strict = OFF; binary = OFF; } else if ( *p == 'p') { partition = ON; if(sscanf((p+1),"%d",&num_part) == 0 || num_part<=0) { printf("Invalid number of partitions.\n"); exit(1); } } else if ( *p == 'w') { wait = ON; } } /*for( p = switches ...*/ } /*VOID set_switches()*/ /***************************************************************************/ VOID construct_output_filename() { p=outpath+strlen(outpath)-1; /* ensure outpath properly terminated*/ if (*p!='\\' && strchr(outpath,'\\')!=0) { *(p+1)='\\'; *(p+2)=0; } if (filename[1]==':') /* strip disk/path from input filename*/ { strcpy(fnwork,(filename+2)); strcpy(filename,fnwork); } for (p=filename+strlen(filename);p>=filename;p--) { if (*p=='\\') { strcpy(fnwork,p+1); strcpy(filename,fnwork); break; } /*if*/ } /* for (p=filename+strlen(filename),p>=filename,p--)*/ if (strlen(outpath)+strlen(filename)<75) { strcpy(fnwork,outpath); strcat(fnwork,filename); strcpy(filename,fnwork); } else { printf("Syntax Error generating output filename\n"); exit(8); } } /*VOID construct_output_filename()*/ /***************************************************************************/ VOID block_read() { while (pbreadinplimit && w==16384) { if (bfsiz>=bread+16384 && size>=pbread+16384 && inpleft>inplimit+16384) { w=fread(bfpa[bfx],1,16384,fp1); } else if (size-pbread>bfsiz-bread && inpleft-inplimit>bfsiz-bread) { w=fread(bfpa[bfx],1,(int)(bfsiz-bread),fp1); } else if (inpleft-inplimit>size-pbread) { w=fread(bfpa[bfx],1,(int)(size-pbread),fp1); } else { w=fread(bfpa[bfx],1,(int)(inpleft-inplimit),fp1); } if (ferror(fp1)) { printf("File read error.\n"); exit(8); } bfx++; bread+=(long)w; pbread+=(long)w; inpleft-=(long)w; } /* while (pbreadinplimit && w==16384)*/ }/* VOID block_read()*/ /***************************************************************************/ VOID block_write() { bfx=0;w=16384; pbwrit=0;bwrit=0; while (pbwrit=bwrit+16384 && size>=pbwrit+16384) { w=fwrite(bfpa[bfx],1,16384,fp2); } else if ((size-pbwrit)>(bread-bwrit)) { w=fwrite(bfpa[bfx],1,(int)(bread-bwrit),fp2); } else { w=fwrite(bfpa[bfx],1,(int)(size-pbwrit),fp2); } if (ferror(fp2)) { printf("File write error.\n"); exit(8); } /*ferror(fp2)*/ bfx++; bwrit+=(long)w; pbwrit+=(long)w; } /*while (pbwritZ, UNLESS -b is specified.\n"); printf(" SIZE is the desired file size for each new file.\n"); printf(" OUTPATH is an optional disk/pathname (A: or \path\ or a:\path\)\n"); printf(" to put output files on a different disk and/or directory from input file.\n"); printf(" If using -p with OUTPATH, enter some dummy argument for SIZE.\n"); printf(" SWITCHES must follow the FILENAME,SIZE and OUTPATH parameters,\n"); printf(" and may be entered in any order. Switches may be combined.\n"); printf("Press any key to continue:\n"); getchar(); printf(" Valid SWITCHES are:\n"); printf("ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»\n"); printf("º -b binary ³ do not add cr/lf/^z to output files. º\n"); printf("º ³ forces -s. º\n"); printf("ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ\n"); printf("º -s strict ³ chop file at exact SIZE boundary. º\n"); printf("ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ\n"); printf("º -w wait ³ wait after closing each output file. º\n"); printf("º ³ can change output diskette if separate º\n"); printf("º ³ from input. º\n"); printf("ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ\n"); printf("º -r return ³ chop file at first carriage return º\n"); printf("º ³ following SIZE characters (default). º\n"); printf("ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ\n"); printf("º -px partition ³ partition file into x equal units. º\n"); printf("º ³ SIZE is ignored (and may be omitted) if º\n"); printf("º ³ you choose this option. º\n"); printf("ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ\n"); } /***************************************************************************/ VOID close_out(fp,filename) FILE *fp; char *filename; /* output file name */ { long file_size; if (binary==OFF) { putc(CR,fp); /* terminating CR */ putc(LF,fp); /* terminating LF */ putc(CTRL_Z,fp); /* terminate file with EOF mark */ } if( fseek(fp,0L,2) == -1 ) /* position at EOF */ { printf("Error seeking end of output file.\n"); exit(1); } file_size = ftell(fp); /* report EOF position */ fclose(fp); printf("Created %s -- %ld bytes\n" , filename , file_size); if (wait==ON && inpleft>0) { printf("Press any key to continue.\n"); getchar(); } } /***************************************************************************/