diff --git a/server b/server index eb5cd1e..a19e418 100644 Binary files a/server and b/server differ diff --git a/server.c b/server.c index 0a2bf1a..2336162 100644 --- a/server.c +++ b/server.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,19 +16,35 @@ socklen_t struct_len = sizeof(struct sockaddr_in); struct sockaddr_in server_addr; struct sockaddr_in client_addr; char buff[BUFSIZ]; +char buff2[BUFSIZ]; FILE *fp = NULL; +char *file_path; +#define DATASIZE 64 struct DICTBLK{ - char key[255]; + char key[(DATASIZE-1)]; u_char keysize; - char data[255]; + char data[(DATASIZE-1)]; u_char datasize; }; typedef struct DICTBLK DICTBLK; #define DICTBLKSZ sizeof(DICTBLK) DICTBLK dict; -#define showUsage(program) printf("Usage: %s listen_port try_times dict_file\n", program) +#define showUsage(program) printf("Usage: %s [-d] listen_port try_times dict_file\n\t-d: As daemon\n", program) + +void acceptClient(); +int bindServer(uint16_t port, u_int try_times); +int checkBuffer(); +off_t fileSize(const char* fname); +int listenSocket(u_int try_times); +int sendData(char *data, size_t length); +int s0_init(int *s); +int s1_get(int *s); +int s2_set(int *s); +int s3_setData(int *s); +int s4_del(int *s); +int s5_list(int *s); int bindServer(uint16_t port, u_int try_times) { int fail_count = 0; @@ -77,6 +94,7 @@ int s0_init(int *s) { 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("quit", buff)) return 0; return sendData(buff, numbytes); } @@ -97,8 +115,8 @@ int s1_get(int *s) { } #define copyKey() {\ - dict.keysize = (numbytes >= 255)?255:numbytes;\ - strncpy(dict.key, buff, 255);\ + dict.keysize = (numbytes >= (DATASIZE-1))?(DATASIZE-1):numbytes;\ + strncpy(dict.key, buff, (DATASIZE-1));\ } int s2_set(int *s) { @@ -107,7 +125,7 @@ int s2_set(int *s) { while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { u_char ks = dict.keysize; dict.key[ks] = 0; - printf("[%ld] Key size: %d\n", numbytes, ks); + printf("[%zd] Key size: %d\n", numbytes, ks); if(!dict.keysize || !strcmp(buff, dict.key)) { copyKey(); fseek(fp, -DICTBLKSZ, SEEK_CUR); @@ -120,7 +138,7 @@ int s2_set(int *s) { } int s3_setData(int *s) { - dict.datasize = (numbytes >= 255)?255:numbytes; + dict.datasize = (numbytes >= (DATASIZE-1))?(DATASIZE-1):numbytes; memcpy(dict.data, buff, dict.datasize); *s = 0; if(fwrite(&dict, DICTBLKSZ, 1, fp) != 1) { @@ -139,7 +157,7 @@ int s4_del(int *s) { while(fread(&dict, DICTBLKSZ, 1, fp) > 0) { dict.key[dict.keysize] = 0; if(!strcmp(buff, dict.key)) { - fseek(fp, -DICTBLKSZ+255, SEEK_CUR); + fseek(fp, -DICTBLKSZ+(DATASIZE-1), SEEK_CUR); fputc(0, fp); return sendData("succ", 4); } @@ -147,6 +165,33 @@ int s4_del(int *s) { return sendData("null", 4); } +off_t fileSize(const char* fname) { + struct stat statbuf; + if(stat(fname, &statbuf)==0) return statbuf.st_size; + else return -1; +} + +int s5_list(int *s) { + *s = 0; + off_t size = fileSize(file_path) / DICTBLKSZ; + char *keys = calloc(size, DATASIZE); + if(keys) { + rewind(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(strstr(dict.key, buff)) { + strcat(keys, dict.key); + strcat(keys, "\n"); + } + } + int len = strlen(keys); + if(len > 0) return sendData(keys, len); + else return sendData("null", 4); + } else return sendData("erro", 4); +} + int checkBuffer() { static int s = 0; printf("Status: %d\n", s); @@ -156,6 +201,7 @@ int checkBuffer() { case 2: return s2_set(&s); break; case 3: return s3_setData(&s); break; case 4: return s4_del(&s); break; + case 5: return s5_list(&s); break; default: return -1; break; } } @@ -168,31 +214,33 @@ void acceptClient() { sendData("Welcome to simple dict server.", 31); while((numbytes = recv(accept_fd, buff, BUFSIZ, 0)) > 0) { buff[numbytes] = 0; - printf("Get %ld bytes: %s\n", numbytes, buff); + printf("Get %zd bytes: %s\n", numbytes, buff); puts("Check buffer"); if(!checkBuffer()) break; } - fprintf(stderr, "Recv %ld bytes\n", numbytes); + fprintf(stderr, "Recv %zd bytes\n", numbytes); close(accept_fd); } else perror("Error accepting client"); } int main(int argc, char *argv[]) { - if(argc != 4) showUsage(argv[0]); + if(argc != 4 && argc != 5) showUsage(argv[0]); else { int port = 0; - sscanf(argv[1], "%d", &port); + int as_daemon = !strcmp("-d", argv[1]); + sscanf(argv[as_daemon?2:1], "%d", &port); if(port > 0 && port < 65536) { int times = 0; - sscanf(argv[2], "%d", ×); + sscanf(argv[as_daemon?3:2], "%d", ×); if(times > 0) { - if(daemon(1, 1) >= 0) { + if(!as_daemon || (as_daemon && (daemon(1, 1) >= 0))) { fp = NULL; - fp = fopen(argv[3], "rb+"); - if(!fp) fp = fopen(argv[3], "wb+"); + fp = fopen(argv[as_daemon?4:3], "rb+"); + if(!fp) fp = fopen(argv[as_daemon?4:3], "wb+"); if(fp) { + file_path = argv[as_daemon?4:3]; if(bindServer(port, times)) if(listenSocket(times)) while(1) acceptClient(); - } else fprintf(stderr, "Error opening dict file: %s\n", argv[3]); + } else fprintf(stderr, "Error opening dict file: %s\n", argv[as_daemon?4:3]); } else perror("Start daemon error"); } else fprintf(stderr, "Error times: %d\n", times); } else fprintf(stderr, "Error port: %d\n", port);