/* * * split.c * * Copyright (c) 1997-2002 DF7BE * * Date : 22.05.2002 * * Logbuchprogramm DF7BE * Amateur-Radio log by DF7BE * Utility for backing up and restore CLLOG database * this programm splits a big file into many single * files to store them on several floppy disks * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the license, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA ( or visit * their web site at http://www.gnu.org/ ). * * * Modification documentation * * +------------+-------------------------+----------------------------------+ * + Date ! Name and Call ! Modification ! * +------------+-------------------------+----------------------------------+ * ! 22.05.2002 ! W.Brunken DF7BE ! first creation ! * +------------+-------------------------+----------------------------------+ * * Compiling: * * gcc split.c -o split.exe (DJGPP) * gcc split.c -o split (UNIX,LINUX) * cc split.c -o split (UNIX) * * MICROSOFT QUICK C 2.5 : use Make Menu * set at Options model to "small" * * * Zerlegen von uebergrossen Dateien in Teildateien * (Bytegroesse) * * fsplit -s ==> split file * beginning with file.001 , file.002 ... * fsplit -c [ext] ==> combine files * * : file extension of combined file * (optional, default is "new"). * * * also the following constants: * F360 , F720 , F1_2 , F1_4 for floppies * * aufteilen (-c) von file.ext in file.001,file.002, .... file.n * in Anzahl Bytes. * zusammenfuegen (-c) : file kennzeichnet die Teildateien, * beginnend mit file.001. * Beispiel : Zerlegen von example.dat von 998 KB in Teilen von je * 200Bytes : * split -s example.dat 200 * und wieder zusammenfuegen * * splitv -c example * setzt zur Datei example.new zusammen. * * splitv -c example dat * setzt zur Datei example.dat zusammen. * * Diskettengroessen: * 362496 F360 * 730112 F720 * 1213952 F1_2 * 1457664 F1_4 * * * EOF ist in der Regel (-1) * * Other Methods to combine the splitted files without this program: * Andere Moeglichkeiten, die Dateien auch ohne dieses Programm * zusammenzusetzen: * * MS-DOS-System 6.22: * COPY /B file.001+file.002+file.003 file.ext * * WinSplit: * - edit file.wsp containing the Extension of file * - Menu combine (zusammensetzen) * * UNIX: * mv file.001 file.ext * cat file.002 >> file.ext * cat file.003 >> file.ext * * **************************************************************** */ /* Define floppy sizes Definition der Diskettengroessen */ #define F_360 362496L #define F_720 730112L #define F_1_2 1213952L #define F_1_44 1457664L /* special defines of Pascal functions */ #define Copy(s1,a,b,s2) MID_D(s1,a,b,s2) #define Pos(a,b) INSTR(0,b,a) #include #include #include FILE * in; /* input file Eingabedatei */ FILE * out; /* output file Ausgabedatei */ /* ======================================= functions itoa and atoi for UNIX ! ======================================= */ #if ( !defined (_MSC_VER) && !defined (__TURBOC__) ) /* ----------------------------- integer to ascii conversion i : the integer e : char pointer to target string ( please reserve enough bytes ) b : base, possible values 10 for decimal 8 for octal 16 for hex returns : pointer to e ----------------------- */ char * itoa(int i , char * e , int b) { switch(b) { case 10: sprintf(e,"%d",i); break; case 8: sprintf(e,"%o",i); break; case 16: sprintf(e,"%x",i); default: * e = '\0'; break; } return e; } /* this function converts asci to integer z : array of char returns : the converted integer conversion stop, when a non numeric character appears */ int atoi ( char z[]) { int e = 0; int i = 0; /* fuehrende Leerzeichen ausblenden */ /* ignore leading blanks */ while (z[i] == ' ') i++; while (z[i] >= '0' && z[i] <= '9') { e = e * 10 + ( z[i] - '0'); i++; } return e; } #endif /* --------------------------------------------------- pos () returns the position of a character in a string by C index ( first position = 0 ) , -1 not found. Gibt die Position eines einzelnen Zeichens in einem String als Integer in C-Position zurueck. -1 : nicht gefunden (Benoetigt fuer viele Funktionen aber im wesentlichen beim Lesen aus Textdateien, wenn \n zu \0 als Stringende erzeugt werden muss. --------------------------------------------------- */ int _FAR_ _cdecl pos ( char *vk, int zeichen) { char *anfang = vk; while (*vk) { if ( *vk == zeichen ) { return vk - anfang; } vk++; } return -1; } /* INSTR */ /* Position des Teilstrings + 1 (Gemaess BASIC-Konvention ) Kein Treffer : wert von von pos (pos wird in der Regel mit 0 uebergeben ! Beispiel : a = INSTR(0,"ABCDEF","DE"); this is the same as INSTR in BASIC */ int _FAR_ _cdecl INSTR(int pos, char _FAR_ * s1 , char _FAR_ * s2 ) { char *s; pos=pos>0?pos:0; s=strstr(s1+pos,s2); return(s>NULL?(int)(s-s1+1):pos>0?pos:0); } char * dname (char * s) /* schneidet die Dateierweiterung ab cuts file extension s : pointer to string with filename the "." was left */ { char *h; h = strrchr(s,'.'); if (h != NULL) { h++; * h = '\0'; } return s; } /* string functions */ void MID_D(char * String,int n, int m, char * aus) /* BASIC-Funktion MID$ same as BASIC function MID$ Liefert ab Position n den String in der maximalen Laenge m Die Position p wird gemaess c-Konventionen intern um 1 reduziert 1 => 0 2 => 1 Aufrufbeispiel: MID_D(s,1,2,(char *) string); String hat mindestens die Laenge m + 1 wg. NULL-Byte */ { int max; * aus = '\0'; max=strlen(String)-n+1; if (max > 0 ) { if ( m < 0 || max < m ) m=max; strncat(aus,&String[n-1],m); } } void intform(char * f, int l, int vb) /* Verarbeitet einen String mit einer (positiven) Ganzzahl zum festen Format z.B. 9999 f : Zeiger auf String mit der Ganzzahl Es sollte fuer den String gegebenenfalls mehr Platz vorgesehen werden l : Feste L„nge vb = 1 : Vornullen werden durch Leerzeichen ersetzt. (bis auf die letzte Null). Achtung ! Die uebergebenen Parameter werden nicht ueberprft, bei festen Werten sowieso nicht notwendig. Verarbeitungsregeln: Die Ganzzahl wird rechtsbuendig ausgerichtet. Entfernen von Zeichen, die nicht zum Zeichensatz zs[] geh”ren : "123 1" ==> "01231" "1a2c3.a78"==> "12378" Ist der Rest absolut ungltig, wird 0 angenommen: "abc" "abc.def" oder ""(Leerstring) Wenn vb = 1 "123" ==> " 123" "1" ==> " 1" this function converts an integer to a string in a fixed format. leading zeros are filled, if necessary, expect vb is set to 1, now leading zeros are substituted by blanks */ { char zs[] = { "0123456789" }; /* the valid character set */ char temp[40]; char temp1[40]; char temp2[2]; int i,max,lae,t,wp,tr; strncpy(temp,f,39); temp[39] = '\0'; /* ersetze alle ungueltigen Zeichen vorerst durch Leerzeichen at first set a blank for an invalid character */ for ( i = 0 ; i < strlen(temp) ; i ++) { Copy(temp,i+1,1,(char *) temp2); if ( Pos(temp2,zs) == 0 ) temp[i] = ' '; } /* Entferne alle Leerzeichen remove all blanks */ t = 255; while ( t != 0 ) { t = INSTR(0,temp," "); if ( t != 0 ) { /* Zeichen entfernen remove characters */ strncpy(temp1,temp,t-1); temp1[t-1] = '\0'; strcat(temp1,&temp[t]); strcpy(temp,temp1); } } strcpy(temp1,temp); /* Formatieren der Vorkommastellen rechtbuendig trim to right */ memset(temp,'0',l); /* Vorbesetzung */ temp[l] = '\0'; /* abschl. NULL-Byte */ max = strlen (temp1); if ( max > 0 ) { if ( max > l ) max = l; lae = l - max; memcpy(&temp[lae], temp1 , max ); } /* bei Bedarf fuehrende Nullen unterdruecken if set, substitute leading zeroes with blanks */ if ( vb == 1 ) { tr = 0; lae = strlen(temp); for ( i = 0 ; i < lae - 1 ; i++ ) { if ( tr == 0 ) { if ( temp[i] == '0' ) { temp [i] = ' '; } else { tr = 1; } } } } /* Inhalt zurueckschreiben copy string to target adress */ strcpy (f,temp); return; } /* === the file functions === */ int split_file(char * datei, long gr) /* split the file parameters: datei : pointer to file name for split gr : the file size */ { int e = 1; /* Input Zeichen input char counter */ int o = 1; /* Output Zeichen output char counter */ int j=1; /* Extension Nr. the number of extension */ /* begin with 001 */ char s[80]; /* Dateiname file name */ char erw[4]; /* Erweiterung + Null-Byte the file extension + null Byte */ long i; /* Open input file */ if ( ! (in = fopen(datei, "rb"))) return (1); while( e != EOF ) { /* Open output file */ /* if ( ! ( out = fopen( strcat (strcpy(s,dname(datei)),itoa(j++,erw,10)),"wb"))) */ itoa(j++,(char *) &erw[0],10 ); /* extension number to char */ intform((char *) &erw[0] ,3,0); /* fixed length with leading zeros */ if ( ! ( out = fopen( strcat (strcpy(s,dname(datei)), erw) ,"wb" ))) { fclose (in); return (1); } /* say name of created file */ printf("Writing: %s\n",s); /* Schleife ueber Ausgangsgroesse loop byte counter */ for( i = 1 ; i <= gr && e != EOF ;i++) { e = fgetc(in); if ( e != EOF ) { o = fputc( e , out ); } } fclose (out); } /* while NOT EOF of input file */ fclose (in); return 0; } int combine_file(char * datei, char * erw) /* combine the file from split files beginning with .001 datei : pointer to string with filename or basename erw : pounter to string with new extension or NULL for default .new */ { int e = 1; /* Input Zeichen */ int o = 1; /* Output Zeichen */ int j = 1; /* Extension Nr. begin with 001 */ char s[80]; /* Dateiname (basename) */ char o[100]; /* output file name */ char akterw[4] = { '\0','\0','\0','\0' }; /* Erweiterung Nummer number file extension */ char d[] = { 'n','e','w', '\0' }; /* the default extension */ char rd[] = { '\0','\0','\0','\0' }; /* the real extension */ char *h; char beginn[] = { 'b' , 'e' , 'g' , 'i' , 'n' , '\0' }; long bc = 0L; /* count written bytes */ /* Erweiterung fuer Ausgabedatei uebernehmen, wenn vorhanden if set as option, copy file extension */ if ( erw == NULL ) { /* otherwise take default */ strcpy(rd,d); } else { /* take the extension of the function parameter */ strcpy(rd,erw); } /* suche Dateierweiterung search for old filextension */ /* h = strrchr(datei,'.'); */ /* Erweiterungszeiger initialisieren */ /* h++; j=atoi(h); */ /* open then output file */ if ( ! ( out = fopen( strcat (strcpy(s,dname(datei)),rd),"wb"))) { printf("Error: cannot open or create file %s\n",s); return (1); } /* remember name of output file */ strcpy(o,s); /* Teildatei oeffnen open single split file */ in = (FILE *) &beginn[0] ; /* is is necessary that the while loop read no null pointer at start position */ while ( in ) { /* Erweiterung "Nummer" bilden */ itoa(j++,(char *) &akterw[0],10 ); /* extension number to char */ intform((char *) &akterw[0] ,3,0); /* fixed length with leading zeros */ if ( h == NULL ) { strcat (strcat (strcpy(s,dname(datei)),"."),akterw); } else { strcat (strcpy(s,dname(datei)),akterw); } /* open the split file */ in = fopen(s,"rb"); if ( in != NULL ) { e = 1; printf("Reading %s\n",s); while ( e != EOF ) { e = fgetc (in); if ( e != EOF ) { o = fputc ( e ,out ); bc ++; } } fclose (in); } /* if open */ } /* while */ fclose (out); printf("Number of Bytes written to Output %s : %ld\n",o,bc); return 0; } void usage() { printf ("usage : fsplit -s ==> split file\n"); printf (" fsplit -c combine files\n"); printf (" : file extension of combined file\n"); printf (" also the following constants:\n"); printf (" F360 , F720 , F1_2 , F1_4 for floppies\n"); printf("\n"); printf("Copyright (c) 1997-2002 DF7BE\n"); printf("\n"); printf("This program is free software; you can redistribute it and/or modify\n"); printf("it under the terms of the GNU General Public License as published by\n"); printf("the Free Software Foundation; either version 2 of the license, or\n"); printf("(at your option) any later version.\n"); printf("\n"); printf("This program is distributed in the hope that it will be useful,\n"); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU General Public License for more details.\n"); printf("You should have received a copy of the GNU General Public License\n"); printf("along with this program; if not, write to the Free Software\n"); printf("Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA ( or visit\n"); printf("their web site at http://www.gnu.org/ ).\n"); } int main(int argc, char * argv[] ) { char d_name[80]; /* the file or basename */ char extens[21]; /* the file extension */ int rc; /* return code from operations */ long gr; /* the file size (not more than 2GByte) */ if (argc < 2 ) { usage(); exit (1); } strcpy(d_name,argv[2]); /* combine file with default file extension */ /* ohne Erweiterung ==> .new */ if ( ( ( strcmp(argv[1],"-c") == 0 ) || ( strcmp(argv[1],"-C") == 0 ) ) && ( argc == 3) ) { rc = combine_file((char *) &d_name, NULL ); return rc; } /* compile file using extension in command line option */ if ( ( ( strcmp(argv[1],"-c") == 0 ) || ( strcmp(argv[1],"-C") == 0 ) ) && /* Erweiterung uebergeben */ ( argc == 4) ) { strcpy(extens,argv[3]); if ( strlen(extens) > 3 ) { printf("Error: file extension longer then 3 characters\n"); usage(); } rc = combine_file((char *) &d_name, extens); return rc; } /* auswerten der Diskettengroesse compare for constants of floppy size */ if ( ( ( strcmp(argv[1],"-s") == 0 ) || ( strcmp(argv[1],"-S") == 0 ) ) && ( argc == 4 ) && ( ( strcmp(argv[3],"f360") == 0 ) || ( strcmp(argv[3],"F360") == 0 ) ) ) { rc = split_file((char *) &d_name,F_360); return rc; } if( ( ( strcmp(argv[1],"-s") == 0 ) || ( strcmp(argv[1],"-S") == 0 ) ) && (argc == 4 ) && ( ( strcmp(argv[3],"f720") == 0 ) || ( strcmp(argv[3],"F720") == 0 ) ) ) { rc = split_file((char *) &d_name,F_720); return rc; } if( ( ( strcmp(argv[1],"-s") == 0 ) || ( strcmp(argv[1],"-S") == 0 ) ) && (argc == 4 ) && ( ( strcmp(argv[3],"f1_2") == 0 ) || ( strcmp(argv[3],"F1_2") == 0 ) ) ) { rc = split_file((char *) &d_name,F_1_2); return rc; } if( ( ( strcmp(argv[1],"-s") == 0 ) || ( strcmp(argv[1],"-S") == 0 ) ) && (argc == 4 ) && ( ( strcmp(argv[3],"f1_4") == 0 ) || ( strcmp(argv[3],"F1_4") == 0 ) ) ) { rc = split_file((char *) &d_name,F_1_44); return rc; } /* Ende Diskettengroesse */ if( ( ( strcmp(argv[1], "-s") == 0 ) || ( strcmp(argv[1],"-S") == 0 ) ) && (argc == 4 ) ) { gr=atol(argv[3]); if ( gr != 0L) { /* Splitten mit Byteangabe split file using byte size */ rc = split_file((char *) &d_name,gr); return rc; } } /* there is something wrong */ printf("split abgebrochen\n"); usage(); exit (1); }