#include #include #include #include #include #include #include #include #include #include #include using namespace std; using std::string; //*************************************************************************** // // s e g c R E A D . C // // Program to control input from tape. Performs check of data and runs several // loops to read all data from magnetic tapes. Control file is a simple log file // that will list all records retreived from tape and corresponding status. // // Compile with: g++ -lm -o segcREAD segcREAD.C // ------------------------------------------------------------------------ // Rev. Date By Description // ------------------------------------------------------------------------ // 0.1 July 2004 M.Slinde First version // //*************************************************************************** //METHODS declaration int dd_read(); string create_segcfile(); void update_logfile(int run, string filename, int filesz); vector get_runList(int expRun); int get_numRec(); int get_filenum(); int get_filesz(string filename); unsigned short bcd_to_ushort (unsigned short *input); string intToStr(int x); int strToInt(string s); string chToStr(char *x); string get_time(); void get_locTape(int reqv_loc); string get_recItem(char *record, int item); //GLOBAL variables char uCom[500]; char folderloc[500]; char logpath[500]; char temppath[500]; char errlog[500]; //MAIN PROGRAM int main(int args, char* argv[]) { char *reel_arg; int run = 1; int expRuns; string fl; //get argument for folderlocation reel_arg= argv[1]; //check with user cout << ">Start reading into : ./"; cout << reel_arg << endl; cout << ">Is this correct (y/n) :"; if ( ! (cin.get() == 'y') ) exit(0); //create folderlocation sprintf(folderloc,"%s", reel_arg); sprintf(uCom,"mkdir %s", folderloc); system(uCom); //create error log to redirect output of stderr/stdout sprintf(errlog,"%s/err.log", folderloc); ofstream oup(errlog); oup.close(); //create tempfile path : here "temp.segc" sprintf(temppath,"%s/temp.segc", folderloc); //create logfile-path fl = reel_arg; if (fl.find("/") != -1) { fl = fl.substr(fl.find_last_of("/")+1); } else fl = reel_arg; sprintf(logpath,"%s/%s.log", folderloc, (char*) fl.c_str()); //start reading - based on log and how many records to append cout<<">Start reading : " << logpath; cout<<" contains " << get_numRec() << " records" <Append to total number of records: "; cin >> expRuns; //READ IN - get a runlist to handle input vector runlist = get_runList(expRuns); vector::iterator rec = runlist.begin(); /** * Reverse the array/vector - read backwards if * currentlocation on tape is higher than expected_runs/2 */ if (get_filenum() > expRuns/2) { cout << ">Warning: Running logfile in reverse" < 0) { cout << "@ Checking entry: " << s < 272) update_logfile(run,create_segcfile(), sz); if (sz == 272) { //only header has been read update_logfile(run, "Error: header ok/segc data lost", sz); dd_read(); //read one empty } if (sz < 272) update_logfile(run, "Error: data lost", sz); rec++; } cout << "Session closed - run again to retreive more records!!!" < to main //*******************************************************/ vector get_runList( int expRun ) { vector v; char buff[256]; int n = 0; ifstream log_file(logpath); while (! log_file.eof()) { log_file.getline(buff,200); string s = buff; if (!log_file.eof()) { //if its not the last empty record v.push_back(s); n++; } } log_file.close(); for ( int i = n; i <= expRun; i++) //append new records v.push_back("NEW"); return v; } /******************************************************* // Get number of records in logfile //*******************************************************/ int get_numRec() { //create if it does not exist if ((fopen(logpath, "r"))==NULL) { ofstream logfile (logpath); logfile << "#RUN\t#FILE\t#SIZE\t#DATE&TIME\t#SOURCE\n"; logfile.close(); return 0; } char buf[200]; int count=0; ifstream logfileIN(logpath); while (! logfileIN.eof() ) { logfileIN.getline (buf,200); count++; } logfileIN.close(); return count-2; } /******************************************************* // A method to get data from log file entries (records) // items : 0=run 1=filename 2=size 4=date&time 5=source //*******************************************************/ string get_recItem(char *record, int item) { char buff[256]; char *tok; int nums=0; sprintf(buff,"%s", record); tok = strtok(buff,"\t"); while (tok != NULL) { if (item==nums) return tok; nums++; tok = strtok (NULL, "\t, "); } return ""; } /******************************************************* // Extract the filenumber from mt-status command. // Redirects output to tmp.log and does some fuzzy // string operation to get the filenumber. //*******************************************************/ int get_filenum() { char input[40]; char tmplog[100]; sprintf(tmplog,"%s/tmp.log", folderloc); sprintf(uCom,"mt -f /dev/nst0 status >%s", tmplog); //redirect output to file tmp.log in same folder system(uCom); fread(input, sizeof(input), 1, fopen(tmplog, "r")); string s = input; s = s.substr(s.find("=")+1); s.erase(s.find(",")); sprintf(uCom,"rm %s", tmplog); //remove it system(uCom); return atoi ((char*)s.c_str()); } /******************************************************* // Move to wanted location on tape // //*******************************************************/ void get_locTape(int reqv_loc) { int curr_loc = get_filenum(); int mark = reqv_loc - curr_loc - 1; // if this is null the location is correct if (mark > 0) { //forward to filenumber sprintf(uCom,"mt -f /dev/nst0 fsf %i", mark-1); system(uCom); dd_read(); //read one empty } if (mark < 0 && reqv_loc > 2) { //rewind to filenumber sprintf(uCom,"mt -f /dev/nst0 bsf %i", abs(mark)+1); system(uCom); dd_read(); //read one empty } if (mark < 0 && reqv_loc == 1) { //to the start; just rewind sprintf(uCom,"mt -f /dev/nst0 rewind"); system(uCom); } if (mark < 0 && reqv_loc == 2) { //to the second; just rewind and read one empty sprintf(uCom,"mt -f /dev/nst0 rewind"); system(uCom); dd_read(); //read one empty } } /******************************************************* // Lookup file size in folder for spesific file // Returns file_size in bytes //*******************************************************/ int get_filesz(string filename) { //redirect output to file tmp.log in same folder struct stat file; if(!stat((char*)filename.c_str(),&file)) { return file.st_size; } return 0; } //******************************************************* // SEG-C header parameter extraction routines. //******************************************************* unsigned short bcd_to_ushort (unsigned short *input) { int out; unsigned short test; unsigned short i = *input; unsigned short mask; mask = 0xF0; test = (i & mask) >> 4; out=test*1000; mask = 0xF; test = (i & mask); out += test*100; mask = 0xF000; test = (i & mask) >> 12; out += test*10; mask = 0xF00; test = (i & mask) >> 8; out += test; return out; } /******************************************************* // Convert int to string // //*******************************************************/ string intToStr(int x) { std::stringstream ss; std::string str; ss << x; ss >> str; return str; } /******************************************************* // Convert char to string // //*******************************************************/ string chToStr(char *x) { string s = x; return s; } /******************************************************* // Convert string to int // //*******************************************************/ int strToInt(string w) { return atoi ((char*)w.c_str()); } /******************************************************* // get date and time as a string // //*******************************************************/ string get_time() { char buff[256]; time_t curtime; struct tm *loctime; char *tok; curtime = time (NULL); loctime = localtime (&curtime); sprintf(buff,"%s", asctime(loctime)); tok = strtok(buff,"\n"); string s = tok; return s; } //================================================================================== // E N D O F P R O G R A M //==================================================================================