local interface polishing, clean up;
This commit is contained in:
parent
39d8ea845c
commit
747f30df68
@ -1,29 +0,0 @@
|
|||||||
/* ipc.h - UNIX domain socket IPC listener and command processor */
|
|
||||||
#ifndef __IPC_H__
|
|
||||||
#define __IPC_H__
|
|
||||||
|
|
||||||
#include <ilib/config.h>
|
|
||||||
#include <ilib/subscribers.h>
|
|
||||||
#include <ilib/pending.h>
|
|
||||||
|
|
||||||
typedef struct ipc_server {
|
|
||||||
int server_fd;
|
|
||||||
char *socket_path;
|
|
||||||
subrelay_config_t *cfg;
|
|
||||||
subscriber_pool_t *subscribers;
|
|
||||||
pending_pool_t *pending;
|
|
||||||
} ipc_server_t;
|
|
||||||
|
|
||||||
/* Initialize non-blocking UNIX domain socket server */
|
|
||||||
int ipc_server_init(ipc_server_t *server,
|
|
||||||
subrelay_config_t *cfg,
|
|
||||||
subscriber_pool_t *subscribers,
|
|
||||||
pending_pool_t *pending);
|
|
||||||
|
|
||||||
/* Non-blocking check for incoming client commands from subrelay-shell */
|
|
||||||
int ipc_server_poll(ipc_server_t *server);
|
|
||||||
|
|
||||||
/* Cleanup socket file and close descriptors */
|
|
||||||
void ipc_server_destroy(ipc_server_t *server);
|
|
||||||
|
|
||||||
#endif /* __IPC_H__ */
|
|
||||||
47
include/ilib/local.h
Normal file
47
include/ilib/local.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* this is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* local.h: local interface to maillist (UNIX socket)
|
||||||
|
*/
|
||||||
|
#ifndef __LOCAL_H__
|
||||||
|
#define __LOCAL_H__
|
||||||
|
|
||||||
|
#include <ilib/config.h>
|
||||||
|
#include <ilib/subscribers.h>
|
||||||
|
#include <ilib/pending.h>
|
||||||
|
|
||||||
|
typedef struct local_ctrl {
|
||||||
|
int server_fd;
|
||||||
|
char *socket_path;
|
||||||
|
subrelay_config_t *cfg;
|
||||||
|
subscriber_pool_t *subscribers;
|
||||||
|
pending_pool_t *pending;
|
||||||
|
} local_ctrl_t;
|
||||||
|
|
||||||
|
/* Initialize non-blocking UNIX domain socket server */
|
||||||
|
int local_ctrl_init(local_ctrl_t *server,
|
||||||
|
subrelay_config_t *cfg,
|
||||||
|
subscriber_pool_t *subscribers,
|
||||||
|
pending_pool_t *pending);
|
||||||
|
|
||||||
|
/* Non-blocking check for incoming client commands from subrelay-shell */
|
||||||
|
int local_ctrl_poll(local_ctrl_t *server);
|
||||||
|
|
||||||
|
/* Cleanup socket file and close descriptors */
|
||||||
|
void local_ctrl_destroy(local_ctrl_t *server);
|
||||||
|
|
||||||
|
#endif /* __LOCAL_H__ */
|
||||||
@ -1,4 +1,23 @@
|
|||||||
/* ipc.c - UNIX domain socket ASCII command listener */
|
/*
|
||||||
|
* this is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* local.c: local interface to maillist (UNIX socket)
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -11,7 +30,10 @@
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <ilib/ipc.h>
|
#include <ilib/local.h>
|
||||||
|
|
||||||
|
#define OUTBUF_MAX 2048
|
||||||
|
#define EMAILLEN_MAX 512
|
||||||
|
|
||||||
static char *trim(char *str)
|
static char *trim(char *str)
|
||||||
{
|
{
|
||||||
@ -25,78 +47,56 @@ static char *trim(char *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse and dispatch ASCII commands from subrelay-shell */
|
/* dispatch requests from local control tool */
|
||||||
static void handle_ipc_command(ipc_server_t *server, int client_fd, char *cmd_line)
|
static void handle_ipc_command(local_ctrl_t *server, int client_fd, char *cmd_line)
|
||||||
{
|
{
|
||||||
char *line = trim(cmd_line);
|
char *line = trim(cmd_line);
|
||||||
if (*line == '\0') return;
|
if (*line == '\0') return;
|
||||||
|
|
||||||
char *cmd = strtok(line, " \t");
|
char *cmd = strtok(line, " \t");
|
||||||
char *arg = strtok(NULL, " \t");
|
char *arg = strtok(NULL, " \t");
|
||||||
|
ssize_t wrt = 0;
|
||||||
char response[2048];
|
char response[OUTBUF_MAX];
|
||||||
|
int rc;
|
||||||
response[0] = '\0';
|
response[0] = '\0';
|
||||||
|
|
||||||
if (!cmd) {
|
if (!cmd) snprintf(response, sizeof(response), "ERR invalid command\n");
|
||||||
snprintf(response, sizeof(response), "ERR invalid_command\n");
|
else if (strcasecmp(cmd, "ADD") == 0) { /* ADD <email> - add email to subscribers list */
|
||||||
}
|
if (!arg) snprintf(response, sizeof(response), "ERR missing argument\n");
|
||||||
/* ---------------------------------------------------------------------- */
|
else {
|
||||||
/* Command: ADD <email> (Directly subscribe address, bypasses opt-in) */
|
rc = subscriber_add(server->subscribers, arg);
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
else if (strcasecmp(cmd, "ADD") == 0) {
|
|
||||||
if (!arg) {
|
|
||||||
snprintf(response, sizeof(response), "ERR missing_email_argument\n");
|
|
||||||
} else {
|
|
||||||
int rc = subscriber_add(server->subscribers, arg);
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
subscriber_save_file(server->subscribers);
|
subscriber_save_file(server->subscribers);
|
||||||
snprintf(response, sizeof(response), "OK subscriber_added %s\n", arg);
|
snprintf(response, sizeof(response), "OK subscription added for: %s\n", arg);
|
||||||
} else if (rc == -EEXIST) {
|
} else if (rc == -EEXIST) snprintf(response,
|
||||||
snprintf(response, sizeof(response), "ERR subscriber_already_exists\n");
|
sizeof(response), "ERR subscriber already exists\n");
|
||||||
} else {
|
else snprintf(response, sizeof(response), "ERR failed to add subscriber\n");
|
||||||
snprintf(response, sizeof(response), "ERR failed_to_add_subscriber\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else if (strcasecmp(cmd, "DEL") == 0) { /* DEL <email> - remove email from list */
|
||||||
/* ---------------------------------------------------------------------- */
|
if (!arg) snprintf(response, sizeof(response), "ERR missing argument\n");
|
||||||
/* Command: DEL <email> (Directly unsubscribe address) */
|
else {
|
||||||
/* ---------------------------------------------------------------------- */
|
rc = subscriber_remove(server->subscribers, arg);
|
||||||
else if (strcasecmp(cmd, "DEL") == 0) {
|
|
||||||
if (!arg) {
|
|
||||||
snprintf(response, sizeof(response), "ERR missing_email_argument\n");
|
|
||||||
} else {
|
|
||||||
int rc = subscriber_remove(server->subscribers, arg);
|
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
subscriber_save_file(server->subscribers);
|
subscriber_save_file(server->subscribers);
|
||||||
snprintf(response, sizeof(response), "OK subscriber_removed %s\n", arg);
|
snprintf(response, sizeof(response), "OK subscription removed for %s\n", arg);
|
||||||
} else {
|
} else snprintf(response, sizeof(response), "ERR subscriber not found\n");
|
||||||
snprintf(response, sizeof(response), "ERR subscriber_not_found\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
} else if (strcasecmp(cmd, "LIST") == 0) { /* LIST - print list of current subscribers */
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
/* Command: LIST (Output current subscribers) */
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
else if (strcasecmp(cmd, "LIST") == 0) {
|
|
||||||
snprintf(response, sizeof(response), "OK SUBSCRIBERS %lu\n",
|
snprintf(response, sizeof(response), "OK SUBSCRIBERS %lu\n",
|
||||||
(unsigned long)server->subscribers->tree.nodecount);
|
(unsigned long)server->subscribers->tree.nodecount);
|
||||||
write(client_fd, response, strlen(response));
|
wrt = write(client_fd, response, strlen(response));
|
||||||
response[0] = '\0';
|
response[0] = '\0';
|
||||||
|
|
||||||
splay_node_t *curr = splay_first(&server->subscribers->tree);
|
splay_node_t *curr = splay_first(&server->subscribers->tree);
|
||||||
while (curr != NULL) {
|
while (curr != NULL) {
|
||||||
subscriber_entry_t *entry = (subscriber_entry_t *)curr;
|
subscriber_entry_t *entry = (subscriber_entry_t *)curr;
|
||||||
char item[512];
|
char item[EMAILLEN_MAX];
|
||||||
snprintf(item, sizeof(item), "%s\n", entry->email);
|
snprintf(item, sizeof(item), "%s\n", entry->email);
|
||||||
write(client_fd, item, strlen(item));
|
wrt = write(client_fd, item, strlen(item));
|
||||||
curr = splay_next(&server->subscribers->tree, curr);
|
curr = splay_next(&server->subscribers->tree, curr);
|
||||||
}
|
}
|
||||||
snprintf(response, sizeof(response), "END\n");
|
snprintf(response, sizeof(response), "END\n");
|
||||||
}
|
} else if (strcasecmp(cmd, "STATUS") == 0) { /* STATUS - output current stats */
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
/* Command: STATUS (Output system stats & daemon info) */
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
else if (strcasecmp(cmd, "STATUS") == 0) {
|
|
||||||
snprintf(response, sizeof(response),
|
snprintf(response, sizeof(response),
|
||||||
"OK LIST_NAME='%s' ADDRESS='%s' SUBSCRIBERS=%lu PENDING=%lu\n",
|
"OK LIST_NAME='%s' ADDRESS='%s' SUBSCRIBERS=%lu PENDING=%lu\n",
|
||||||
server->cfg->maillist_name,
|
server->cfg->maillist_name,
|
||||||
@ -104,20 +104,21 @@ static void handle_ipc_command(ipc_server_t *server, int client_fd, char *cmd_li
|
|||||||
(unsigned long)server->subscribers->tree.nodecount,
|
(unsigned long)server->subscribers->tree.nodecount,
|
||||||
(unsigned long)server->pending->tree.nodecount);
|
(unsigned long)server->pending->tree.nodecount);
|
||||||
}
|
}
|
||||||
else {
|
else snprintf(response, sizeof(response), "ERR unknown command\n");
|
||||||
snprintf(response, sizeof(response), "ERR unknown_command\n");
|
(void)wrt; /* don't care about how much was written to local socket - not critical */
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(response) > 0) {
|
if (strlen(response) > 0) {
|
||||||
write(client_fd, response, strlen(response));
|
wrt = write(client_fd, response, strlen(response));
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_server_init(ipc_server_t *server, subrelay_config_t *cfg, subscriber_pool_t *subscribers, pending_pool_t *pending)
|
int local_ctrl_init(local_ctrl_t *server, subrelay_config_t *cfg,
|
||||||
|
subscriber_pool_t *subscribers, pending_pool_t *pending)
|
||||||
{
|
{
|
||||||
if (!server || !cfg || !cfg->socket_path) return -EINVAL;
|
if (!server || !cfg || !cfg->socket_path) return -EINVAL;
|
||||||
|
|
||||||
memset(server, 0, sizeof(ipc_server_t));
|
memset(server, 0, sizeof(local_ctrl_t));
|
||||||
server->cfg = cfg;
|
server->cfg = cfg;
|
||||||
server->subscribers = subscribers;
|
server->subscribers = subscribers;
|
||||||
server->pending = pending;
|
server->pending = pending;
|
||||||
@ -155,7 +156,7 @@ int ipc_server_init(ipc_server_t *server, subrelay_config_t *cfg, subscriber_poo
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipc_server_poll(ipc_server_t *server)
|
int local_ctrl_poll(local_ctrl_t *server)
|
||||||
{
|
{
|
||||||
if (!server || server->server_fd < 0) return -EINVAL;
|
if (!server || server->server_fd < 0) return -EINVAL;
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ int ipc_server_poll(ipc_server_t *server)
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[1024];
|
char buf[OUTBUF_MAX];
|
||||||
ssize_t bytes = read(client_fd, buf, sizeof(buf) - 1);
|
ssize_t bytes = read(client_fd, buf, sizeof(buf) - 1);
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
buf[bytes] = '\0';
|
buf[bytes] = '\0';
|
||||||
@ -178,7 +179,7 @@ int ipc_server_poll(ipc_server_t *server)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipc_server_destroy(ipc_server_t *server)
|
void local_ctrl_destroy(local_ctrl_t *server)
|
||||||
{
|
{
|
||||||
if (!server) return;
|
if (!server) return;
|
||||||
|
|
||||||
@ -191,5 +192,5 @@ void ipc_server_destroy(ipc_server_t *server)
|
|||||||
free(server->socket_path);
|
free(server->socket_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(server, 0, sizeof(ipc_server_t));
|
memset(server, 0, sizeof(local_ctrl_t));
|
||||||
}
|
}
|
||||||
@ -1,4 +1,23 @@
|
|||||||
/* src/subrelayd/main.c - Main daemon process */
|
/*
|
||||||
|
* this is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published
|
||||||
|
* by the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* this is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2026 <alex@vapaa.xyz>
|
||||||
|
* subrelay: a minimalistic maillist server based on external IMAPs/SMTPs
|
||||||
|
*
|
||||||
|
* subrelayd.c: maillist daemon - main entry
|
||||||
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#define _BSD_SOURCE
|
#define _BSD_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -16,7 +35,7 @@
|
|||||||
#include <ilib/pending.h>
|
#include <ilib/pending.h>
|
||||||
#include <ilib/mail_engine.h>
|
#include <ilib/mail_engine.h>
|
||||||
#include <ilib/mail_processor.h>
|
#include <ilib/mail_processor.h>
|
||||||
#include <ilib/ipc.h>
|
#include <ilib/local.h>
|
||||||
|
|
||||||
static volatile int running = 1;
|
static volatile int running = 1;
|
||||||
|
|
||||||
@ -62,25 +81,37 @@ static void print_usage(const char *progname)
|
|||||||
{
|
{
|
||||||
printf("Usage: %s -c <config_file> [-d]\n", progname);
|
printf("Usage: %s -c <config_file> [-d]\n", progname);
|
||||||
printf(" -c <path> Path to subrelay configuration file\n");
|
printf(" -c <path> Path to subrelay configuration file\n");
|
||||||
printf(" -d Run in foreground/debug mode\n");
|
printf(" -f Run in foreground mode\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *config_path = NULL;
|
char *config_path = NULL;
|
||||||
int debug_mode = 0;
|
int foreground_mode = 0;
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "c:d")) != -1) {
|
|
||||||
switch (opt) {
|
while(1) {
|
||||||
|
int option_index = 0;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"config-file", required_argument, NULL, 'c'},
|
||||||
|
{"foreground", no_argument, NULL, 'f'},
|
||||||
|
{NULL, 0, NULL, 0},
|
||||||
|
};
|
||||||
|
|
||||||
|
if((opt = getopt_long(argc, argv, "hc:f", long_options, &option_index)) == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch(opt) {
|
||||||
|
case 'h': print_usage(argv[0]); return 0; break;
|
||||||
case 'c': config_path = optarg; break;
|
case 'c': config_path = optarg; break;
|
||||||
case 'd': debug_mode = 1; break;
|
case 'f': foreground_mode = 1; break;
|
||||||
default: print_usage(argv[0]); return EXIT_FAILURE;
|
default: print_usage(argv[0]); return EXIT_FAILURE; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config_path) {
|
if (!config_path) {
|
||||||
fprintf(stderr, "error: configuration file required (-c <config_path>)\n");
|
fprintf(stderr, "error: configuration file required (-c <config_file>)\n");
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -121,8 +152,8 @@ int main(int argc, char **argv)
|
|||||||
pending_load_file(&pending);
|
pending_load_file(&pending);
|
||||||
|
|
||||||
/* 3. Initialize IPC Socket Server */
|
/* 3. Initialize IPC Socket Server */
|
||||||
ipc_server_t ipc;
|
local_ctrl_t ipc;
|
||||||
if (ipc_server_init(&ipc, &cfg, &subscribers, &pending) != 0) {
|
if (local_ctrl_init(&ipc, &cfg, &subscribers, &pending) != 0) {
|
||||||
fprintf(stderr, "error: failed to bind IPC socket '%s'\n", cfg.socket_path);
|
fprintf(stderr, "error: failed to bind IPC socket '%s'\n", cfg.socket_path);
|
||||||
pending_pool_destroy(&pending);
|
pending_pool_destroy(&pending);
|
||||||
subscriber_pool_destroy(&subscribers);
|
subscriber_pool_destroy(&subscribers);
|
||||||
@ -133,7 +164,7 @@ int main(int argc, char **argv)
|
|||||||
/* 4. Drop Root Privileges */
|
/* 4. Drop Root Privileges */
|
||||||
if (drop_privileges(cfg.run_user, cfg.run_group) != 0) {
|
if (drop_privileges(cfg.run_user, cfg.run_group) != 0) {
|
||||||
fprintf(stderr, "error: failed to drop privileges\n");
|
fprintf(stderr, "error: failed to drop privileges\n");
|
||||||
ipc_server_destroy(&ipc);
|
local_ctrl_destroy(&ipc);
|
||||||
pending_pool_destroy(&pending);
|
pending_pool_destroy(&pending);
|
||||||
subscriber_pool_destroy(&subscribers);
|
subscriber_pool_destroy(&subscribers);
|
||||||
config_free(&cfg);
|
config_free(&cfg);
|
||||||
@ -143,7 +174,7 @@ int main(int argc, char **argv)
|
|||||||
/* 5. Initialize Network Engine */
|
/* 5. Initialize Network Engine */
|
||||||
if (mail_engine_global_init() != 0) {
|
if (mail_engine_global_init() != 0) {
|
||||||
fprintf(stderr, "error: failed to initialize libcurl global context\n");
|
fprintf(stderr, "error: failed to initialize libcurl global context\n");
|
||||||
ipc_server_destroy(&ipc);
|
local_ctrl_destroy(&ipc);
|
||||||
pending_pool_destroy(&pending);
|
pending_pool_destroy(&pending);
|
||||||
subscriber_pool_destroy(&subscribers);
|
subscriber_pool_destroy(&subscribers);
|
||||||
config_free(&cfg);
|
config_free(&cfg);
|
||||||
@ -153,7 +184,7 @@ int main(int argc, char **argv)
|
|||||||
mail_processor_t processor;
|
mail_processor_t processor;
|
||||||
mail_processor_init(&processor, &cfg, &subscribers, &pending);
|
mail_processor_init(&processor, &cfg, &subscribers, &pending);
|
||||||
|
|
||||||
if (!debug_mode) {
|
if (!foreground_mode) {
|
||||||
if (daemon(0, 0) != 0) {
|
if (daemon(0, 0) != 0) {
|
||||||
fprintf(stderr, "error: failed to daemonize\n");
|
fprintf(stderr, "error: failed to daemonize\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -165,7 +196,7 @@ int main(int argc, char **argv)
|
|||||||
/* 6. Main Operational Daemon Loop */
|
/* 6. Main Operational Daemon Loop */
|
||||||
while (running) {
|
while (running) {
|
||||||
/* Check local UNIX socket for subrelay-shell IPC commands */
|
/* Check local UNIX socket for subrelay-shell IPC commands */
|
||||||
ipc_server_poll(&ipc);
|
local_ctrl_poll(&ipc);
|
||||||
|
|
||||||
/* Poll remote IMAP server for unseen messages */
|
/* Poll remote IMAP server for unseen messages */
|
||||||
mail_list_results_t unseen;
|
mail_list_results_t unseen;
|
||||||
@ -195,7 +226,7 @@ int main(int argc, char **argv)
|
|||||||
pending_save_file(&pending);
|
pending_save_file(&pending);
|
||||||
|
|
||||||
mail_engine_global_cleanup();
|
mail_engine_global_cleanup();
|
||||||
ipc_server_destroy(&ipc);
|
local_ctrl_destroy(&ipc);
|
||||||
pending_pool_destroy(&pending);
|
pending_pool_destroy(&pending);
|
||||||
subscriber_pool_destroy(&subscribers);
|
subscriber_pool_destroy(&subscribers);
|
||||||
config_free(&cfg);
|
config_free(&cfg);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user