/************************************************************************** Program: virtlogsplit Why: Disperses a log file containing virtual domain names into several files readable by analog. OS: Developed under Windows NT Ver. 4.0, but runs on Unix. Autor: Thomas Belmer created: 2000-05-25 Invoke ------ virtlogsplit logfile directory_for_dispersed_files History ------- who when what --------------------------------------------------------------------------- Th. Belmer 2000-05-25 created. Th. Belmer 2000-05-10 For testing purposes corrupt lines get printed. Th. Belmer 2000-06-10 Algorythm for recognition of corrupt lines changed. Th. Belmer 2001-06-01 Extract only one given virtual domain. **************************************************************************/ #include #include #include #include #ifdef unix #else #include #endif #ifndef FALSE #define FALSE 0 #define TRUE !FALSE #endif #define ONE_LINE 10000 #ifdef unix #define C_PATH '/' #define CH_PATH "/" #else #define C_PATH '\\' #define CH_PATH "\\" #endif void GiveReturn (int iCode); unsigned long ReadAndProcessLogFile (char *cfilename, char *cpath_to_put, char *vDomain); // Terminate program by returning an error message. void GiveReturn (int iCode) { printf("Error %d.\n",iCode); exit (iCode); } unsigned long ReadAndProcessLogFile (char *cfilename, char *cpath_to_put, char *vDomain) { FILE *fstream = NULL; FILE *fOutput = NULL; char *cvDomain = NULL; char *cLineBuffer = NULL; char *cDatestart = NULL; char *cOutput = NULL; unsigned long ulLinesProcessed = 0; unsigned long ulWritten_lines = 0; unsigned long ulCorrupt_lines = 0; unsigned long ulOpening_errors = 0; unsigned long ulWriting_errors = 0; size_t st_path_to_put = 0; size_t st_Len = 0; size_t st_vDom = 0; int iWrite = 0; // Line variables. char *cOutput_line_start = NULL; char *cAfter_IP = NULL; if ( (cLineBuffer = malloc (ONE_LINE+1)) == NULL ) GiveReturn (3); st_path_to_put = strlen(cpath_to_put); if (vDomain != NULL) { st_vDom = strlen (vDomain); if (st_vDom > 1) cvDomain = malloc (st_vDom +1); if (cvDomain) { strcpy (cvDomain, vDomain); st_Len = st_vDom; // Virtual Domain must only contain "_". for (st_Len; st_Len > 0; st_Len--) if ( *(cvDomain+st_Len-1) == '.' ) *(cvDomain+st_Len-1) = '_'; } } // Read the file line by line or use stdin instead. if ( !strcmp (cfilename, "STDIN") ) fstream = stdin; else fstream = fopen(cfilename,"r"); if (fstream == NULL) GiveReturn (1); while (!feof(fstream)) { if ( fgets(cLineBuffer, ONE_LINE, fstream) != NULL ) { // Example of a line. // www.bieruhr.de 194.24.201.114 - - [16/May/2000:21:06:02 +0200] "GET /bilder/rauten.gif HTTP/1.1" 304 - // www.bieruhr.de 194.24.201.114 - accessgroup [16/May/2000:21:06:02 +0200] "GET /bilder/rauten.gif HTTP/1.1" 304 - cAfter_IP = strstr(cLineBuffer," - "); cOutput_line_start = strchr(cLineBuffer, ' '); // Check whether the line is ok. if ( (cAfter_IP == NULL) || (cOutput_line_start == NULL) || (cOutput_line_start >= cAfter_IP) ) { // Delete this line if you don't want to display corrupt lines. printf("Corrupt line:\n%s\n",cLineBuffer); ulCorrupt_lines++; } else { *cOutput_line_start = '\0'; cOutput_line_start++; // File name. st_Len = strlen (cLineBuffer); if ( (cOutput = malloc (st_path_to_put + st_Len + 10)) == NULL ) { fclose(fstream); GiveReturn (3); } strcpy (cOutput, cpath_to_put); // Last character must be path character. if ( *(cpath_to_put+st_path_to_put-1) != C_PATH ) strcat (cOutput, CH_PATH); // Replace '.' through '_' in domain name. for (st_Len; st_Len > 0; st_Len--) if ( *(cLineBuffer+st_Len-1) == '.' ) *(cLineBuffer+st_Len-1) = '_'; // The complete filename. strcat (cOutput, cLineBuffer); // Unfortunately Windows wants to have a file extension. strcat (cOutput, ".log"); if (cvDomain) { // printf ("%s, %s#\n", cvDomain, cLineBuffer); if (!strncmp (cvDomain, cLineBuffer, st_vDom)) iWrite = 1; else iWrite = 0; } else iWrite = 1; if (iWrite) { // Write the line to the file. fOutput = fopen(cOutput,"a+"); if (fOutput != NULL) { if ( fputs (cOutput_line_start, fOutput) < 0 ) ulWriting_errors++; else ulWritten_lines++; fclose (fOutput); } else ulOpening_errors++; } //printf ("%s\n",cOutput); ulLinesProcessed++; } } else break; } fclose (fstream); printf("Summary of run on file %s:\n", cfilename); printf("Total processed lines: \t%15d\n",ulLinesProcessed + ulCorrupt_lines); printf("Total lines ok: \t%15d\n", ulLinesProcessed); printf("Total written lines: \t%15d\n",ulWritten_lines); printf("Total corrupt lines: \t%15d\n", ulCorrupt_lines); printf("Total opening errors: \t%15d\n", ulOpening_errors); printf("Total writing errors: \t%15d\n", ulWriting_errors); return (ulLinesProcessed); } int main(int argc, char *argv[], char *envp[]) { char *chlogfilename = NULL; size_t st_Len = 0; unsigned long ulReturnValue = 0; double dStartZeit; time_t tStartZeit; // Welcome message. if ( (argc < 3) || (argc > 4) ) { printf("virtlogsplit version 1.0 - built "__DATE__" "__TIME__"\n"); printf("(c) 2000 Thomas Belmer, Email: Thomas.Belmer@asamnet.de\n\n"); printf("USAGE: virtlogsplit logfile path_to_put [virtdomain]\n\n"); printf("PARAMETERS:\n"); printf("logfile = logfile to process, use STDIN for standard input\n"); printf("path_to_put = path where to put the split files.\n"); printf("virtdomain = extract only the given virtual domain.\n\n"); printf("Examples: virtlogsize /usr/logs/access_log /usr/logs\n"); printf(" cat /usr/logs/access_log | virtlogsplit STDIN /usr/logs\n\n"); printf("FILE CONTENTS:\n"); printf("logfile before processing: "); printf("www.bieruhr.de 194.24.201.114 - - [16/May/2000...\n"); printf("files in path_to_put: "); printf("194.24.201.114 - - [16/May/2000...\n\n"); printf("RETURN CODES:\n"); printf("0 = Success\n"); printf("1 = Invalid logfile parameter\n"); printf("2 = Invalid path_to_put parameter\n"); printf("3 = Out of memory\n\n"); return (1); } // Parameters ok? if ( (st_Len=strlen(argv[1])) < 1 ) GiveReturn (1); if ( (st_Len=strlen(argv[2])) < 1 ) GiveReturn (2); dStartZeit = (double) clock() / CLOCKS_PER_SEC; time (&tStartZeit); printf("\n"); printf("virtlogsplit version 1.01 - built "__DATE__" "__TIME__"\n\n"); printf("Start: %s\n", ctime(&tStartZeit) ); ulReturnValue = ReadAndProcessLogFile (argv[1], argv[2], argv[3]); // printf("%d lines in %s processed.\n", ulReturnValue, argv[1]); printf("%lf seconds runtime.\n", ((double) clock() / CLOCKS_PER_SEC) - dStartZeit); return(0); }