mirror of
https://github.com/fumiama/simple-kanban.git
synced 2026-06-30 16:10:26 +08:00
优化代码结构
This commit is contained in:
@@ -10,16 +10,16 @@ endif()
|
|||||||
|
|
||||||
add_definitions(-DLISTEN_ON_IPV6)
|
add_definitions(-DLISTEN_ON_IPV6)
|
||||||
|
|
||||||
# include_directories("/usr/local/include")
|
include_directories("/usr/local/include")
|
||||||
# link_directories("/usr/local/lib")
|
link_directories("/usr/local/lib")
|
||||||
|
|
||||||
add_executable(simple-kanban server.c)
|
add_executable(simple-kanban server.c)
|
||||||
add_executable(simple-kanban-client client.c)
|
add_executable(simple-kanban-client client.c)
|
||||||
add_executable(cfgwriter cfgwriter.c)
|
add_executable(cfgwriter cfgwriter.c)
|
||||||
|
|
||||||
target_link_libraries(simple-kanban spb pthread)
|
target_link_libraries(simple-kanban libspb.a pthread)
|
||||||
target_link_libraries(simple-kanban-client pthread)
|
target_link_libraries(simple-kanban-client pthread)
|
||||||
target_link_libraries(cfgwriter spb)
|
target_link_libraries(cfgwriter libspb.a)
|
||||||
|
|
||||||
INSTALL(TARGETS simple-kanban RUNTIME DESTINATION bin)
|
INSTALL(TARGETS simple-kanban RUNTIME DESTINATION bin)
|
||||||
INSTALL(TARGETS simple-kanban-client RUNTIME DESTINATION bin)
|
INSTALL(TARGETS simple-kanban-client RUNTIME DESTINATION bin)
|
||||||
|
|||||||
10
cfgwriter.c
10
cfgwriter.c
@@ -3,17 +3,17 @@
|
|||||||
#include <simple_protobuf.h>
|
#include <simple_protobuf.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
CONFIG cfg;
|
config_t cfg;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
printf("Enter a password: ");
|
printf("Enter a password: ");
|
||||||
scanf("%s", cfg.pwd);
|
scanf("%s", cfg.pwd);
|
||||||
printf("Enter a set password: ");
|
printf("Enter a set password: ");
|
||||||
scanf("%s", cfg.sps);
|
scanf("%s", cfg.sps);
|
||||||
uint32_t* types_len = align_struct(sizeof(CONFIG), 2, &cfg.pwd, &cfg.sps);
|
uint32_t* types_len = align_struct(sizeof(config_t), 2, &cfg.pwd, &cfg.sps);
|
||||||
FILE* fp = fopen("cfg.sp", "wb");
|
FILE* fp = fopen("cfg.sp", "wb");
|
||||||
if(fp) {
|
if(fp) {
|
||||||
set_pb(fp, types_len, sizeof(CONFIG), &cfg);
|
set_pb(fp, types_len, sizeof(config_t), &cfg);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
puts("Config is saved to cfg.sp.");
|
puts("Config is saved to cfg.sp.");
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
@@ -21,8 +21,8 @@ int main() {
|
|||||||
fp = fopen("cfg.sp", "rb");
|
fp = fopen("cfg.sp", "rb");
|
||||||
if(fp) {
|
if(fp) {
|
||||||
SIMPLE_PB* spb = get_pb(fp);
|
SIMPLE_PB* spb = get_pb(fp);
|
||||||
memset(&cfg, 0, sizeof(CONFIG));
|
memset(&cfg, 0, sizeof(config_t));
|
||||||
memcpy(&cfg, spb->target, sizeof(CONFIG));
|
memcpy(&cfg, spb->target, sizeof(config_t));
|
||||||
printf("set pwd: %s, sps: %s\n", cfg.pwd, cfg.sps);
|
printf("set pwd: %s, sps: %s\n", cfg.pwd, cfg.sps);
|
||||||
} else perror("[SPB]");
|
} else perror("[SPB]");
|
||||||
} else perror("[SPB]");
|
} else perror("[SPB]");
|
||||||
|
|||||||
4
config.h
4
config.h
@@ -1,10 +1,10 @@
|
|||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
struct CONFIG {
|
struct config_t {
|
||||||
char pwd[64]; //password
|
char pwd[64]; //password
|
||||||
char sps[64]; //set password
|
char sps[64]; //set password
|
||||||
};
|
};
|
||||||
typedef struct CONFIG CONFIG;
|
typedef struct config_t config_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
252
server.c
252
server.c
@@ -4,6 +4,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <simple_protobuf.h>
|
#include <simple_protobuf.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
#include <machine/endian.h>
|
#include <machine/endian.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static CONFIG* cfg; // 存储 pwd 和 sps
|
static config_t* cfg; // 存储 pwd 和 sps
|
||||||
|
|
||||||
static int fd; // server socket fd
|
static int fd; // server socket fd
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ static pthread_attr_t attr;
|
|||||||
// accept_timer 使用的结构体
|
// accept_timer 使用的结构体
|
||||||
// 包含了本次 accept 的全部信息
|
// 包含了本次 accept 的全部信息
|
||||||
// 以方便退出后清理空间
|
// 以方便退出后清理空间
|
||||||
struct THREADTIMER {
|
struct threadtimer_t {
|
||||||
int index; // 指向 accept_threads 某个槽位的下标
|
int index; // 指向 accept_threads 某个槽位的下标
|
||||||
time_t touch; // 最后访问时间,与当前时间差超过 MAXWAITSEC 将由 timer 强行回收线程
|
time_t touch; // 最后访问时间,与当前时间差超过 MAXWAITSEC 将由 timer 强行回收线程
|
||||||
int accept_fd; // 本次 accept 的 fd,会自行关闭或出错时由 timer 负责回收
|
int accept_fd; // 本次 accept 的 fd,会自行关闭或出错时由 timer 负责回收
|
||||||
@@ -59,30 +60,29 @@ struct THREADTIMER {
|
|||||||
FILE *fp; // 本会话打开的文件,会自行关闭或出错时由 timer 负责回收
|
FILE *fp; // 本会话打开的文件,会自行关闭或出错时由 timer 负责回收
|
||||||
char data[TIMERDATSZ];
|
char data[TIMERDATSZ];
|
||||||
};
|
};
|
||||||
typedef struct THREADTIMER THREADTIMER;
|
typedef struct threadtimer_t threadtimer_t;
|
||||||
|
|
||||||
#define showUsage(program) printf("Usage: %s [-d] listen_port try_times kanban_file data_file config_file\n\t-d: As daemon\n", program)
|
#define show_usage(program) printf("Usage: %s [-d] listen_port kanban_file data_file config_file\n\t-d: As daemon\n", program)
|
||||||
|
|
||||||
static void accept_client();
|
static void accept_client();
|
||||||
static void accept_timer(void *p);
|
static void accept_timer(void *p);
|
||||||
static int bind_server(uint16_t port, int try_times);
|
static int bind_server(uint16_t port);
|
||||||
static int check_buffer(THREADTIMER *timer);
|
static int check_buffer(threadtimer_t *timer);
|
||||||
static void clean_timer(THREADTIMER* timer);
|
static void clean_timer(threadtimer_t* timer);
|
||||||
static void close_file(FILE *fp);
|
static void close_file(FILE *fp);
|
||||||
static int close_file_and_send(THREADTIMER *timer, char *data, size_t numbytes);
|
static int close_file_and_send(threadtimer_t *timer, char *data, size_t numbytes);
|
||||||
|
static void exit_thread(int signo);
|
||||||
static void handle_accept(void *accept_fd_p);
|
static void handle_accept(void *accept_fd_p);
|
||||||
static void handle_pipe(int signo);
|
static int listen_socket();
|
||||||
static void handle_quit(int signo);
|
|
||||||
static int listen_socket(int try_times);
|
|
||||||
static FILE *open_file(char* file_path, int lock_type, char* mode);
|
static FILE *open_file(char* file_path, int lock_type, char* mode);
|
||||||
static int send_all(char* file_path, THREADTIMER *timer);
|
static int send_all(char* file_path, threadtimer_t *timer);
|
||||||
static int send_data(int accept_fd, char *data, size_t length);
|
static int send_data(int accept_fd, char *data, size_t length);
|
||||||
static off_t size_of_file(const char* fname);
|
static off_t size_of_file(const char* fname);
|
||||||
static int sm1_pwd(THREADTIMER *timer);
|
static int sm1_pwd(threadtimer_t *timer);
|
||||||
static int s0_init(THREADTIMER *timer);
|
static int s0_init(threadtimer_t *timer);
|
||||||
static int s1_get(THREADTIMER *timer);
|
static int s1_get(threadtimer_t *timer);
|
||||||
static int s2_set(THREADTIMER *timer);
|
static int s2_set(threadtimer_t *timer);
|
||||||
static int s3_set_data(THREADTIMER *timer);
|
static int s3_set_data(threadtimer_t *timer);
|
||||||
|
|
||||||
static pid_t pid;
|
static pid_t pid;
|
||||||
/***************************************
|
/***************************************
|
||||||
@@ -102,13 +102,11 @@ static void accept_client() {
|
|||||||
puts("Server subprocess exited. Restart...");
|
puts("Server subprocess exited. Restart...");
|
||||||
pid = fork();
|
pid = fork();
|
||||||
}
|
}
|
||||||
signal(SIGQUIT, handle_quit);
|
|
||||||
signal(SIGPIPE, handle_pipe);
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
if(pid < 0) puts("Error when forking a subprocess.");
|
if(pid < 0) puts("Error when forking a subprocess.");
|
||||||
else while(1) {
|
else while(1) {
|
||||||
puts("Ready for accept, waitting...");
|
puts("\nReady for accept, waitting...");
|
||||||
int p = 0;
|
int p = 0;
|
||||||
while(p < THREADCNT && accept_threads[p] && !pthread_kill(accept_threads[p], 0)) p++;
|
while(p < THREADCNT && accept_threads[p] && !pthread_kill(accept_threads[p], 0)) p++;
|
||||||
if(p >= THREADCNT) {
|
if(p >= THREADCNT) {
|
||||||
@@ -117,7 +115,7 @@ static void accept_client() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf("Next thread is No.%d\n", p);
|
printf("Next thread is No.%d\n", p);
|
||||||
THREADTIMER *timer = malloc(sizeof(THREADTIMER));
|
threadtimer_t *timer = malloc(sizeof(threadtimer_t));
|
||||||
if(!timer) {
|
if(!timer) {
|
||||||
puts("Allocate timer error");
|
puts("Allocate timer error");
|
||||||
continue;
|
continue;
|
||||||
@@ -149,7 +147,7 @@ static void accept_client() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define timer_ptr(x) ((THREADTIMER*)(x))
|
#define timer_ptr(x) ((threadtimer_t*)(x))
|
||||||
#define my_thread(timer) accept_threads[timer->index]
|
#define my_thread(timer) accept_threads[timer->index]
|
||||||
/***************************************
|
/***************************************
|
||||||
* accept_timer 是与 handle_accept 伴生的
|
* accept_timer 是与 handle_accept 伴生的
|
||||||
@@ -163,11 +161,10 @@ static void accept_timer(void *p) {
|
|||||||
if(waitsec > MAXWAITSEC) break;
|
if(waitsec > MAXWAITSEC) break;
|
||||||
}
|
}
|
||||||
clean_timer(timer_ptr(p));
|
clean_timer(timer_ptr(p));
|
||||||
free(p); // 唯一 free 点
|
|
||||||
puts("Timer has been freed");
|
puts("Timer has been freed");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bind_server(uint16_t port, int try_times) {
|
static int bind_server(uint16_t port) {
|
||||||
int fail_count = 0;
|
int fail_count = 0;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
#ifdef LISTEN_ON_IPV6
|
#ifdef LISTEN_ON_IPV6
|
||||||
@@ -182,21 +179,15 @@ static int bind_server(uint16_t port, int try_times) {
|
|||||||
bzero(&(server_addr.sin_zero), 8);
|
bzero(&(server_addr.sin_zero), 8);
|
||||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
#endif
|
#endif
|
||||||
while(!~(result = bind(fd, (struct sockaddr *)&server_addr, struct_len)) && fail_count++ < try_times) sleep(1);
|
if(!~bind(fd, (struct sockaddr *)&server_addr, struct_len)) return 1;
|
||||||
if(!~result && fail_count >= try_times) {
|
return 0;
|
||||||
puts("Bind server failure!");
|
|
||||||
return 0;
|
|
||||||
} else{
|
|
||||||
puts("Bind server success!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
* check_buffer 检查接收到的数据,结合
|
* check_buffer 检查接收到的数据,结合
|
||||||
* 当前会话所处状态决定接下来的处理流程
|
* 当前会话所处状态决定接下来的处理流程
|
||||||
***************************************/
|
***************************************/
|
||||||
static int check_buffer(THREADTIMER *timer) {
|
static int check_buffer(threadtimer_t *timer) {
|
||||||
printf("Status: %d\n", (int)timer->status);
|
printf("Status: %d\n", (int)timer->status);
|
||||||
switch(timer->status) {
|
switch(timer->status) {
|
||||||
case -1: return sm1_pwd(timer); break;
|
case -1: return sm1_pwd(timer); break;
|
||||||
@@ -209,7 +200,7 @@ static int check_buffer(THREADTIMER *timer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// clean_timer 清理 timer
|
// clean_timer 清理 timer
|
||||||
static void clean_timer(THREADTIMER* timer) {
|
static void clean_timer(threadtimer_t* timer) {
|
||||||
puts("Start cleaning.");
|
puts("Start cleaning.");
|
||||||
if(my_thread(timer)) {
|
if(my_thread(timer)) {
|
||||||
pthread_kill(my_thread(timer), SIGQUIT);
|
pthread_kill(my_thread(timer), SIGQUIT);
|
||||||
@@ -226,6 +217,7 @@ static void clean_timer(THREADTIMER* timer) {
|
|||||||
timer->accept_fd = 0;
|
timer->accept_fd = 0;
|
||||||
puts("Close accept.");
|
puts("Close accept.");
|
||||||
}
|
}
|
||||||
|
free(timer);
|
||||||
puts("Finish cleaning.");
|
puts("Finish cleaning.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +229,7 @@ static void close_file(FILE *fp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int close_file_and_send(THREADTIMER *timer, char *data, size_t numbytes) {
|
static int close_file_and_send(threadtimer_t *timer, char *data, size_t numbytes) {
|
||||||
close_file(timer->fp);
|
close_file(timer->fp);
|
||||||
timer->is_open = 0;
|
timer->is_open = 0;
|
||||||
return send_data(timer->accept_fd, data, numbytes);
|
return send_data(timer->accept_fd, data, numbytes);
|
||||||
@@ -262,58 +254,52 @@ static int close_file_and_send(THREADTIMER *timer, char *data, size_t numbytes)
|
|||||||
#define my_dat(x) (timer_ptr(x)->data)
|
#define my_dat(x) (timer_ptr(x)->data)
|
||||||
// handle_accept 初步解析指令,处理部分粘连
|
// handle_accept 初步解析指令,处理部分粘连
|
||||||
static void handle_accept(void *p) {
|
static void handle_accept(void *p) {
|
||||||
if(my_fd(p) > 0) {
|
puts("Connected to the client.");
|
||||||
puts("Connected to the client.");
|
signal(SIGQUIT, exit_thread);
|
||||||
signal(SIGQUIT, handle_quit);
|
signal(SIGPIPE, exit_thread);
|
||||||
signal(SIGPIPE, handle_pipe);
|
pthread_t thread;
|
||||||
pthread_t thread;
|
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) {
|
||||||
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) puts("Error creating timer thread");
|
puts("Error creating timer thread");
|
||||||
else puts("Creating timer thread succeeded");
|
close(my_fd(p));
|
||||||
send_data(my_fd(p), "Welcome to simple kanban server.", 33);
|
free(p);
|
||||||
timer_ptr(p)->status = -1;
|
return;
|
||||||
while(my_thread(timer_ptr(p)) && (timer_ptr(p)->numbytes = recv(my_fd(p), my_dat(p), TIMERDATSZ, 0)) > 0) {
|
}
|
||||||
touch_timer(p);
|
puts("Creating timer thread succeeded");
|
||||||
my_dat(p)[timer_ptr(p)->numbytes] = 0;
|
pthread_cleanup_push((void*)clean_timer, p);
|
||||||
printf("Get %d bytes: %s\n", (int)timer_ptr(p)->numbytes, my_dat(p));
|
send_data(my_fd(p), "Welcome to simple kanban server.", 33);
|
||||||
puts("Check buffer");
|
timer_ptr(p)->status = -1;
|
||||||
//处理部分粘连
|
while(my_thread(timer_ptr(p)) && (timer_ptr(p)->numbytes = recv(my_fd(p), my_dat(p), TIMERDATSZ, 0)) > 0) {
|
||||||
take_word(p, cfg->pwd, my_dat(p));
|
touch_timer(p);
|
||||||
take_word(p, "get", my_dat(p));
|
my_dat(p)[timer_ptr(p)->numbytes] = 0;
|
||||||
take_word(p, "set", my_dat(p));
|
printf("Get %d bytes: %s\n", (int)timer_ptr(p)->numbytes, my_dat(p));
|
||||||
take_word(p, "cat", my_dat(p));
|
puts("Check buffer");
|
||||||
take_word(p, "quit", my_dat(p));
|
//处理部分粘连
|
||||||
take_word(p, cfg->sps, my_dat(p));
|
take_word(p, cfg->pwd, my_dat(p));
|
||||||
take_word(p, "ver", my_dat(p));
|
take_word(p, "get", my_dat(p));
|
||||||
take_word(p, "dat", my_dat(p));
|
take_word(p, "set", my_dat(p));
|
||||||
if(timer_ptr(p)->numbytes > 0) chkbuf(p);
|
take_word(p, "cat", my_dat(p));
|
||||||
}
|
take_word(p, "quit", my_dat(p));
|
||||||
printf("Break: recv %d bytes\n", (int)timer_ptr(p)->numbytes);
|
take_word(p, cfg->sps, my_dat(p));
|
||||||
my_thread(timer_ptr(p)) = 0;
|
take_word(p, "ver", my_dat(p));
|
||||||
clean_timer(timer_ptr(p));
|
take_word(p, "dat", my_dat(p));
|
||||||
} else puts("Error accepting client");
|
if(timer_ptr(p)->numbytes > 0) chkbuf(p);
|
||||||
|
}
|
||||||
|
printf("Break: recv %d bytes\n", (int)timer_ptr(p)->numbytes);
|
||||||
|
my_thread(timer_ptr(p)) = 0;
|
||||||
|
pthread_cleanup_pop(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_quit(int signo) {
|
static void exit_thread(int signo) {
|
||||||
perror("signal quit");
|
printf("Signal %d", signo);
|
||||||
|
perror("");
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_pipe(int signo) {
|
static int listen_socket() {
|
||||||
perror("signal pipe");
|
|
||||||
pthread_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int listen_socket(int try_times) {
|
|
||||||
int fail_count = 0;
|
int fail_count = 0;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
while(!~(result = listen(fd, 10)) && fail_count++ < try_times) sleep(1);
|
if(!~listen(fd, 10)) return 1;
|
||||||
if(!~result && fail_count >= try_times) {
|
return 0;
|
||||||
puts("Listen failed!");
|
|
||||||
return 0;
|
|
||||||
} else{
|
|
||||||
puts("Listening....");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *open_file(char* file_path, int lock_type, char* mode) {
|
static FILE *open_file(char* file_path, int lock_type, char* mode) {
|
||||||
@@ -329,7 +315,7 @@ static FILE *open_file(char* file_path, int lock_type, char* mode) {
|
|||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_all(char* file_path, THREADTIMER *timer) {
|
static int send_all(char* file_path, threadtimer_t *timer) {
|
||||||
int re = 1;
|
int re = 1;
|
||||||
FILE *fp = open_file(file_path, LOCK_SH, "rb");
|
FILE *fp = open_file(file_path, LOCK_SH, "rb");
|
||||||
if(fp) {
|
if(fp) {
|
||||||
@@ -391,12 +377,12 @@ static off_t size_of_file(const char* fname) {
|
|||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sm1_pwd(THREADTIMER *timer) {
|
static int sm1_pwd(threadtimer_t *timer) {
|
||||||
if(!strcmp(cfg->pwd, timer->data)) timer->status = 0;
|
if(!strcmp(cfg->pwd, timer->data)) timer->status = 0;
|
||||||
return !timer->status;
|
return !timer->status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s0_init(THREADTIMER *timer) {
|
static int s0_init(threadtimer_t *timer) {
|
||||||
if(!strcmp("get", timer->data)) timer->status = 1;
|
if(!strcmp("get", timer->data)) timer->status = 1;
|
||||||
else if(!strcmp(cfg->sps, timer->data)) timer->status = 2;
|
else if(!strcmp(cfg->sps, timer->data)) timer->status = 2;
|
||||||
else if(!strcmp("cat", timer->data)) return send_all(data_path, timer);
|
else if(!strcmp("cat", timer->data)) return send_all(data_path, timer);
|
||||||
@@ -404,7 +390,7 @@ static int s0_init(THREADTIMER *timer) {
|
|||||||
return send_data(timer->accept_fd, timer->data, timer->numbytes);
|
return send_data(timer->accept_fd, timer->data, timer->numbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s1_get(THREADTIMER *timer) { //get kanban
|
static int s1_get(threadtimer_t *timer) { //get kanban
|
||||||
FILE *fp = open_file(kanban_path, LOCK_SH, "rb");
|
FILE *fp = open_file(kanban_path, LOCK_SH, "rb");
|
||||||
timer->status = 0;
|
timer->status = 0;
|
||||||
if(fp) {
|
if(fp) {
|
||||||
@@ -429,7 +415,7 @@ static int s1_get(THREADTIMER *timer) { //get kanban
|
|||||||
return close_file_and_send(timer, "null", 4);
|
return close_file_and_send(timer, "null", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s2_set(THREADTIMER *timer) {
|
static int s2_set(threadtimer_t *timer) {
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
if(!strcmp(timer->data, "ver")) {
|
if(!strcmp(timer->data, "ver")) {
|
||||||
fp = open_file(kanban_path, LOCK_EX, "wb");
|
fp = open_file(kanban_path, LOCK_EX, "wb");
|
||||||
@@ -447,7 +433,7 @@ static int s2_set(THREADTIMER *timer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s3_set_data(THREADTIMER *timer) {
|
static int s3_set_data(threadtimer_t *timer) {
|
||||||
timer->status = 0;
|
timer->status = 0;
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
uint32_t file_size = __builtin_bswap32(*(uint32_t*)(timer->data));
|
uint32_t file_size = __builtin_bswap32(*(uint32_t*)(timer->data));
|
||||||
@@ -494,42 +480,62 @@ static int s3_set_data(THREADTIMER *timer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if(argc != 6 && argc != 7) showUsage(argv[0]);
|
if(argc != 5 && argc != 6) {
|
||||||
else {
|
show_usage(argv[0]);
|
||||||
int port = 0;
|
return 0;
|
||||||
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[as_daemon?3:2], "%d", ×);
|
|
||||||
if(times > 0) {
|
|
||||||
if(!as_daemon || (as_daemon && (daemon(1, 1) >= 0))) {
|
|
||||||
FILE *fp = NULL;
|
|
||||||
fp = fopen(argv[as_daemon?4:3], "rb+");
|
|
||||||
if(!fp) fp = fopen(argv[as_daemon?4:3], "wb+");
|
|
||||||
if(fp) {
|
|
||||||
kanban_path = argv[as_daemon?4:3];
|
|
||||||
fclose(fp);
|
|
||||||
fp = NULL;
|
|
||||||
fp = fopen(argv[as_daemon?5:4], "rb+");
|
|
||||||
if(!fp) fp = fopen(argv[as_daemon?5:4], "wb+");
|
|
||||||
if(fp) {
|
|
||||||
data_path = argv[as_daemon?5:4];
|
|
||||||
fclose(fp);
|
|
||||||
fp = NULL;
|
|
||||||
fp = fopen(argv[as_daemon?6:5], "rb");
|
|
||||||
if(fp) {
|
|
||||||
SIMPLE_PB* spb = get_pb(fp);
|
|
||||||
cfg = (CONFIG*)spb->target;
|
|
||||||
fclose(fp);
|
|
||||||
if(bind_server(port, times)) if(listen_socket(times)) accept_client();
|
|
||||||
} else printf("Error opening config file: %s\n", argv[as_daemon?6:5]);
|
|
||||||
} else printf("Error opening data file: %s\n", argv[as_daemon?5:4]);
|
|
||||||
} else printf("Error opening kanban file: %s\n", argv[as_daemon?4:3]);
|
|
||||||
} else puts("Start daemon error");
|
|
||||||
} else printf("Error times: %d\n", times);
|
|
||||||
} else printf("Error port: %d\n", port);
|
|
||||||
}
|
}
|
||||||
close(fd);
|
int port = 0;
|
||||||
exit(EXIT_FAILURE);
|
int as_daemon = !strcmp("-d", argv[1]);
|
||||||
|
sscanf(argv[as_daemon?2:1], "%d", &port);
|
||||||
|
if(port <= 0 || port >= 65536) {
|
||||||
|
printf("Error port: %d\n", port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(as_daemon && daemon(1, 1) < 0) {
|
||||||
|
perror("Start daemon error");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
FILE *fp = NULL;
|
||||||
|
fp = fopen(argv[as_daemon?3:2], "rb+");
|
||||||
|
if(!fp) fp = fopen(argv[as_daemon?3:2], "wb+");
|
||||||
|
if(!fp) {
|
||||||
|
printf("Error opening kanban file: ");
|
||||||
|
perror(argv[as_daemon?3:2]);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
kanban_path = argv[as_daemon?3:2];
|
||||||
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
|
fp = fopen(argv[as_daemon?4:3], "rb+");
|
||||||
|
if(!fp) fp = fopen(argv[as_daemon?4:3], "wb+");
|
||||||
|
if(!fp) {
|
||||||
|
printf("Error opening data file: ");
|
||||||
|
perror(argv[as_daemon?4:3]);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
data_path = argv[as_daemon?4:3];
|
||||||
|
fclose(fp);
|
||||||
|
fp = NULL;
|
||||||
|
fp = fopen(argv[as_daemon?5:4], "rb");
|
||||||
|
if(!fp) {
|
||||||
|
printf("Error opening config file: ");
|
||||||
|
perror(argv[as_daemon?5:4]);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
SIMPLE_PB* spb = get_pb(fp);
|
||||||
|
cfg = (config_t*)spb->target;
|
||||||
|
fclose(fp);
|
||||||
|
if(bind_server(port)) {
|
||||||
|
perror("Bind server failed");
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
puts("Bind server success!");
|
||||||
|
if(listen_socket()) {
|
||||||
|
perror("Listen failed");
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
pthread_cleanup_push((void*)close, (void*)(uintptr_t)fd);
|
||||||
|
accept_client();
|
||||||
|
pthread_cleanup_pop(1);
|
||||||
|
return 99;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user