From cae61ad6df0a66cc12ba599f605f13e43aceef8e Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sat, 16 Dec 2017 12:14:21 +0100 Subject: [PATCH] initctl refactor, break out domain socket/client API Signed-off-by: Joachim Nilsson --- src/Makefile.am | 3 +- src/client.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ src/client.h | 39 ++++++++++++++++++++ src/initctl.c | 84 +++++------------------------------------- 4 files changed, 147 insertions(+), 76 deletions(-) create mode 100644 src/client.c create mode 100644 src/client.h diff --git a/src/Makefile.am b/src/Makefile.am index ba0a7b81..d3ae9d46 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -43,7 +43,8 @@ else finit_LDADD += -ldl endif -initctl_SOURCES = initctl.c serv.c serv.h svc.c svc.h \ +initctl_SOURCES = initctl.c client.c client.h \ + serv.c serv.h svc.c svc.h \ cond.c cond.h util.c util.h initctl_CFLAGS = -W -Wall -Wextra -Wno-unused-parameter -std=gnu99 initctl_CFLAGS += $(lite_CFLAGS) diff --git a/src/client.c b/src/client.c new file mode 100644 index 00000000..50e8738e --- /dev/null +++ b/src/client.c @@ -0,0 +1,97 @@ +/* External client API, using UNIX domain socket. + * + * Copyright (c) 2015-2017 Joachim Nilsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "client.h" + +static int sd = -1; + +int client_connect(void) +{ + struct sockaddr_un sun = { + .sun_family = AF_UNIX, + .sun_path = INIT_SOCKET, + }; + + sd = socket(AF_UNIX, SOCK_STREAM, 0); + if (-1 == sd) + goto error; + + if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1) { + close(sd); + goto error; + } + + return sd; +error: + perror("Failed connecting to finit"); + return -1; +} + +int client_disconnect(void) +{ + int rc; + + if (sd < 0) { + errno = EINVAL; + return -1; + } + + rc = close(sd); + sd = -1; + + return rc; +} + +int client_send(struct init_request *rq, ssize_t len) +{ + int sd, result = 255; + + sd = client_connect(); + if (-1 == sd) + return -1; + + if (write(sd, rq, len) != len) + goto error; + + if (read(sd, rq, len) != len) + goto error; + + result = 0; + goto exit; +error: + perror("Failed communicating with finit"); +exit: + client_disconnect(); + return result; +} + +/** + * Local Variables: + * indent-tabs-mode: t + * c-file-style: "linux" + * End: + */ diff --git a/src/client.h b/src/client.h new file mode 100644 index 00000000..b123af8b --- /dev/null +++ b/src/client.h @@ -0,0 +1,39 @@ +/* External client API, using UNIX domain socket. + * + * Copyright (c) 2015-2017 Joachim Nilsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef FINIT_CLIENT_H_ +#define FINIT_CLIENT_H_ + +#include "finit.h" + +typedef struct { + char *cmd; + int (*cb)(char *arg); +} command_t; + +int client_connect (void); +int client_disconnect (void); + +int client_send (struct init_request *rq, ssize_t len); + +#endif /* FINIT_CLIENT_H_ */ diff --git a/src/initctl.c b/src/initctl.c index c3deaf5e..ff41c963 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -33,11 +33,9 @@ #include #include #include -#include -#include #include -#include "finit.h" +#include "client.h" #include "cond.h" #include "serv.h" #include "service.h" @@ -45,86 +43,22 @@ #define _PATH_COND _PATH_VARRUN "finit/cond/" -typedef struct { - char *cmd; - int (*cb)(char *arg); -} command_t; - int verbose = 0; int runlevel = 0; -static int do_connect(void) -{ - int sd; - struct sockaddr_un sun = { - .sun_family = AF_UNIX, - .sun_path = INIT_SOCKET, - }; - - sd = socket(AF_UNIX, SOCK_STREAM, 0); - if (-1 == sd) - goto error; - - if (connect(sd, (struct sockaddr*)&sun, sizeof(sun)) == -1) { - close(sd); - goto error; - } - - return sd; -error: - perror("Failed connecting to finit"); - return -1; -} - -static int do_send(struct init_request *rq, ssize_t len) -{ - int sd, result = 255; - - sd = do_connect(); - if (-1 == sd) - return -1; - - if (write(sd, rq, len) != len) - goto error; - - if (read(sd, rq, len) != len) - goto error; - - result = 0; - goto exit; -error: - perror("Failed communicating with finit"); -exit: - close(sd); - return result; -} - static int runlevel_get(void) { - int sd, result = 255; + int result; struct init_request rq; memset(&rq, 0, sizeof(rq)); rq.cmd = INIT_CMD_GET_RUNLEVEL; rq.magic = INIT_MAGIC; - sd = do_connect(); - if (-1 == sd) - return -1; + result = client_send(&rq, sizeof(rq)); + if (!result) + result = rq.runlevel; - if (write(sd, &rq, sizeof(rq)) != sizeof(rq)) - goto error; - - if (read(sd, &rq, sizeof(rq)) != sizeof(rq)) - goto error; - - result = rq.runlevel; - goto exit; -error: - perror("Failed communicating with finit"); - result = -1; -exit: - close(sd); return result; } @@ -135,7 +69,7 @@ static int toggle_debug(char *arg) .cmd = INIT_CMD_DEBUG, }; - return do_send(&rq, sizeof(rq)); + return client_send(&rq, sizeof(rq)); } static int do_log(char *svc) @@ -169,7 +103,7 @@ static int do_runlevel(char *arg) return 0; } - return do_send(&rq, sizeof(rq)); + return client_send(&rq, sizeof(rq)); } static int do_svc(int cmd, char *arg) @@ -181,7 +115,7 @@ static int do_svc(int cmd, char *arg) strlcpy(rq.data, arg, sizeof(rq.data)); - return do_send(&rq, sizeof(rq)); + return client_send(&rq, sizeof(rq)); } static int do_emit (char *arg) { return do_svc(INIT_CMD_EMIT, arg); } @@ -547,7 +481,7 @@ static int show_status(char *arg) }; snprintf(rq.data, sizeof(rq.data), "%s", jobid); - if (do_send(&rq, sizeof(rq))) { + if (client_send(&rq, sizeof(rq))) { snprintf(args, sizeof(args), "Unknown inetd"); info = args; } else {