Subversion Repositories MLServ

Rev

Rev 5 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 7
Line 1... Line 1...
1
/* $Id: server.c 5 2024-09-25 00:19:35Z nishi $ */
1
/* $Id: server.c 7 2024-09-25 00:56:55Z nishi $ */
2
 
2
 
3
#include "ms_server.h"
3
#include "ms_server.h"
4
 
4
 
5
#include <stdio.h>
5
#include <stdio.h>
6
#include <poll.h>
6
#include <poll.h>
7
#include <sys/un.h>
7
#include <sys/un.h>
8
#include <sys/socket.h>
8
#include <sys/socket.h>
9
#include <signal.h>
9
#include <signal.h>
-
 
10
#include <stdlib.h>
10
#include <unistd.h>
11
#include <unistd.h>
11
#include <string.h>
12
#include <string.h>
-
 
13
#include <stdbool.h>
12
 
14
 
-
 
15
#include <cm_string.h>
13
#include <cm_ipc.h>
16
#include <cm_ipc.h>
14
#include <cm_db.h>
17
#include <cm_db.h>
15
 
18
 
16
#define strsend(sock, str) send(sock, str, strlen(str), 0)
19
#define strsend(sock, str) send(sock, str, strlen(str), 0)
17
 
20
 
18
void ms_handle_socket(int sock) {
21
void ms_handle_socket(int sock) {
19
	sqlite3* db = cm_db_init();
22
	sqlite3* db = cm_db_init();
20
	if(db == NULL) {
23
	if(db == NULL) {
21
		strsend(sock, "* DBERROR\n");
24
		strsend(sock, "DBERROR\n");
22
		return;
25
		return;
23
	}
26
	}
-
 
27
	int bad = 0;
-
 
28
	char* line = malloc(1);
-
 
29
	line[0] = 0;
24
	struct pollfd pollfds[1];
30
	struct pollfd pollfds[1];
25
	pollfds[0].fd = sock;
31
	pollfds[0].fd = sock;
26
	pollfds[0].events = POLLIN | POLLPRI;
32
	pollfds[0].events = POLLIN | POLLPRI;
-
 
33
	strsend(sock, "READY\n");
27
	while(1) {
34
	while(1) {
28
		int ret = poll(pollfds, 1, 1000);
35
		int ret = poll(pollfds, 1, 5000);
29
		if(ret < 0) {
36
		if(ret < 0) {
30
			break;
37
			break;
31
		} else if(ret == 0) {
38
		} else if(ret == 0) {
32
			strsend(sock, "* TIMEOUT\n");
39
			strsend(sock, "TIMEOUT\n");
33
			break;
40
			break;
34
		} else {
41
		} else {
35
			int i;
42
			int i;
36
			char buffer[512];
43
			char buffer[512];
-
 
44
			char cbuf[2];
-
 
45
			cbuf[1] = 0;
37
			int len = recv(sock, buffer, 512, 0);
46
			int len = recv(sock, buffer, 512, 0);
38
			for(i = 0; i < len; i++) {
47
			for(i = 0; i < len; i++) {
-
 
48
				if(buffer[i] == '\n') {
-
 
49
					if(strcmp(line, "BYE") == 0) {
-
 
50
						goto brk;
-
 
51
					} else if(strcmp(line, "LIST-ML") == 0) {
-
 
52
						char** list = cm_list_ml(db);
-
 
53
						if(list != NULL) {
-
 
54
							strsend(sock, "BEGIN\n");
-
 
55
							strsend(sock, "END\n");
-
 
56
							int j;
-
 
57
							for(j = 0; list[j] != NULL; j++) free(list[j]);
-
 
58
							free(list);
-
 
59
						} else {
-
 
60
							strsend(sock, "DBERROR\n");
-
 
61
							goto nobye;
-
 
62
						}
-
 
63
					} else {
-
 
64
						strsend(sock, "SYNERR\n");
-
 
65
						bad++;
-
 
66
					}
-
 
67
					if(bad >= 3) {
-
 
68
						goto brk;
-
 
69
					}
-
 
70
					free(line);
-
 
71
					line = malloc(1);
-
 
72
					line[0] = 0;
-
 
73
				} else if(buffer[i] != '\r') {
-
 
74
					cbuf[0] = buffer[i];
-
 
75
					char* tmp = line;
-
 
76
					line = cm_strcat(tmp, cbuf);
-
 
77
					free(tmp);
-
 
78
				}
39
			}
79
			}
40
		}
80
		}
41
	}
81
	}
-
 
82
brk:
-
 
83
	strsend(sock, "BYE\n");
-
 
84
nobye:
-
 
85
	free(line);
42
	sqlite3_close(db);
86
	sqlite3_close(db);
43
}
87
}
44
 
88
 
45
int ms_handle_server(int argc, char** argv, int start) {
89
int ms_handle_server(int argc, char** argv, int start) {
46
	int sock = cm_ipc_create();
90
	int sock = cm_ipc_create();
Line 56... Line 100...
56
	while(1) {
100
	while(1) {
57
		int ret = poll(pollfds, 1, 1000);
101
		int ret = poll(pollfds, 1, 1000);
58
		if(ret < 0) {
102
		if(ret < 0) {
59
			return 1;
103
			return 1;
60
		} else if(ret == 0) {
104
		} else if(ret == 0) {
-
 
105
 
61
		} else if(ret > 0 && pollfds[0].revents & POLLIN) {
106
		} else if(ret > 0 && pollfds[0].revents & POLLIN) {
62
			struct sockaddr_un claddr;
107
			struct sockaddr_un claddr;
63
			int clen = sizeof(claddr);
108
			int clen = sizeof(claddr);
64
 
109
 
65
			int csock = accept(sock, (struct sockaddr*)&claddr, &clen);
110
			int csock = accept(sock, (struct sockaddr*)&claddr, &clen);
66
			if(csock < 0) return 1;
111
			if(csock < 0) return 1;
67
 
112
 
68
			if(fork() == 0) {
113
			if(fork() == 0) {
69
				strsend(csock, "* READY\n");
-
 
70
				ms_handle_socket(csock);
114
				ms_handle_socket(csock);
71
				close(csock);
115
				close(csock);
72
				_exit(0);
116
				_exit(0);
73
			} else {
117
			} else {
74
				close(csock);
118
				close(csock);