📄 session.cpp
字号:
#include "Session.h"Session::Session() {}Session::Session(char *data_str,time_t t) { init(data_str,t); }Session::~Session() {}void Session::init(char *str,time_t t) { string key,val; int state=0; unsigned i; for(i=0;i<strlen(str);i++) { // state machine switch(state) { case 0: // key cannot start from digit key=""; val=""; if(isalpha(str[i]) || str[i]=='_') { key+=str[i]; state=1; } break; case 1: if(isalnum(str[i]) || str[i]=='_') { key+=str[i]; state=1; } else if(str[i]=='=') { state=2; } else if(str[i]=='&') { data[key]=""; state=0; } break; case 2: // value if(str[i]=='\\') { state=3; } else if(str[i]!='&') { val+=str[i]; } else { data[key]=val; state=0; } break; case 3: // '&' escaped val+=str[i]; state=2; break; } } if(state==2 || state==1) { data[key]=val; } touched=t;}string &Session::get(const string &key) { return data[key];}void Session::set(const string &key,const string &val) { data[key]=val;}char * Session::to_string() { int pos=0; static char buf[MAXSESSIZE]; map<string,string>::const_iterator ci=data.begin(); while(ci!=data.end()) { if(pos>=MAXSESSIZE) return buf; const char *key=ci->first.c_str(); const char *val=ci->second.c_str(); strcpy(buf+pos,key); pos+=strlen(key); buf[pos++]='='; for(int i=0;i<strlen(val);i++) { if(val[i]=='&') { buf[pos++]='\\'; } buf[pos++]=val[i]; } buf[pos++]='&'; ci++; } buf[pos]=0; return buf;} bool getSession(const char *sid,Session &s) { int i; int shmid,semid; key_t key; sessionslist *slist; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid<0) return -1; lockSession(semid); shmid=getShmID(key); if(shmid<0) return -1; slist=(sessionslist *)shmat(shmid,NULL,0); for(i=0;i<slist->nsessions;i++) { if(!strcmp(sid,slist->s[i].sid)) { slist->s[i].touched=time(NULL); s.init(slist->s[i].data,slist->s[i].touched); shmdt(slist); unlockSession(semid); return true; } } shmdt(slist); unlockSession(semid); return false;}bool addSession(const char *sid,Session &s) { int i,sind; int shmid,semid; bool ret_val=false; key_t key; sessionslist *slist; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid<0) return false; if(lockSession(semid)==-1) return false; shmid=getShmID(key); if(shmid<0) goto unlock; slist=(sessionslist *)shmat(shmid,NULL,0); if((long)slist==-1) goto unlock; for(i=0;i<slist->nsessions;i++) { if(!strcmp(sid,slist->s[i].sid)) { strcpy(slist->s[i].data,s.to_string()); slist->s[i].touched=time(NULL); ret_val=true; goto detach; } } if(slist->nsessions>=MAXSESSIONS) { cleanUp(slist); if(slist->nsessions>=MAXSESSIONS) { goto detach; } } strcpy(slist->s[slist->nsessions].data,s.to_string()); strcpy(slist->s[slist->nsessions].sid,sid); slist->s[slist->nsessions].touched=time(NULL); slist->nsessions++; ret_val=true;detach: shmdt(slist);unlock: unlockSession(semid); return ret_val;}bool destroy() { int semid,shmid; key_t key; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid>=0) { shmid=getShmID(key); if(shmid) { if(!semctl(semid,0,IPC_RMID,0) && !shmctl(shmid,IPC_RMID,0)) { return true; } } } return false;}bool getInfo(int &nsessions,int &seed,vector <string> &sid,vector <string> &data,vector <time_t> &touched) { int i,sind; int shmid,semid; bool ret_val=false; key_t key; sessionslist *slist; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid<0) return false; if(lockSession(semid)==-1) return false; shmid=getShmID(key); if(shmid<0) goto unlock; slist=(sessionslist *)shmat(shmid,NULL,0); if((long)slist==-1) goto unlock; nsessions=slist->nsessions; seed=slist->seed; for(i=0;i<slist->nsessions;i++) { sid.push_back(slist->s[i].sid); data.push_back(slist->s[i].data); touched.push_back(slist->s[i].touched); } shmdt(slist); ret_val=true;unlock: unlockSession(semid); return ret_val;} bool removeSessions() { int i; int shmid,semid; key_t key; sessionslist *slist; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid<0) return -1; lockSession(semid); shmid=getShmID(key); if(shmid<0) return -1; slist=(sessionslist *)shmat(shmid,NULL,0); slist->nsessions=0; fprintf(stderr,"sessions removed\n"); shmdt(slist); unlockSession(semid); return true;} void cleanUp(sessionslist *slist) { int i; int shmid,semid; key_t key; fprintf(stderr,"cleaning up ...\n"); for(i=0;i<slist->nsessions;i++) { if((time(NULL) - slist->s[i].touched)>EXPIRE) { memmove(&(slist->s[i]),&(slist->s[i+1]),(slist->nsessions-i-1)*sizeof(session)); slist->nsessions--; i--; } } return;}int getSemID(key_t key) { int semid; if((semid=semget(key,1,0))==-1) { if(errno==ENOENT) { if((semid=semget(key,1,IPC_CREAT | 0755))==-1) { perror("semget"); return -1; } else { struct sembuf buf={0,1,0}; if(semop(semid,&buf,1)==-1) { perror("semop"); return -1; } return semid; } } else { perror("semget"); return -1; } } return semid;}int getShmID(key_t key) { int shmid; if((shmid=shmget(key,ALLSIZE,0))==-1) { if(errno==ENOENT) { if((shmid=shmget(key,ALLSIZE,IPC_CREAT | 0755))==-1) { perror("shmget"); return -1; } else { sessionslist *slist=(sessionslist *)shmat(shmid,NULL,0); slist->nsessions=0; shmdt(slist); return shmid; } } else { perror("shmget"); return -1; } } return shmid;}int lockSession(int semid) { struct sembuf buf={0,-1,0}; if(semop(semid,&buf,1)==-1) { perror("semop"); return -1; } return 0;}int unlockSession(int semid) { struct sembuf buf={0,1,0}; if(semop(semid,&buf,1)==-1) { perror("semop"); return -1; } return 0;}char *getUniqueId() { char symbols[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0'}; static char buf[9]; int i; int shmid,semid; key_t key; sessionslist *slist; key=ftok(FKEY,PROJ); semid=getSemID(key); if(semid<0) return NULL; lockSession(semid); shmid=getShmID(key); if(shmid<0) return NULL; slist=(sessionslist *)shmat(shmid,NULL,0); if((long)slist==-1) return NULL; srand(slist->seed++); for(i=0;i<8;i++) { buf[i]=symbols[((int) (36.0*rand()/(RAND_MAX+1.0)))]; } shmdt(slist); unlockSession(semid); return buf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -