diff --git a/server.c b/server.c index 596e8f7..22bf090 100644 --- a/server.c +++ b/server.c @@ -22,14 +22,16 @@ struct sockaddr_in server_addr; //char buff[BUFSIZ]; char *file_path; pthread_t accept_threads[8]; -FILE *fp_cross; #define MAXWAITSEC 10 struct THREADTIMER { pthread_t *thread; time_t touch; int accept_fd; + size_t numbytes; char *data; + char status; + FILE *fp; }; typedef struct THREADTIMER THREADTIMER; @@ -49,7 +51,7 @@ DICTBLK dict; void acceptClient(); void acceptTimer(void *p); int bindServer(uint16_t port, u_int try_times); -int checkBuffer(int accept_fd, int *s, char *data, size_t numbytes); +int checkBuffer(THREADTIMER *timer); int freeAfterSend(int accept_fd, char *data, size_t length); void closeDict(FILE *fp); int closeDictAndSend(FILE *fp, int accept_fd, char *data, size_t numbytes); @@ -61,13 +63,13 @@ int listenSocket(u_int try_times); FILE *openDict(int lock_type); int sendAll(int accept_fd, char *buff); int sendData(int accept_fd, char *data, size_t length); -int sm1_pwd(int *s, int accept_fd, char *buff); -int s0_init(int *s, int accept_fd, char *buff, size_t numbytes); -int s1_get(int *s, int accept_fd, char *buff); -int s2_set(int *s, int accept_fd, char *buff, size_t numbytes); -int s3_setData(int *s, int accept_fd, char *buff, size_t numbytes); -int s4_del(int *s, int accept_fd, char *buff); -int s5_list(int *s, int accept_fd, char *buff); +int sm1_pwd(THREADTIMER *timer); +int s0_init(THREADTIMER *timer); +int s1_get(THREADTIMER *timer); +int s2_set(THREADTIMER *timer); +int s3_setData(THREADTIMER *timer); +int s4_del(THREADTIMER *timer); +int s5_list(THREADTIMER *timer); int bindServer(uint16_t port, u_int try_times) { int fail_count = 0; @@ -113,6 +115,7 @@ int sendData(int accept_fd, char *data, size_t length) { return 0; } else { printf("Send data: "); + if(length > 64) length = 64; while(length--) putchar(*data++); putchar('\n'); return 1; @@ -133,93 +136,98 @@ int sendAll(int accept_fd, char *buff) { return re; } -int sm1_pwd(int *s, int accept_fd, char *buff) { - if(!strcmp(PASSWORD, buff)) *s = 0; - return !*s; +int sm1_pwd(THREADTIMER *timer) { + if(!strcmp(PASSWORD, timer->data)) timer->status = 0; + return !timer->status; } -int s0_init(int *s, int accept_fd, char *buff, size_t numbytes) { - if(!strcmp("get", buff)) *s = 1; - else if(!strcmp("set", buff)) *s = 2; - else if(!strcmp("del", buff)) *s = 4; - else if(!strcmp("lst", buff)) *s = 5; - else if(!strcmp("cat", buff)) return sendAll(accept_fd, buff); - else if(!strcmp("quit", buff)) return 0; - return sendData(accept_fd, buff, numbytes); +int s0_init(THREADTIMER *timer) { + if(!strcmp("get", timer->data)) timer->status = 1; + else if(!strcmp("set", timer->data)) timer->status = 2; + else if(!strcmp("del", timer->data)) timer->status = 4; + else if(!strcmp("lst", timer->data)) timer->status = 5; + else if(!strcmp("cat", timer->data)) return sendAll(timer->accept_fd, timer->data); + else if(!strcmp("quit", timer->data)) return 0; + return sendData(timer->accept_fd, timer->data, timer->numbytes); } -int s1_get(int *s, int accept_fd, char *buff) { +int s1_get(THREADTIMER *timer) { FILE *fp = openDict(LOCK_SH); DICTBLK dict; - *s = 0; - if(fp) while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { - u_char ks = dict.keysize; - dict.key[ks] = 0; - printf("[%s] Look key: (%d)%s\n", buff, ks, dict.key); - if(!strcmp(buff, dict.key)) - return closeDictAndSend(fp, accept_fd, dict.data, dict.datasize); - } - return closeDictAndSend(fp, accept_fd, "null", 4); -} - -#define copyKey() {\ - dict.keysize = (numbytes >= (DATASIZE-1))?(DATASIZE-1):numbytes;\ - strncpy(dict.key, buff, (DATASIZE-1));\ -} - -int s2_set(int *s, int accept_fd, char *buff, size_t numbytes) { - FILE *fp = openDict(LOCK_EX); + timer->status = 0; if(fp) { - *s = 3; + timer->fp = fp; while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { u_char ks = dict.keysize; dict.key[ks] = 0; - printf("[%zd] Key size: %d\n", numbytes, ks); - if(!dict.keysize || !strcmp(buff, dict.key)) { + //printf("[%s] Look key: (%d)%s\n", timer->data, ks, dict.key); + if(!strcmp(timer->data, dict.key)) + return closeDictAndSend(fp, timer->accept_fd, dict.data, dict.datasize); + } + } + return closeDictAndSend(fp, timer->accept_fd, "null", 4); +} + +#define copyKey() {\ + dict.keysize = (timer->numbytes >= (DATASIZE-1))?(DATASIZE-1):timer->numbytes;\ + strncpy(dict.key, timer->data, (DATASIZE-1));\ +} + +int s2_set(THREADTIMER *timer) { + FILE *fp = openDict(LOCK_EX); + if(fp) { + timer->status = 3; + timer->fp = fp; + while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { + u_char ks = dict.keysize; + dict.key[ks] = 0; + printf("[%zd] Key size: %d\n", timer->numbytes, ks); + if(!dict.keysize || !strcmp(timer->data, dict.key)) { copyKey(); fseek(fp, -DICTBLKSZ, SEEK_CUR); - fp_cross = fp; - return sendData(accept_fd, "data", 4); + return sendData(timer->accept_fd, "data", 4); } } copyKey(); fseek(fp, 0, SEEK_END); - fp_cross = fp; - return sendData(accept_fd, "data", 4); + return sendData(timer->accept_fd, "data", 4); } else { - *s = 0; - return sendData(accept_fd, "erro", 4); + timer->status = 0; + return sendData(timer->accept_fd, "erro", 4); } } -int s3_setData(int *s, int accept_fd, char *buff, size_t numbytes) { - *s = 0; - dict.datasize = (numbytes >= (DATASIZE-1))?(DATASIZE-1):numbytes; +int s3_setData(THREADTIMER *timer) { + timer->status = 0; + dict.datasize = (timer->numbytes >= (DATASIZE-1))?(DATASIZE-1):timer->numbytes; printf("Set data size: %d\n", dict.datasize); - memcpy(dict.data, buff, dict.datasize); + memcpy(dict.data, timer->data, dict.datasize); puts("Data copy to dict succ"); - if(fwrite(&dict, DICTBLKSZ, 1, fp_cross) != 1) { - printf("Error set data: dict[%s]=%s\n", dict.key, buff); - return closeDictAndSend(fp_cross, accept_fd, "erro", 4); + if(fwrite(&dict, DICTBLKSZ, 1, timer->fp) != 1) { + printf("Error set data: dict[%s]=%s\n", dict.key, timer->data); + return closeDictAndSend(timer->fp, timer->accept_fd, "erro", 4); } else { - printf("Set data: dict[%s]=%s\n", dict.key, buff); - return closeDictAndSend(fp_cross, accept_fd, "succ", 4); + printf("Set data: dict[%s]=%s\n", dict.key, timer->data); + return closeDictAndSend(timer->fp, timer->accept_fd, "succ", 4); } } -int s4_del(int *s, int accept_fd, char *buff) { +int s4_del(THREADTIMER *timer) { FILE *fp = openDict(LOCK_EX); DICTBLK dict; - *s = 0; - if(fp) while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { - dict.key[dict.keysize] = 0; - if(!strcmp(buff, dict.key)) { - fseek(fp, -DICTBLKSZ+(DATASIZE-1), SEEK_CUR); - fputc(0, fp); - return closeDictAndSend(fp, accept_fd, "succ", 4); + timer->status = 0; + if(fp) { + timer->fp = fp; + while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { + dict.key[dict.keysize] = 0; + if(!strcmp(timer->data, dict.key)) { + fseek(fp, -DICTBLKSZ+(DATASIZE-1), SEEK_CUR); + fputc(0, fp); + return closeDictAndSend(fp, timer->accept_fd, "succ", 4); + } } } - return closeDictAndSend(fp, accept_fd, "null", 4); + return closeDictAndSend(fp, timer->accept_fd, "null", 4); } off_t fileSize(const char* fname) { @@ -228,43 +236,44 @@ off_t fileSize(const char* fname) { else return -1; } -int s5_list(int *s, int accept_fd, char *buff) { - *s = 0; +int s5_list(THREADTIMER *timer) { + timer->status = 0; off_t size = fileSize(file_path) / DICTBLKSZ; char *keys = calloc(size, DATASIZE); DICTBLK dict; FILE *fp = openDict(LOCK_SH); if(keys && fp) { + timer->fp = fp; keys[0] = 0; while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { u_char ks = dict.keysize; dict.key[ks] = 0; - printf("[%s] Look key: (%d)%s\n", buff, ks, dict.key); - if(strstr(dict.key, buff)) { + //printf("[%s] Look key: (%d)%s\n", timer->data, ks, dict.key); + if(strstr(dict.key, timer->data)) { strcat(keys, dict.key); strcat(keys, "\n"); } } int len = strlen(keys); closeDict(fp); - if(len > 0) return freeAfterSend(accept_fd, keys, len); - else return sendData(accept_fd, "null", 4); + if(len > 0) return freeAfterSend(timer->accept_fd, keys, len); + else return sendData(timer->accept_fd, "null", 4); } else { if(fp) closeDict(fp); - return sendData(accept_fd, "erro", 4); + return sendData(timer->accept_fd, "erro", 4); } } -int checkBuffer(int accept_fd, int *s, char *data, size_t numbytes) { - printf("Status: %d\n", *s); - switch(*s) { - case -1: return sm1_pwd(s, accept_fd, data); break; - case 0: return s0_init(s, accept_fd, data, numbytes); break; - case 1: return s1_get(s, accept_fd, data); break; - case 2: return s2_set(s, accept_fd, data, numbytes); break; - case 3: return s3_setData(s, accept_fd, data, numbytes); break; - case 4: return s4_del(s, accept_fd, data); break; - case 5: return s5_list(s, accept_fd, data); break; +int checkBuffer(THREADTIMER *timer) { + printf("Status: %d\n", timer->status); + switch(timer->status) { + case -1: return sm1_pwd(timer); break; + case 0: return s0_init(timer); break; + case 1: return s1_get(timer); break; + case 2: return s2_set(timer); break; + case 3: return s3_setData(timer); break; + case 4: return s4_del(timer); break; + case 5: return s5_list(timer); break; default: return -1; break; } } @@ -286,6 +295,7 @@ void acceptTimer(void *p) { pthread_kill(*timer->thread, SIGQUIT); close(timer->accept_fd); if(timer->data) free(timer->data); + if(timer->fp) closeDict(timer->fp); *timer->thread = 0; } } @@ -306,7 +316,7 @@ void handleAccept(void *p) { if (pthread_create(&thread, NULL, (void *)&acceptTimer, p)) puts("Error creating timer thread"); else puts("Creating timer thread succeeded"); sendData(accept_fd, "Welcome to simple dict server.", 31); - int s = -1; + timerPointerOf(p)->status = -1; ssize_t numbytes = 0; char *buff = calloc(BUFSIZ, sizeof(char)); if(buff) { @@ -316,7 +326,7 @@ void handleAccept(void *p) { buff[numbytes] = 0; printf("Get %zd bytes: %s\n", numbytes, buff); puts("Check buffer"); - if(!checkBuffer(accept_fd, &s, buff, numbytes)) break; + if(!checkBuffer(timerPointerOf(p))) break; } printf("Recv %zd bytes\n", numbytes); } else puts("Error allocating buffer"); @@ -350,7 +360,7 @@ void acceptClient() { FILE *openDict(int lock_type) { FILE *fp = NULL; - fp = fopen(file_path, "rb+"); + fp = fopen(file_path, (lock_type == LOCK_SH)?"rb":"rb+"); if(fp) { if(!~flock(fileno(fp), lock_type | LOCK_NB)) { printf("Error: ");