commit 453651303bf1b056ee6cd1451b33a254b51f0fbe
parent 6ad23c6bbbec7b44d57c9d96fb59e32fff9068b1
Author: Friedel Schön <[email protected]>
Date: Mon, 22 May 2023 23:55:31 +0200
some restructuring
Diffstat:
20 files changed, 458 insertions(+), 464 deletions(-)
diff --git a/include/service.h b/include/service.h
@@ -129,27 +129,26 @@ extern int depends_size;
extern const char* service_dir_path;
-char service_get_command(const char* command);
-int service_command(char command, char extra, const char* service, service_t* response, int response_max);
-int service_handle_command(void* s, sv_command_t command, uint8_t extra, service_t** response);
-int service_pattern(const char* name, service_t** dest, int dest_max);
-int service_refresh(void);
-int service_supervise(const char* service_dir, const char* runlevel, bool force_socket);
+const char* service_status_name(service_t* s);
+void service_decode(service_t* s, const service_serial_t* buffer); // for fsvc
+void service_encode(service_t* s, service_serial_t* buffer); // for fsvs
+void service_encode_runit(service_t* s, service_serial_runit_t* buffer);
service_t* service_get(const char* name);
+void service_handle_client(int client);
+int service_handle_command(void* argv, sv_command_t command, uint8_t extra, service_t** response);
+void service_handle_command_runit(service_t* s, sv_command_runit_t command);
+void service_handle_exit(service_t* s, bool signaled, int return_code);
+void service_init_runit(service_t* s);
+void service_kill(service_t* s, int signal);
+bool service_need_restart(service_t* s);
+int service_pattern(const char* name, service_t** dest, int dest_max);
+int service_refresh_directory(void);
service_t* service_register(int dir, const char* name, bool is_log_service);
-void service_check_state(service_t* s, bool signaled, int return_code);
-void service_handle_socket(int client);
-void service_load(service_t* s, const service_serial_t* buffer); // for fsvc
-void service_send(service_t* s, int signal);
+void service_run(service_t* s);
+int service_send_command(char command, char extra, const char* service, service_t* response, int response_max);
+void service_stage(int stage);
void service_start(service_t* s, bool* changed);
void service_stop(service_t* s, bool* changed);
-void service_store(service_t* s, service_serial_t* buffer); // for fsvs
-void service_store_runit(service_t* s, service_serial_runit_t* buffer);
-const char* service_store_human(service_t* s);
+int service_supervise(const char* service_dir, const char* runlevel, bool force_socket);
void service_update_dependency(service_t* s);
-bool service_need_restart(service_t* s);
-void service_run(service_t* s);
-void service_init_status(service_t* s);
void service_update_status(service_t* s);
-void service_handle_command_runit(service_t* s, sv_command_runit_t command);
-void service_handle_stage(int stage);
diff --git a/src/command.c b/src/command.c
@@ -1,63 +0,0 @@
-#include "service.h"
-#include "util.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-
-const char* command_error[] = {
- [0] = "success",
- [EBADCMD] = "command not found",
- [ENOSV] = "service required",
- [EBADSV] = "no matching services",
- [EBEXT] = "invalid extra"
-};
-
-int service_command(char command, char extra, const char* service, service_t* response, int response_max) {
- char request[2] = { command, extra };
-
- int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sockfd == -1) {
- print_error("error: cannot connect to socket: %s\n");
- exit(1);
- }
-
- struct sockaddr_un addr;
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, sizeof(addr.sun_path), SV_CONTROL_SOCKET, runlevel);
-
- int ret;
- if ((ret = connect(sockfd, (struct sockaddr*) &addr, sizeof(addr))) == -1) {
- print_error("error: cannot connect to %s: %s\n", addr.sun_path);
- exit(EXIT_FAILURE);
- }
-
- write(sockfd, request, sizeof(request));
- writestr(sockfd, service);
-
- int res;
- read(sockfd, &res, 1);
-
- service_serial_t service_buffer;
-
- if (res == 0) {
- if (response) {
- while (res < response_max && readstr(sockfd, response[res].name) > 1) {
- read(sockfd, &service_buffer, sizeof(service_buffer));
- service_load(&response[res], &service_buffer);
- res++;
- }
- }
- } else {
- res *= -1;
- }
-
- close(sockfd);
- return res;
-}
diff --git a/src/config_parser.c b/src/config_parser.c
@@ -1,83 +0,0 @@
-#include "config_parser.h"
-
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-
-void parse_param_file(service_t* s, char* args[]) {
- int param_file;
- int args_size = 0;
- int line_size = 0;
- char c;
-
- strcpy(args[args_size++], "./run");
-
- bool start = true;
- if ((param_file = openat(s->dir, "params", O_RDONLY)) != -1) {
- while (read(param_file, &c, 1) > 0) {
- if (start && c == '%') {
- args_size--;
- continue;
- }
- if (c == '\n') {
- args[args_size++][line_size] = '\0';
-
- line_size = 0;
- } else {
- args[args_size][line_size++] = c;
- }
- start = false;
- }
- if (line_size > 0)
- args[args_size++][line_size] = '\0';
- close(param_file);
- }
-
- args[args_size] = NULL;
-}
-
-void parse_env_file(char** env) {
- int env_file;
- int env_size = 0;
- int line_size = 0;
- char c;
-
- if ((env_file = open("env", O_RDONLY)) != -1) {
- while (read(env_file, &c, 1) > 0) {
- if (c == '\n') {
- env[env_size++][line_size] = '\0';
-
- line_size = 0;
- } else {
- env[env_size][line_size++] = c;
- }
- }
- if (line_size > 0)
- env[env_size++][line_size] = '\0';
- close(env_file);
- }
-
- env[env_size] = NULL;
-}
-
-
-pid_t parse_pid_file(service_t* s) {
- int pid_file;
- if ((pid_file = openat(s->dir, "pid", O_RDONLY)) == -1)
- return 0;
-
- char buffer[SV_PID_BUFFER];
- int n;
- if ((n = read(pid_file, buffer, sizeof(buffer))) <= 0) {
- close(pid_file);
- return 0;
- }
- buffer[n] = '\0';
-
- close(pid_file);
- return atoi(buffer);
-}
diff --git a/src/exec/fsvc.c b/src/exec/fsvc.c
@@ -277,13 +277,13 @@ int main(int argc, char** argv) {
if (check) {
service_t s;
- if ((rc = service_command(command, extra, service, &s, 1)) != 1) {
+ if ((rc = service_send_command(command, extra, service, &s, 1)) != 1) {
printf("error: %s (errno: %d)\n", command_error[-rc], -rc);
return 1;
}
return s.state == STATE_ACTIVE_PID || s.state == STATE_ACTIVE_DUMMY || s.state == STATE_ACTIVE_FOREGROUND || s.state == STATE_ACTIVE_BACKGROUND;
} else {
- rc = service_command(command, extra, service, response, SV_SOCKET_SERVICE_MAX);
+ rc = service_send_command(command, extra, service, response, SV_SOCKET_SERVICE_MAX);
if (rc < 0) {
printf("error: %s (errno: %d)\n", command_error[-rc], -rc);
diff --git a/src/handle_client.c b/src/handle_client.c
@@ -0,0 +1,67 @@
+#include "service.h"
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+void service_handle_client(int client) {
+ char command[2] = { 0, 0 };
+ char service_name[SV_NAME_MAX];
+
+ read(client, command, sizeof(command));
+
+ ssize_t service_len = readstr(client, service_name);
+
+ if (service_len)
+ printf("command issued by user: %c-%02x with service '%s'\n", command[0], command[1], service_name);
+ else
+ printf("command issued by user: %c-%02x without service\n", command[0], command[1]);
+
+ int res = 0;
+ int res_off = 0;
+ service_t* response[SV_SOCKET_SERVICE_MAX];
+ service_t* request[SV_SOCKET_SERVICE_MAX];
+
+ if (service_len > 0) {
+ if (command[0] == S_SWITCH) {
+ res = service_handle_command(service_name, command[0], command[1], response + res_off);
+ } else {
+ int req_size = service_pattern(service_name, request, 128);
+ if (req_size == 0) {
+ res = -EBADSV;
+ goto cleanup;
+ }
+ for (int i = 0; i < req_size; i++) {
+ res = service_handle_command(request[i], command[0], command[1], response + res_off);
+ if (res < 0)
+ goto cleanup;
+ res_off += res;
+ }
+ }
+ } else {
+ res = service_handle_command(NULL, command[0], command[1], response);
+ if (res < 0)
+ goto cleanup;
+
+ res_off = res;
+ }
+
+
+cleanup:
+ if (res < 0) {
+ res *= -1;
+ write(client, &res, 1);
+ goto cleanup;
+ } else {
+ write(client, "", 1);
+ service_serial_t service_buffer;
+
+ for (int i = 0; i < res_off; i++) {
+ service_encode(response[i], &service_buffer);
+ writestr(client, response[i]->name);
+ write(client, &service_buffer, sizeof(service_buffer));
+ }
+ write(client, "", 1);
+ }
+ close(client);
+}
diff --git a/src/command_handler.c b/src/handle_command.c
diff --git a/src/handle_exit.c b/src/handle_exit.c
@@ -0,0 +1,112 @@
+#include "config_parser.h"
+#include "service.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+static void do_finish(service_t* s) {
+ struct stat st;
+ if (fstatat(s->dir, "finish", &st, 0) != -1 && st.st_mode & S_IXUSR) {
+ s->state = STATE_FINISHING;
+ if ((s->pid = fork_dup_cd_exec(s->dir, "./finish", null_fd, null_fd, null_fd)) == -1) {
+ print_error("error: cannot execute ./finish: %s\n");
+ s->state = STATE_INACTIVE;
+ }
+ } else if (s->fail_count == SV_FAIL_MAX) {
+ s->state = STATE_DEAD;
+ printf("%s died\n", s->name);
+ } else {
+ s->state = STATE_INACTIVE;
+ }
+
+ s->status_change = time(NULL);
+ service_update_status(s);
+}
+
+
+void service_handle_exit(service_t* s, bool signaled, int return_code) {
+ s->pid = 0;
+ if (s->restart_file == S_ONCE)
+ s->restart_file = S_DOWN;
+ if (s->restart_manual == S_ONCE)
+ s->restart_manual = S_DOWN;
+
+ struct stat st;
+
+ switch (s->state) {
+ case STATE_SETUP:
+ service_run(s);
+ break;
+ case STATE_ACTIVE_FOREGROUND:
+ if (signaled) {
+ s->last_exit = EXIT_SIGNALED;
+ s->return_code = return_code;
+ s->fail_count++;
+
+ printf("%s killed thought signal %d\n", s->name, s->return_code);
+ } else {
+ s->last_exit = EXIT_NORMAL;
+ s->return_code = return_code;
+ if (s->return_code > 0)
+ s->fail_count++;
+ else
+ s->fail_count = 0;
+
+ printf("%s exited with code %d\n", s->name, s->return_code);
+ }
+
+ do_finish(s);
+
+ break;
+ case STATE_ACTIVE_DUMMY:
+ case STATE_ACTIVE_PID:
+ case STATE_ACTIVE_BACKGROUND:
+ case STATE_STOPPING:
+ do_finish(s);
+ break;
+
+ case STATE_FINISHING:
+ if (s->fail_count == SV_FAIL_MAX) {
+ s->state = STATE_DEAD;
+ printf("%s died\n", s->name);
+ } else {
+ s->state = STATE_INACTIVE;
+ }
+ break;
+ case STATE_STARTING:
+ if (!signaled && return_code == 0) {
+ if (fstatat(s->dir, "stop", &st, 0) != -1 && st.st_mode & S_IXUSR) {
+ s->state = STATE_ACTIVE_BACKGROUND;
+ } else if (fstatat(s->dir, "pid", &st, 0) != -1 && st.st_mode & S_IXUSR) {
+ s->pid = parse_pid_file(s);
+ s->state = STATE_ACTIVE_PID;
+ } else {
+ do_finish(s);
+ }
+ } else if (!signaled) {
+ s->last_exit = EXIT_NORMAL;
+ s->return_code = return_code;
+
+ do_finish(s);
+ } else { // signaled
+ s->last_exit = EXIT_SIGNALED;
+ s->return_code = return_code;
+
+ do_finish(s);
+ }
+ break;
+
+ case STATE_DEAD:
+ case STATE_INACTIVE:
+ printf("warn: %s died but was set to inactive\n", s->name);
+ }
+
+ s->status_change = time(NULL);
+ service_update_status(s);
+}
diff --git a/src/parse.c b/src/parse.c
@@ -0,0 +1,155 @@
+#include "config_parser.h"
+
+#include <fcntl.h>
+#include <grp.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+void parse_param_file(service_t* s, char* args[]) {
+ int param_file;
+ int args_size = 0;
+ int line_size = 0;
+ char c;
+
+ strcpy(args[args_size++], "./run");
+
+ bool start = true;
+ if ((param_file = openat(s->dir, "params", O_RDONLY)) != -1) {
+ while (read(param_file, &c, 1) > 0) {
+ if (start && c == '%') {
+ args_size--;
+ continue;
+ }
+ if (c == '\n') {
+ args[args_size++][line_size] = '\0';
+
+ line_size = 0;
+ } else {
+ args[args_size][line_size++] = c;
+ }
+ start = false;
+ }
+ if (line_size > 0)
+ args[args_size++][line_size] = '\0';
+ close(param_file);
+ }
+
+ args[args_size] = NULL;
+}
+
+void parse_env_file(char** env) {
+ int env_file;
+ int env_size = 0;
+ int line_size = 0;
+ char c;
+
+ if ((env_file = open("env", O_RDONLY)) != -1) {
+ while (read(env_file, &c, 1) > 0) {
+ if (c == '\n') {
+ env[env_size++][line_size] = '\0';
+
+ line_size = 0;
+ } else {
+ env[env_size][line_size++] = c;
+ }
+ }
+ if (line_size > 0)
+ env[env_size++][line_size] = '\0';
+ close(env_file);
+ }
+
+ env[env_size] = NULL;
+}
+
+
+pid_t parse_pid_file(service_t* s) {
+ int pid_file;
+ if ((pid_file = openat(s->dir, "pid", O_RDONLY)) == -1)
+ return 0;
+
+ char buffer[SV_PID_BUFFER];
+ int n;
+ if ((n = read(pid_file, buffer, sizeof(buffer))) <= 0) {
+ close(pid_file);
+ return 0;
+ }
+ buffer[n] = '\0';
+
+ close(pid_file);
+ return atoi(buffer);
+}
+
+/* uid:gid[:gid[:gid]...] */
+static int parse_ugid_num(char* str, uid_t* uid, gid_t* gids) {
+ int i;
+
+ char* end;
+ *uid = strtoul(str, &end, 10);
+
+ if (*end != ':')
+ return -1;
+
+ str = end + 1;
+ for (i = 0; i < 60; ++i, ++str) {
+ gids[i++] = strtoul(str, &end, 10);
+
+ if (*end != ':')
+ break;
+
+ str = end + 1;
+ }
+
+ if (*str != '\0')
+ return -1;
+
+ return i;
+}
+
+int parse_ugid(char* str, uid_t* uid, gid_t* gids) {
+ struct passwd* pwd;
+ struct group* gr;
+ char* end;
+ char* groupstr = NULL;
+ int gid_size = 0;
+
+ if (str[0] == ':')
+ return parse_ugid_num(str + 1, uid, gids);
+
+ if ((end = strchr(str, ':')) != NULL) {
+ end[0] = '\0';
+ groupstr = end + 1;
+ }
+
+ if ((pwd = getpwnam(str)) == NULL) {
+ return -1;
+ }
+ *uid = pwd->pw_uid;
+
+ if (groupstr == NULL) {
+ gids[0] = pwd->pw_gid;
+ return 1;
+ }
+
+ char* next = groupstr;
+
+ while (next && gid_size < 60) {
+ groupstr = next;
+ if ((end = strchr(groupstr, ':')) != NULL) {
+ end[0] = '\0';
+ next = end + 1;
+ } else {
+ next = NULL;
+ }
+ if ((gr = getgrnam(groupstr)) == NULL)
+ return -1;
+
+ gids[gid_size++] = gr->gr_gid;
+ }
+
+ return gid_size;
+}
diff --git a/src/pattern.c b/src/pattern.c
@@ -1,5 +1,6 @@
#include "pattern.h"
+
static const char* strend(const char* s) {
while (*s)
s++;
diff --git a/src/register.c b/src/register.c
@@ -35,7 +35,7 @@ service_t* service_register(int dir, const char* name, bool is_log_service) {
strncpy(s->name, name, sizeof(s->name));
- service_init_status(s);
+ service_init_runit(s);
s->status_change = time(NULL);
service_update_status(s);
diff --git a/src/restart.c b/src/restart.c
@@ -1,112 +0,0 @@
-#include "config_parser.h"
-#include "service.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-
-static void do_finish(service_t* s) {
- struct stat st;
- if (fstatat(s->dir, "finish", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_FINISHING;
- if ((s->pid = fork_dup_cd_exec(s->dir, "./finish", null_fd, null_fd, null_fd)) == -1) {
- print_error("error: cannot execute ./finish: %s\n");
- s->state = STATE_INACTIVE;
- }
- } else if (s->fail_count == SV_FAIL_MAX) {
- s->state = STATE_DEAD;
- printf("%s died\n", s->name);
- } else {
- s->state = STATE_INACTIVE;
- }
-
- s->status_change = time(NULL);
- service_update_status(s);
-}
-
-
-void service_check_state(service_t* s, bool signaled, int return_code) {
- s->pid = 0;
- if (s->restart_file == S_ONCE)
- s->restart_file = S_DOWN;
- if (s->restart_manual == S_ONCE)
- s->restart_manual = S_DOWN;
-
- struct stat st;
-
- switch (s->state) {
- case STATE_SETUP:
- service_run(s);
- break;
- case STATE_ACTIVE_FOREGROUND:
- if (signaled) {
- s->last_exit = EXIT_SIGNALED;
- s->return_code = return_code;
- s->fail_count++;
-
- printf("%s killed thought signal %d\n", s->name, s->return_code);
- } else {
- s->last_exit = EXIT_NORMAL;
- s->return_code = return_code;
- if (s->return_code > 0)
- s->fail_count++;
- else
- s->fail_count = 0;
-
- printf("%s exited with code %d\n", s->name, s->return_code);
- }
-
- do_finish(s);
-
- break;
- case STATE_ACTIVE_DUMMY:
- case STATE_ACTIVE_PID:
- case STATE_ACTIVE_BACKGROUND:
- case STATE_STOPPING:
- do_finish(s);
- break;
-
- case STATE_FINISHING:
- if (s->fail_count == SV_FAIL_MAX) {
- s->state = STATE_DEAD;
- printf("%s died\n", s->name);
- } else {
- s->state = STATE_INACTIVE;
- }
- break;
- case STATE_STARTING:
- if (!signaled && return_code == 0) {
- if (fstatat(s->dir, "stop", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_ACTIVE_BACKGROUND;
- } else if (fstatat(s->dir, "pid", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->pid = parse_pid_file(s);
- s->state = STATE_ACTIVE_PID;
- } else {
- do_finish(s);
- }
- } else if (!signaled) {
- s->last_exit = EXIT_NORMAL;
- s->return_code = return_code;
-
- do_finish(s);
- } else { // signaled
- s->last_exit = EXIT_SIGNALED;
- s->return_code = return_code;
-
- do_finish(s);
- }
- break;
-
- case STATE_DEAD:
- case STATE_INACTIVE:
- printf("warn: %s died but was set to inactive\n", s->name);
- }
-
- s->status_change = time(NULL);
- service_update_status(s);
-}
diff --git a/src/runit.c b/src/runit.c
@@ -19,7 +19,7 @@ static int runit_signals[] = {
[R_USR2] = SIGUSR2,
};
-void service_init_status(service_t* s) {
+void service_init_runit(service_t* s) {
#if SV_RUNIT_COMPAT != 0
int lockfd;
struct stat st;
@@ -60,7 +60,7 @@ void service_update_status(service_t* s) {
}
service_serial_runit_t stat_runit;
- service_store_runit(s, &stat_runit);
+ service_encode_runit(s, &stat_runit);
if (write(fd, &stat_runit, sizeof(stat_runit)) == -1) {
print_error("cannot write to supervise/status: %s\n");
@@ -74,7 +74,7 @@ void service_update_status(service_t* s) {
return;
}
- const char* stat_human = service_store_human(s);
+ const char* stat_human = service_status_name(s);
if (write(fd, stat_human, strlen(stat_human)) == -1) {
print_error("cannot write to supervise/stat: %s\n");
return;
@@ -111,18 +111,18 @@ void service_handle_command_runit(service_t* s, sv_command_runit_t command) {
break;
case R_KILL:
s->restart_manual = S_FORCE_DOWN;
- service_send(s, SIGKILL);
+ service_kill(s, SIGKILL);
break;
case R_PAUSE:
if (!s->paused) {
s->paused = true;
- service_send(s, SIGSTOP);
+ service_kill(s, SIGSTOP);
}
break;
case R_CONT:
if (s->paused) {
s->paused = false;
- service_send(s, SIGCONT);
+ service_kill(s, SIGCONT);
}
break;
case R_ALARM:
@@ -131,7 +131,7 @@ void service_handle_command_runit(service_t* s, sv_command_runit_t command) {
case R_QUIT:
case R_USR1:
case R_USR2:
- service_send(s, runit_signals[command]);
+ service_kill(s, runit_signals[command]);
break;
case R_EXIT:
// ignored
diff --git a/src/send_command.c b/src/send_command.c
@@ -0,0 +1,63 @@
+#include "service.h"
+#include "util.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+
+const char* command_error[] = {
+ [0] = "success",
+ [EBADCMD] = "command not found",
+ [ENOSV] = "service required",
+ [EBADSV] = "no matching services",
+ [EBEXT] = "invalid extra"
+};
+
+int service_send_command(char command, char extra, const char* service, service_t* response, int response_max) {
+ char request[2] = { command, extra };
+
+ int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sockfd == -1) {
+ print_error("error: cannot connect to socket: %s\n");
+ exit(1);
+ }
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ snprintf(addr.sun_path, sizeof(addr.sun_path), SV_CONTROL_SOCKET, runlevel);
+
+ int ret;
+ if ((ret = connect(sockfd, (struct sockaddr*) &addr, sizeof(addr))) == -1) {
+ print_error("error: cannot connect to %s: %s\n", addr.sun_path);
+ exit(EXIT_FAILURE);
+ }
+
+ write(sockfd, request, sizeof(request));
+ writestr(sockfd, service);
+
+ int res;
+ read(sockfd, &res, 1);
+
+ service_serial_t service_buffer;
+
+ if (res == 0) {
+ if (response) {
+ while (res < response_max && readstr(sockfd, response[res].name) > 1) {
+ read(sockfd, &service_buffer, sizeof(service_buffer));
+ service_decode(&response[res], &service_buffer);
+ res++;
+ }
+ }
+ } else {
+ res *= -1;
+ }
+
+ close(sockfd);
+ return res;
+}
diff --git a/src/serialize.c b/src/serialize.c
@@ -1,7 +1,29 @@
#include "service.h"
-void service_store(service_t* s, service_serial_t* buffer) {
+const char* service_status_name(service_t* s) {
+ switch (s->state) {
+ case STATE_SETUP:
+ return "setup";
+ case STATE_STARTING:
+ return "starting";
+ case STATE_ACTIVE_DUMMY:
+ case STATE_ACTIVE_FOREGROUND:
+ case STATE_ACTIVE_BACKGROUND:
+ case STATE_ACTIVE_PID:
+ return "run";
+ case STATE_STOPPING:
+ return "stopping";
+ case STATE_FINISHING:
+ return "finishing";
+ case STATE_INACTIVE:
+ return "down";
+ case STATE_DEAD:
+ return "dead";
+ }
+}
+
+void service_encode(service_t* s, service_serial_t* buffer) {
buffer->pid[0] = (s->pid >> 0) & 0xff;
buffer->pid[1] = (s->pid >> 8) & 0xff;
buffer->pid[2] = (s->pid >> 16) & 0xff;
@@ -29,29 +51,7 @@ void service_store(service_t* s, service_serial_t* buffer) {
((s->log_service != NULL) << 2);
}
-const char* service_store_human(service_t* s) {
- switch (s->state) {
- case STATE_SETUP:
- return "setup";
- case STATE_STARTING:
- return "starting";
- case STATE_ACTIVE_DUMMY:
- case STATE_ACTIVE_FOREGROUND:
- case STATE_ACTIVE_BACKGROUND:
- case STATE_ACTIVE_PID:
- return "run";
- case STATE_STOPPING:
- return "stopping";
- case STATE_FINISHING:
- return "finishing";
- case STATE_INACTIVE:
- return "down";
- case STATE_DEAD:
- return "dead";
- }
-}
-
-void service_store_runit(service_t* s, service_serial_runit_t* buffer) {
+void service_encode_runit(service_t* s, service_serial_runit_t* buffer) {
uint64_t tai = (uint64_t) s->status_change + 4611686018427387914ULL;
int runit_state;
switch (s->state) {
@@ -95,7 +95,7 @@ void service_store_runit(service_t* s, service_serial_runit_t* buffer) {
buffer->state[0] = runit_state;
}
-void service_load(service_t* s, const service_serial_t* buffer) {
+void service_decode(service_t* s, const service_serial_t* buffer) {
s->pid = (buffer->pid[3] << 24) |
(buffer->pid[2] << 16) |
(buffer->pid[1] << 8) |
diff --git a/src/service.c b/src/service.c
@@ -23,7 +23,6 @@ bool verbose = false;
dependency_t depends[SV_DEPENDENCY_MAX];
int depends_size;
-
service_t* service_get(const char* name) {
for (int i = 0; i < services_size; i++) {
if (streq(services[i].name, name))
diff --git a/src/socket_handler.c b/src/socket_handler.c
@@ -1,67 +0,0 @@
-#include "service.h"
-
-#include <stdio.h>
-#include <unistd.h>
-
-
-void service_handle_socket(int client) {
- char command[2] = { 0, 0 };
- char service_name[SV_NAME_MAX];
-
- read(client, command, sizeof(command));
-
- ssize_t service_len = readstr(client, service_name);
-
- if (service_len)
- printf("command issued by user: %c-%02x with service '%s'\n", command[0], command[1], service_name);
- else
- printf("command issued by user: %c-%02x without service\n", command[0], command[1]);
-
- int res = 0;
- int res_off = 0;
- service_t* response[SV_SOCKET_SERVICE_MAX];
- service_t* request[SV_SOCKET_SERVICE_MAX];
-
- if (service_len > 0) {
- if (command[0] == S_SWITCH) {
- res = service_handle_command(service_name, command[0], command[1], response + res_off);
- } else {
- int req_size = service_pattern(service_name, request, 128);
- if (req_size == 0) {
- res = -EBADSV;
- goto cleanup;
- }
- for (int i = 0; i < req_size; i++) {
- res = service_handle_command(request[i], command[0], command[1], response + res_off);
- if (res < 0)
- goto cleanup;
- res_off += res;
- }
- }
- } else {
- res = service_handle_command(NULL, command[0], command[1], response);
- if (res < 0)
- goto cleanup;
-
- res_off = res;
- }
-
-
-cleanup:
- if (res < 0) {
- res *= -1;
- write(client, &res, 1);
- goto cleanup;
- } else {
- write(client, "", 1);
- service_serial_t service_buffer;
-
- for (int i = 0; i < res_off; i++) {
- service_store(response[i], &service_buffer);
- writestr(client, response[i]->name);
- write(client, &service_buffer, sizeof(service_buffer));
- }
- write(client, "", 1);
- }
- close(client);
-}
diff --git a/src/stage.c b/src/stage.c
@@ -15,7 +15,7 @@ static const char* stage_exec[] = {
};
-void service_handle_stage(int stage) {
+void service_stage(int stage) {
if (stage != 0 && stage != 2)
return;
diff --git a/src/stop.c b/src/stop.c
@@ -12,7 +12,7 @@
void service_stop(service_t* s, bool* changed) {
switch (s->state) {
case STATE_ACTIVE_DUMMY:
- service_check_state(s, false, 0);
+ service_handle_exit(s, false, 0);
if (changed)
*changed = true;
diff --git a/src/supervise.c b/src/supervise.c
@@ -41,7 +41,7 @@ static void signal_child(int unused) {
if (s == NULL)
return;
- service_check_state(s, WIFSIGNALED(status), WIFSIGNALED(status) ? WTERMSIG(status) : WEXITSTATUS(status));
+ service_handle_exit(s, WIFSIGNALED(status), WIFSIGNALED(status) ? WTERMSIG(status) : WEXITSTATUS(status));
}
static void check_deaths(void) {
@@ -50,7 +50,7 @@ static void check_deaths(void) {
s = &services[i];
if (s->state == STATE_ACTIVE_PID) {
if (kill(s->pid, 0) == -1 && errno == ESRCH)
- service_check_state(s, false, 0);
+ service_handle_exit(s, false, 0);
}
}
}
@@ -86,7 +86,7 @@ static void accept_socket(void) {
print_error("error: cannot accept client from control-socket: %s\n");
}
} else {
- service_handle_socket(client_fd);
+ service_handle_client(client_fd);
}
}
@@ -169,7 +169,7 @@ int service_supervise(const char* service_dir_, const char* runlevel_, bool forc
printf(":: starting services on '%s'\n", runlevel);
- if (service_refresh() < 0)
+ if (service_refresh_directory() < 0)
return 1;
printf(":: started services\n");
@@ -177,7 +177,7 @@ int service_supervise(const char* service_dir_, const char* runlevel_, bool forc
// accept connections and handle requests
while (daemon_running) {
check_deaths();
- service_refresh();
+ service_refresh_directory();
check_services();
control_sockets();
accept_socket();
@@ -214,7 +214,7 @@ int service_supervise(const char* service_dir_, const char* runlevel_, bool forc
for (int i = 0; i < services_size; i++) {
if (services[i].pid) {
printf(":: killing %s\n", services[i].name);
- service_send(&services[i], SIGKILL);
+ service_kill(&services[i], SIGKILL);
}
}
diff --git a/src/user_group.c b/src/user_group.c
@@ -1,77 +0,0 @@
-#include "user_group.h"
-
-#include <grp.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* uid:gid[:gid[:gid]...] */
-static int parse_ugid_num(char* str, uid_t* uid, gid_t* gids) {
- int i;
-
- char* end;
- *uid = strtoul(str, &end, 10);
-
- if (*end != ':')
- return -1;
-
- str = end + 1;
- for (i = 0; i < 60; ++i, ++str) {
- gids[i++] = strtoul(str, &end, 10);
-
- if (*end != ':')
- break;
-
- str = end + 1;
- }
-
- if (*str != '\0')
- return -1;
-
- return i;
-}
-
-int parse_ugid(char* str, uid_t* uid, gid_t* gids) {
- struct passwd* pwd;
- struct group* gr;
- char* end;
- char* groupstr = NULL;
- int gid_size = 0;
-
- if (str[0] == ':')
- return parse_ugid_num(str + 1, uid, gids);
-
- if ((end = strchr(str, ':')) != NULL) {
- end[0] = '\0';
- groupstr = end + 1;
- }
-
- if ((pwd = getpwnam(str)) == NULL) {
- return -1;
- }
- *uid = pwd->pw_uid;
-
- if (groupstr == NULL) {
- gids[0] = pwd->pw_gid;
- return 1;
- }
-
- char* next = groupstr;
-
- while (next && gid_size < 60) {
- groupstr = next;
- if ((end = strchr(groupstr, ':')) != NULL) {
- end[0] = '\0';
- next = end + 1;
- } else {
- next = NULL;
- }
- if ((gr = getgrnam(groupstr)) == NULL)
- return -1;
-
- gids[gid_size++] = gr->gr_gid;
- }
-
- return gid_size;
-}