Rev 5 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/* $Id: server.c 7 2024-09-25 00:56:55Z nishi $ */
#include "ms_server.h"
#include <stdio.h>
#include <poll.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <cm_string.h>
#include <cm_ipc.h>
#include <cm_db.h>
#define strsend(sock, str) send(sock, str, strlen(str), 0)
void ms_handle_socket(int sock) {
sqlite3* db = cm_db_init();
if(db == NULL) {
strsend(sock, "DBERROR\n");
return;
}
int bad = 0;
char* line = malloc(1);
line[0] = 0;
struct pollfd pollfds[1];
pollfds[0].fd = sock;
pollfds[0].events = POLLIN | POLLPRI;
strsend(sock, "READY\n");
while(1) {
int ret = poll(pollfds, 1, 5000);
if(ret < 0) {
break;
} else if(ret == 0) {
strsend(sock, "TIMEOUT\n");
break;
} else {
int i;
char buffer[512];
char cbuf[2];
cbuf[1] = 0;
int len = recv(sock, buffer, 512, 0);
for(i = 0; i < len; i++) {
if(buffer[i] == '\n') {
if(strcmp(line, "BYE") == 0) {
goto brk;
} else if(strcmp(line, "LIST-ML") == 0) {
char** list = cm_list_ml(db);
if(list != NULL) {
strsend(sock, "BEGIN\n");
strsend(sock, "END\n");
int j;
for(j = 0; list[j] != NULL; j++) free(list[j]);
free(list);
} else {
strsend(sock, "DBERROR\n");
goto nobye;
}
} else {
strsend(sock, "SYNERR\n");
bad++;
}
if(bad >= 3) {
goto brk;
}
free(line);
line = malloc(1);
line[0] = 0;
} else if(buffer[i] != '\r') {
cbuf[0] = buffer[i];
char* tmp = line;
line = cm_strcat(tmp, cbuf);
free(tmp);
}
}
}
}
brk:
strsend(sock, "BYE\n");
nobye:
free(line);
sqlite3_close(db);
}
int ms_handle_server(int argc, char** argv, int start) {
int sock = cm_ipc_create();
if(sock == -1) {
fprintf(stderr, "Failed to create the socket\n");
}
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
printf("MLServ server ready\n");
struct pollfd pollfds[1];
pollfds[0].fd = sock;
pollfds[0].events = POLLIN | POLLPRI;
while(1) {
int ret = poll(pollfds, 1, 1000);
if(ret < 0) {
return 1;
} else if(ret == 0) {
} else if(ret > 0 && pollfds[0].revents & POLLIN) {
struct sockaddr_un claddr;
int clen = sizeof(claddr);
int csock = accept(sock, (struct sockaddr*)&claddr, &clen);
if(csock < 0) return 1;
if(fork() == 0) {
ms_handle_socket(csock);
close(csock);
_exit(0);
} else {
close(csock);
}
}
}
return 0;
}