/******************************************************************************/ /** Copyright 2005 MBARI - Monterey Bay Aquarium Research Institute */ /******************************************************************************/ /******************************************************************************/ /** Filename : LOBODATA.C */ /** Author : Luke Coletti */ /** Project : 600144 */ /** Version : 1.00 */ /** Created : 05/03/05 */ /** Compiler : gcc version 3.0.1 */ /** OS, Box : IRIX Release 6.5 IP27, lepas.mbari.org */ /** Archived : */ /** Summary : Parses the records within the downloaded files, that are */ /** managed via loboserv, and copies them into the appropriate */ /** mooring directories and data instrument files on tornado. */ /******************************************************************************/ /** Modification History: */ /** 03/16/06 LJC: Changed ERROR reporting to one e-mail message per file parse*/ /******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define OK 0 #define ERROR (-1) #define SENDMAIL "/usr/lib/sendmail -t" #define SENDER "coletti@mbari.org" #define RECIPIENT "coletti@mbari.org" enum LoboDataDirs{TestData=0, L01Data, L02Data, L03Data, L04Data, LoboDataDirsEnd}; static char *data_dirs[] = {"test", "L01", "L02", "L03", "L04"}; enum LoboRecords{LoboIsusData=0, LoboSbe16CtdData, LoboSbe37CtdData, LoboControllerStatusData, LoboControllerErrorData, LoboRecordsEnd}; static char *data_recs[] = {"", "", "", "", ""}; static char *data_file[] = {"isus.log", "sbe16.log", "sbe37.log", "lobo.log", "error.log"}; static char data_path_in[100] = "/u/coletti/lobo/outgoing"; static char data_path_out[100] = "/hosts/tornado/vol/vol0/ChemWebData/moorings/lobo"; struct dirent **filelist; long lobofiles; int ArchiveLoboFiles(char *fpath_in, char *fpath_out, char *id); int ProcessLoboFiles(char *fpath_in, char *fpath_out, char *id); int MoveLastTransmissionFile(char *fpath_in, char *fpath_out); int MatchRecord(char *rec); int ScanLoboFileDir(char *fpath, char *id); int fmatch(struct dirent *d); int numsortup(struct dirent **d1, struct dirent **d2); int numsortdn(struct dirent **d1, struct dirent **d2); void UpdateErrorLogFile(char *emsg); void SendEmail(char *subject, char *message); int main(int argc, char **argv, char **envp) { char sbuf[250]; char ebuf[250]; char path_in[250]; char path_out[250]; int choice, ret; ulong err_recs; /* if( isatty(0) ){ fprintf(stderr,"This program was meant to run out of cron\n"); exit( OK ); } */ //test if file system "Tornado" can be mounted! if( (ret = access(data_path_out, F_OK)) != OK ){ snprintf(sbuf, sizeof(sbuf)-1, "Tornado Mount Access Error"); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, main() - access() ret = %d - Tornado File System Unavailable", ret); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); exit(1); } choice = 0; while( choice < LoboDataDirsEnd ){ // construct input directory memset(path_in, '\0', sizeof(path_in) ); snprintf(path_in, sizeof(path_in)-1, "%s/%s", data_path_in, data_dirs[choice]); // scan directory for LOBO files only if( (lobofiles = ScanLoboFileDir(path_in, data_dirs[choice])) > 0 ){ // construct output directory memset(path_out, '\0', sizeof(path_out)); snprintf(path_out, sizeof(path_out)-1, "%s/%s/data", data_path_out, data_dirs[choice]); //check if output directory can be accessed if( (ret = access(path_out, F_OK)) != OK ){ snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Mount Access Error", data_dirs[choice]); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, main() - access() ret = %d - %s", ret, path_out); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); } else{ ArchiveLoboFiles(path_in, path_out, data_dirs[choice]); err_recs = ProcessLoboFiles(path_in, path_out, data_dirs[choice]); if(err_recs != 0){ snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Data Record Error(s)", data_dirs[choice]); snprintf(ebuf, sizeof(ebuf)-1, "At least one ERROR was found in %s\nTotal Error Records Found = %lu\n", file_in, err_recs); SendEmail(sbuf, ebuf); } MoveLastTransmissionFile(path_in, path_out); } } ++choice; } //end while return( OK ); } int ArchiveLoboFiles(char *fpath_in, char *fpath_out, char *id) { FILE *fptr_in; char cbuf[512]; char file_in[250]; char file_out[250]; char sbuf[250]; char ebuf[250]; int ret; long i; for(i = 0L; i < lobofiles; i++){ memset(file_in, '\0', sizeof(file_in)); snprintf(file_in, sizeof(file_in)-1, "%s/%s", fpath_in, filelist[i]->d_name); fptr_in = fopen(file_in, "r"); if( fptr_in == NULL ){ fclose(fptr_in); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Input File Access Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ArchiveLoboFiles() - fopen() ret = NULL - %s", file_in); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); continue; } fclose(fptr_in); memset(file_out, '\0', sizeof(file_out)); snprintf(file_out, sizeof(file_out)-1, "%s/%s", fpath_out, "archive.tar"); memset(cbuf, '\0', sizeof(cbuf)); snprintf(cbuf, sizeof(cbuf), "(/u/coletti/bin/tar -uPf %s %s)", file_out, file_in); ret = system(cbuf); } // end for return( OK ); } ulong ProcessLoboFiles(char *fpath_in, char *fpath_out, char *id) { FILE *fptr_in, *fptr_out; char sbuf[250]; char ebuf[250]; char file_in[250]; char file_out[250]; char record[2000]; char recstr[100]; char *dataptr; int index; long i; ulong err_ctr; err_ctr = 0; for(i = 0L; i < lobofiles; i++){ memset(file_in, '\0', sizeof(file_in)); snprintf(file_in, sizeof(file_in)-1, "%s/%s", fpath_in, filelist[i]->d_name); fptr_in = fopen(file_in, "r"); if( fptr_in == NULL ){ fclose(fptr_in); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Input File Access Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ProcessLoboFiles() - fopen() ret = NULL - %s", file_in); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); continue; } while( fgets(record, sizeof(record), fptr_in) != NULL ){ if( memccpy(recstr, record, ',', sizeof(recstr)) != NULL){ dataptr = memchr(record, ',', sizeof(record)) + 1; if( (index = MatchRecord(recstr)) != ERROR){ memset(file_out, '\0', sizeof(file_out)); switch(index){ case LoboIsusData: case LoboSbe16CtdData: case LoboSbe37CtdData: case LoboControllerStatusData: snprintf(file_out, sizeof(file_out)-1, "%s/%s", fpath_out, data_file[index] ); fptr_out = fopen(file_out, "a+"); if( fptr_out == NULL ){ fclose(fptr_out); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Output File Access Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ProcessLoboFiles() - %s - fopen() ret = NULL - %s", data_recs[index], file_out); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); break; } fprintf(fptr_out, "%s", dataptr); fclose(fptr_out); break; case LoboControllerErrorData: snprintf(file_out, sizeof(file_out)-1, "%s/%s", fpath_out, data_file[index] ); fptr_out = fopen(file_out, "a+"); if( fptr_out == NULL ){ fclose(fptr_out); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Output File Access Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ProcessLoboFiles() - %s - fopen() ret = NULL - %s", data_recs[index], file_out); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); break; //look at this again... } fprintf(fptr_out, "%s", dataptr); fclose(fptr_out); break; default: snprintf(file_out, sizeof(file_out)-1, "%s/%s", fpath_out, "unknown.log" ); fptr_out = fopen(file_out, "a+"); if( fptr_out == NULL ){ fclose(fptr_out); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Output File Access Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ProcessLoboFiles() - - fopen() ret = NULL - %s", file_out); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); break; } fprintf(fptr_out, "%s", dataptr); fclose(fptr_out); snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Data Record Unknown", id); snprintf(ebuf, sizeof(ebuf)-1, "Data Record Unknown in %s\nRecord = %s\n", file_in, dataptr ); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); } // end switch } // end MatchRecord if } // end memccpy if } // end while fclose(fptr_in); remove(file_in); } // end for return( err_ctr ); } int MoveLastTransmissionFile(char *fpath_in, char *fpath_out) { FILE *fptr_in; char cbuf[512]; char file_in[250]; int ret; memset(file_in, '\0', sizeof(file_in)); snprintf(file_in, sizeof(file_in)-1, "%s/%s", fpath_in, "lastfile.log" ); fptr_in = fopen(file_in, "r"); if( fptr_in == NULL ){ fclose(fptr_in); return( -10 ); } fclose(fptr_in); snprintf(cbuf, sizeof(cbuf), "(/u/coletti/bin/mv --backup --force %s %s)", file_in, fpath_out); ret = system(cbuf); return( ret ); } int MatchRecord(char *rec) { int choice; for (choice=0; (choice < LoboRecordsEnd); choice++) { if( strstr(rec, data_recs[choice]) != NULL ) return( choice ); } return( ERROR ); } /************************************************************************/ /* Function : ScanLoboFileDir */ /* Purpose : make a list of all valid files in the outgoing/LOBO dir*/ /* Input : None */ /* Outputs : None */ /* Comments : */ /************************************************************************/ int ScanLoboFileDir(char *fpath, char *id) { char sbuf[250]; char ebuf[250]; int ret; ret = scandir(fpath, &filelist, fmatch, numsortdn); if( ret < 0 ){ snprintf(sbuf, sizeof(sbuf)-1, "Lobo [%s] Scan Directory Error", id); snprintf(ebuf, sizeof(ebuf)-1, "ERROR, ScanLoboFileDir() - scandir() ret = %d - %s", ret, fpath); SendEmail(sbuf, ebuf); UpdateErrorLogFile(ebuf); return( ERROR ); } else return( ret ); } int fmatch(struct dirent *d) { int ret, year, doy, seq; ret = sscanf(d->d_name,"%2d%3d%3d.LOG", &year, &doy, &seq); if( ret == 3 ) return( TRUE ); else return( FALSE ); } int numsortup(struct dirent **d1, struct dirent **d2) { unsigned long num1; unsigned long num2; num1 = strtoul(d1[0]->d_name, (char **)NULL, 10); num2 = strtoul(d2[0]->d_name, (char **)NULL, 10); if(num1 > num2) return(-1); else if(num1 < num2) return(1); else if(num1 == num2) return(0); else return( OK ); //make the stupid compiler happy... } int numsortdn(struct dirent **d1, struct dirent **d2) { unsigned long num1; unsigned long num2; num1 = strtoul(d1[0]->d_name, (char **)NULL, 10); num2 = strtoul(d2[0]->d_name, (char **)NULL, 10); if(num1 > num2) return(1); else if(num1 < num2) return(-1); else if(num1 == num2) return(0); else return( OK ); //make the stupid compiler happy... } /************************************************************************/ /* Function : UpdateErrorLogFile */ /* Purpose : keep a usage log of all unsuccessful sessions */ /* Input : None */ /* Outputs : None */ /* Comments : */ /************************************************************************/ void UpdateErrorLogFile(char *emsg) { FILE *logfile; char timebuf[64]; time_t timer; struct tm *timeptr; time(&timer); timeptr = localtime(&timer); strftime(timebuf, sizeof(timebuf)-1, "%a %d %b %Y %H:%M:%S", timeptr); logfile = fopen("/u/coletti/lobo/logs/lobodata.log", "a+"); fprintf(logfile,"%s, %s, %ld\r\n", emsg, timebuf, getpid()); fflush(logfile); fclose(logfile); } void SendEmail(char *subject, char *message) { FILE *out; out = popen(SENDMAIL, "w"); fprintf(out, "From: %s <%s>\n", "LoboData", SENDER); fprintf(out, "To: %s\n", RECIPIENT); fprintf(out, "Subject: %s\n", subject); fprintf(out, "\n \n"); fprintf(out, "%s", message); fprintf(out, "\n \n"); pclose(out); }