diff options
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | src/mds-server.c | 137 | ||||
-rw-r--r-- | src/mds-server.h | 22 | ||||
-rw-r--r-- | src/mds.c | 13 |
4 files changed, 168 insertions, 11 deletions
@@ -62,15 +62,14 @@ C_FLAGS = $(OPTIMISE) $(WARN) -std=$(STD) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ # Build rules. .PHONY: all -all: bin/mds +all: bin/mds bin/mds-server -bin/mds: obj/mds.o +bin/%: obj/%.o mkdir -p bin gcc $(C_FLAGS) -o $@ $^ - -obj/%.o: src/%.c src/*.h +obj/%.o: src/%.c src/%.h src/config.h mkdir -p obj gcc $(C_FLAGS) -c -o $@ $< diff --git a/src/mds-server.c b/src/mds-server.c new file mode 100644 index 0000000..e532c72 --- /dev/null +++ b/src/mds-server.c @@ -0,0 +1,137 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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/>. + */ +#include "mds-server.h" +#include "config.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <limits.h> + + +/** + * Number of elements in `argv` + */ +static int argc; + +/** + * Command line arguments + */ +static char** argv; + + +/** + * Entry point of the server + * + * @param argc_ Number of elements in `argv_` + * @param argv_ Command line arguments + * @return Non-zero on error + */ +int main(int argc_, char** argv_) +{ + char* unparsed_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; + int i; + int is_respawn = -1; + int socket_fd = -1; + int unparsed_args_ptr = 0; + + + argc = argc_; + argv = argv_; + + + /* Sanity check the number of command line arguments. */ + if (argc > ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT) + { + fprintf(stderr, + "%s: that number of arguments is ridiculous, I will not allow it.\n", + *argv); + return 1; + } + + + /* Parse command line arguments. */ + for (i = 1; i < argc; i++) + { + char* arg = argv[i]; + if (!strcmp(arg, "--initial-spawn")) /* Initial spawn? */ + if (is_respawn == 1) + { + fprintf(stderr, + "%s: conflicting arguments %s and %s cannot be combined.\n", + *argv, "--initial-spawn", "--respawn"); + return 1; + } + else + is_respawn = 0; + else if (!strcmp(arg, "--respawn")) /* Respawning after crash? */ + if (is_respawn == 0) + { + fprintf(stderr, + "%s: conflicting arguments %s and %s cannot be combined.\n", + *argv, "--initial-spawn", "--respawn"); + return 1; + } + else + is_respawn = 1; + else if (strstr(arg, "--socket-fd=") == arg) /* Socket file descriptor. */ + { + long int r; + char* endptr; + if (socket_fd != -1) + { + fprintf(stderr, "%s: duplicate declaration of %s.\n", *argv, "--socket-fd"); + return -1; + } + arg += strlen("--socket-fd="); + r = strtol(arg, &endptr, 10); + if ((*argv == '\0') || isspace(*argv) || + (endptr - arg != (ssize_t)strlen(arg)) + || (r < 0) || (r > INT_MAX)) + { + fprintf(stderr, "%s: invalid value for %s: %s.\n", *argv, "--socket-fd", arg); + return 1; + } + socket_fd = (int)r; + } + else + /* Not recognised, it is probably for another server. */ + unparsed_args[unparsed_args_ptr++] = arg; + } + unparsed_args[unparsed_args_ptr] = NULL; + + + /* Check that manditory arguments have been specified. */ + if (is_respawn < 0) + { + fprintf(stderr, + "%s: missing state argument, require either %s or %s.\n", + *argv, "--initial-spawn", "--respawn"); + return 1; + } + if (socket_fd < 0) + { + fprintf(stderr, "%s: missing socket file descriptor argument.\n", *argv); + return 1; + } + + + return 0; +} + diff --git a/src/mds-server.h b/src/mds-server.h new file mode 100644 index 0000000..4b558dd --- /dev/null +++ b/src/mds-server.h @@ -0,0 +1,22 @@ +/** + * mds — A micro-display server + * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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/>. + */ +#ifndef MDS_MDS_SERVER_H +#define MDS_MDS_SERVER_H + +#endif + @@ -246,7 +246,7 @@ int spawn_and_respawn_server(int fd) struct timespec time_end; char* child_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; char pathname[PATH_MAX]; - char fdstr[64]; + char fdstr[12 /* strlen("--socket-fd=") */ + 64]; int i; pid_t pid; int status; @@ -260,13 +260,12 @@ int spawn_and_respawn_server(int fd) child_args[i] = argv[i]; child_args[argc + 0] = strdup("--initial-spawn"); - child_args[argc + 1] = strdup("--socket-fd"); - snprintf(fdstr, sizeof(fdstr) / sizeof(char), "%i", fd); - child_args[argc + 2] = fdstr; - child_args[argc + 3] = NULL; + snprintf(fdstr, sizeof(fdstr) / sizeof(char), "--socket-fd=%i", fd); + child_args[argc + 1] = fdstr; + child_args[argc + 2] = NULL; -#if (LIBEXEC_ARGC_EXTRA_LIMIT < 3) -# error LIBEXEC_ARGC_EXTRA_LIMIT is too small, need at least 3. +#if (LIBEXEC_ARGC_EXTRA_LIMIT < 2) +# error LIBEXEC_ARGC_EXTRA_LIMIT is too small, need at least 2. #endif for (;;) |