📄 collection.cc
字号:
#include "collection.h"using namespace std;collection::collection(){ last.ut_type = -1; key = ftok("/dev/null",0); if((msgid = msgget(key,0))== -1){ msgid = msgget(key,IPC_CREAT | IPC_EXCL | 0600); if(msgid < 0) exit(-1); }} collection::~collection(){ dump_lastposition(); dump_unfinished(); multimap<short,utmpx*>::iterator it; for(it = login.begin(); it!=login.end();it++) delete it->second; for(it = logoff.begin(); it!=logoff.end();it++) delete it->second; list<info*>::iterator it2; for(it2 = data.begin(); it2 != data.end();it2++) delete *it2; }void collection::setdefault(){ backup_file = BACKUP; position_file = POSITION; system_file = SYSTEM;}string collection::localIP(){ static string ip = NOT_ASSIGNED; if(ip == NOT_ASSIGNED) { char* name = new char[255]; gethostname(name,255); hostent* h = gethostbyname(name); inet_ntop(AF_INET,h->h_addr_list[0],name,16); ip = name; delete name; } return ip;}void collection::loadconfiguration(const char* file){ if(file == NULL) { setdefault(); } else { if(access(file,F_OK)<0){ setdefault(); } else { ifstream fin(file); if(!fin) { setdefault(); } else { while(!fin.eof()) { char buf[MAX_BUF]; memset(buf,0x00,MAX_BUF); fin.getline(buf,MAX_BUF); string input = buf; if(input.find(COMMENT_TAG,0) != input.npos) continue; if(input.find(BACKUP_TAG,0) != input.npos){ backup_file = input.erase(0,input.find(DELIMITER_TAG,0)+1); } if(input.find(POSITION_TAG,0) != input.npos){ position_file = input.erase(0,input.find(DELIMITER_TAG,0)+1); } if(input.find(SYSTEM_TAG,0) != input.npos){ system_file = input.erase(0,input.find(DELIMITER_TAG,0)+1); } }//end of while(!fin.eof()) fin.close(); }//end of else [if(!fin)] }//end of else [if(access(file,F_OK)<0)] }//end of else [if(file == NULL)] #ifdef __DEBUG cout << " BACKUP =" << backup_file << endl; cout << " POSITION =" << position_file << endl; cout << " SYSTEM =" << system_file << endl; #endif}//end of functionvoid collection::retrieve(){ utmpx* tmp; #ifdef __TIMER _timer.start("collection::retrieve"); #endif //check backup if(access(backup_file.c_str(),F_OK)==0){ ifstream ifs(backup_file.c_str(),ios::in | ios::binary); while(1) { utmpx* p; p = new utmpx; ifs.read((char*)p,sizeof(utmpx)); if(ifs.eof()) break; login.insert(pair<short,utmpx*>(p->ut_pid,p)); } ifs.close(); } //load system file //set position if(access(position_file.c_str(),F_OK)==0) { utmpxname(position_file.c_str()); setutxent(); utmpx* pos = new utmpx; tmp = getutxent(); memcpy(pos,tmp,sizeof(utmpx)); #ifdef __DEBUG show(pos); #endif endutxent(); utmpxname(system_file.c_str()); setutxent(); tmp = getutxline(pos); #ifdef __DEBUG cout << endl << endl; show(tmp); #endif while(1) { if(tmp == NULL) { setutxent(); break; } else if(tmp->ut_tv.tv_sec != pos->ut_tv.tv_sec) { getutxent(); tmp = getutxline(pos); } else break; } #ifdef __DEBUG cout << " ------------ " << endl; show(tmp); #endif delete pos; } else { utmpxname(system_file.c_str()); setutxent(); } while((tmp = getutxent()) != NULL) { if(tmp->ut_type == USER_PROCESS) { utmpx* t = new utmpx; memcpy(t,tmp,sizeof(utmpx)); login.insert(pair<short,utmpx*>(tmp->ut_pid,t)); memcpy(&last,tmp,sizeof(last)); } if(tmp->ut_type == DEAD_PROCESS) { utmpx* t = new utmpx; memcpy(t,tmp,sizeof(utmpx)); logoff.insert(pair<short,utmpx*>(tmp->ut_pid,t)); } #ifdef __DEBUG printf("\x0d\tLogin: %d\tLogoff: %d",login.size(), logoff.size()); #endif } #ifdef __DEBUG utmpx* u = &last; show(u); cout << endl; #endif endutxent(); #ifdef __TIMER _timer.end(); _timer.show(); #endif}int collection::processing(){ #ifdef __DEBUG int s = login.size(); int count = 0; #endif multimap<short,utmpx*>::iterator it = login.begin(); #ifdef __TIMER _timer.start("collection::processing"); #endif for(it = login.begin();it != login.end();it++) { time_t min = -1; multimap<short,utmpx*>::iterator start,end,matched; start = logoff.lower_bound(it->first); end = logoff.upper_bound(it->first); matched = logoff.end(); if(start == end && start == logoff.end()) continue; while(start != end) { if(start->second->ut_tv.tv_sec > it->second->ut_tv.tv_sec && !strcmp(start->second->ut_name,it->second->ut_name)) { if(min == -1) { matched = start; min = start->second->ut_tv.tv_sec - it->second->ut_tv.tv_sec; } else { if(start->second->ut_tv.tv_sec - it->second->ut_tv.tv_sec < min && start->second->ut_tv.tv_sec - it->second->ut_tv.tv_sec > 0) { min = start->second->ut_tv.tv_sec - it->second->ut_tv.tv_sec; matched = start; } } } start++; } if(matched != logoff.end()) { store(it->second,min); #ifdef __DEBUG count++; #endif login.erase(it); it--; logoff.erase(matched); } } #ifdef __DEBUG printf("\nThere are %d matched. \n", count); #endif ////sending finish /* msg _msg; _msg.mtype = END; while(msgsnd(msgid,&_msg,sizeof(_msg),0)) sleep(1); */ #ifdef __TIMER _timer.end(); _timer.show(); cout << " there are still " << login.size() << " login no matched." << endl; #endif return 0;}void collection::store(const utmpx* u, const time_t& t){ info inf; memset(&inf,0x00,sizeof(inf)); strcpy(inf.user_name,u->ut_name); inf.start_time = u->ut_tv.tv_sec; inf.duration = t; strcpy(inf.IP,localIP().c_str()); //data.push_back(inf); msg _msg; _msg.mtype = 1; memcpy(&_msg.inf,&inf,sizeof(info)); #ifdef __DEBUG /*cout << " ***************** " << endl; cout << inf.user_name << "\t" << inf.duration << "\t"; cout << inf.IP << endl; cout << " ***************** " << endl; */ #endif while(msgsnd(msgid,&_msg,sizeof(_msg),IPC_NOWAIT)) sleep(1); }void collection::dump_unfinished(){ remove(backup_file.c_str()); string cmd = "touch " + string(backup_file); system(cmd.c_str()); int fd = open(backup_file.c_str(),O_WRONLY); if(fd < 0) { #ifdef __DEBUG cout << " cannot open file for output." << endl; #endif return; } for(multimap<short,utmpx*>::iterator it = login.begin(); it != login.end(); it++) { if(write(fd,(char*)(it->second),sizeof(utmpx))<0) { #ifdef __DEBUG perror("write"); #endif } } close(fd); }void collection::dump_lastposition(){ if(last.ut_type == -1) return; remove(position_file.c_str()); string cmd = "touch " + string(position_file); system(cmd.c_str()); utmpxname(position_file.c_str()); setutxent(); pututxline(&last); endutxent(); }void collection::show(struct utmpx*& tmp){ cout << tmp->ut_user << endl; cout << tmp->ut_id << endl; cout << tmp->ut_line << endl; cout << tmp->ut_pid << endl; cout << tmp->ut_type << endl; cout << tmp->ut_tv.tv_sec << endl; }void collection::start_cllection(){ retrieve(); processing();}void collection::receive(){ msg _msg; while(msgrcv(msgid,&_msg,sizeof(msg),0,0)>0) { info * _inf; _inf = new info; if(_msg.mtype == END) break; memcpy(_inf,&_msg.inf,sizeof(info)); #ifdef __DEBUG //cout << _inf->user_name << "\t" << _inf->duration << "\t"; //cout << _inf->IP << endl; #endif data.push_back(_inf); } #ifdef __DEBUG cout << " Threre are " << data.size() << " records matched" << endl; ofstream fout("result.txt"); fout << " Threre are " << data.size() << " records matched" << endl; for(list<info*>::iterator it = data.begin(); it!= data.end(); it++) { fout << (*it)->user_name << "\t" << (*it)->duration << "\t"; fout << (*it)->IP << endl; } fout.close(); #endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -