commit fcfc94b29c3b6ea367a5dca19aefe7904fbf296b
Author: Cem Keylan <cem@ckyln.com>
Date: Thu, 17 Sep 2020 11:23:05 +0300
initial commit
Diffstat:
10 files changed, 414 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,47 @@
+.SUFFIXES:
+.SUFFIXES: .o .c
+
+CC = cc
+AR = ar
+RANLIB = ranlib
+
+HDR = \
+ util.h
+
+LIBUTILSRC = \
+ libutil/enprintf.c \
+ libutil/env.c \
+ libutil/io.c \
+ libutil/proc.c \
+ libutil/service.c \
+ libutil/strtonum.c \
+
+BIN = \
+ sysmgr
+
+LIBUTILOBJ = ${LIBUTILSRC:.c=.o}
+LIBUTIL = libutil.a
+
+SRC = ${BIN:=.c}
+OBJ = ${SRC:.c=.o} ${LIBUTILOBJ}
+
+all: ${BIN}
+
+${BIN}: ${LIBUTIL}
+
+${OBJ}: ${HDR}
+
+${LIBUTIL}: ${LIBUTILOBJ}
+ ${AR} rc $@ $?
+ ${RANLIB} $@
+
+.o:
+ ${CC} ${LDFLAGS} -o $@ $< ${LIBUTIL} ${LIBS}
+
+.c.o:
+ ${CC} ${CFLAGS} ${CPPFLAGS} -o $@ -c $<
+
+clean:
+ rm -f ${BIN} ${OBJ} ${LIBUTIL}
+
+.PHONY: all clean
diff --git a/README b/README
@@ -0,0 +1,2 @@
+sysmgr in C
+-----------+
\ No newline at end of file
diff --git a/libutil/enprintf.c b/libutil/enprintf.c
@@ -0,0 +1,64 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../util.h"
+
+char *argv0;
+
+static void venprintf(int, const char *, va_list);
+
+void
+eprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(1, fmt, ap);
+ va_end(ap);
+}
+
+void
+enprintf(int status, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ venprintf(status, fmt, ap);
+ va_end(ap);
+}
+
+void
+venprintf(int status, const char *fmt, va_list ap)
+{
+ if (strncmp(fmt, "usage", strlen("usage")))
+ fprintf(stderr, "%s: ", argv0);
+
+ vfprintf(stderr, fmt, ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ }
+
+ exit(status);
+}
+
+void
+weprintf(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (strncmp(fmt, "usage", strlen("usage")))
+ fprintf(stderr, "%s: ", argv0);
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ }
+}
diff --git a/libutil/env.c b/libutil/env.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+
+#include "../util.h"
+
+char*
+getenv_fallback(char *name, char *fallback)
+{
+ char *value = getenv(name);
+ if (!value)
+ value = fallback;
+ return value;
+}
diff --git a/libutil/io.c b/libutil/io.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "../util.h"
+
+void
+out(const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ fputc('\n', stderr);
+}
+
+void
+die(const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+
+ if (msg[0] && msg[strlen(msg)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ fputc('\n', stderr);
+ }
+ exit(1);
+}
diff --git a/libutil/proc.c b/libutil/proc.c
@@ -0,0 +1,67 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "../util.h"
+
+pid_t
+getsvpid(service *sv)
+{
+ pid_t pid;
+
+ if (access(sv->pidfile, R_OK) == -1)
+ return -1;
+ FILE *pidfile;
+
+ pidfile = fopen(sv->pidfile, "r");
+ if (pidfile == NULL)
+ return -2;
+
+ fscanf(pidfile, "%d", &pid);
+ fclose(pidfile);
+
+ return pid;
+}
+
+int
+writesvpid(char *file, pid_t pid)
+{
+ if (access(file, W_OK) == -1)
+ return -1;
+
+ FILE *pidfile;
+
+ pidfile = fopen(file, "w");
+ if (pidfile == NULL)
+ /* perror(file); */
+ return -2;
+
+ fprintf(pidfile, "%d\n", pid);
+ fclose(pidfile);
+
+ return 0;
+}
+
+int
+checkprocess(int pid)
+{
+ if (kill(pid, 0) == 0) return 0;
+ else {
+ switch (errno) {
+ case 1:
+ /* EPERM is only produced if the process exists, but the
+ * user running the program doesn't have the permissions
+ * to kill the process. We can safely assume that the
+ * process exists in this case and return 0.
+ */
+ return 0;
+ break;
+ default:
+ perror("kill");
+ break;
+ }
+
+ return 1;
+ }
+}
diff --git a/libutil/service.c b/libutil/service.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#include "../util.h"
+
+service*
+sv_init(service *sv, char *sv_name)
+{
+ sprintf(sv->name, "%s", sv_name);
+ sprintf(sv->sysdir, "%s", getenv_fallback("SYSDIR", "/var/sysmgr"));
+ sprintf(sv->rundir, "%s", getenv_fallback("RUNDIR", "/run/sysmgr"));
+ sprintf(sv->pidfile, "%s/%s/pid", sv->rundir, sv->name);
+ sprintf(sv->svfile, "%s/%s", sv->sysdir, sv_name);
+
+ return sv;
+}
diff --git a/libutil/strtonum.c b/libutil/strtonum.c
@@ -0,0 +1,85 @@
+/* $OpenBSD: strtonum.c,v 1.7 2013/04/17 18:40:58 tedu Exp $ */
+
+/*
+ * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "../util.h"
+
+#define INVALID 1
+#define TOOSMALL 2
+#define TOOLARGE 3
+
+long long
+strtonum(const char *numstr, long long minval, long long maxval,
+ const char **errstrp)
+{
+ long long ll = 0;
+ int error = 0;
+ char *ep;
+ struct errval {
+ const char *errstr;
+ int err;
+ } ev[4] = {
+ { NULL, 0 },
+ { "invalid", EINVAL },
+ { "too small", ERANGE },
+ { "too large", ERANGE },
+ };
+
+ ev[0].err = errno;
+ errno = 0;
+ if (minval > maxval) {
+ error = INVALID;
+ } else {
+ ll = strtoll(numstr, &ep, 10);
+ if (numstr == ep || *ep != '\0')
+ error = INVALID;
+ else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+ error = TOOSMALL;
+ else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+ error = TOOLARGE;
+ }
+ if (errstrp != NULL)
+ *errstrp = ev[error].errstr;
+ errno = ev[error].err;
+ if (error)
+ ll = 0;
+
+ return (ll);
+}
+
+long long
+enstrtonum(int status, const char *numstr, long long minval, long long maxval)
+{
+ const char *errstr;
+ long long ll;
+
+ ll = strtonum(numstr, minval, maxval, &errstr);
+ if (errstr)
+ enprintf(status, "strtonum %s: %s\n", numstr, errstr);
+ return ll;
+}
+
+long long
+estrtonum(const char *numstr, long long minval, long long maxval)
+{
+ return enstrtonum(1, numstr, minval, maxval);
+}
diff --git a/sysmgr.c b/sysmgr.c
@@ -0,0 +1,37 @@
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <libgen.h>
+
+#include "util.h"
+static char *argv0;
+
+void
+usage(void)
+{
+ printf("usage: %s\n\nSee sysmgr(8) for detailed information.\n\nVersion: %s\n", argv0, VERSION);
+ exit(0);
+}
+
+
+int main(int argc, char *argv[])
+{
+ argv0 = basename(argv[0]);
+
+ if (argc > 1)
+ usage();
+
+ if (setenv("SYSDIR", "/var/sysmgr", 0) == -1)
+ die("setenv:");
+ if (setenv("RUNDIR", "/run/sysmgr", 0) == -1)
+ die("setenv:");
+
+ char *rundir = getenv("RUNDIR");
+ char *sysdir = getenv("SYSDIR");
+
+ pid_t pid = getpid();
+
+}
diff --git a/util.h b/util.h
@@ -0,0 +1,49 @@
+/* See LICENSE for copyright information */
+
+#ifndef _LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef _TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifndef VERSION
+#define VERSION "git"
+#endif
+
+typedef struct service {
+ char name[NAME_MAX];
+ char sysdir[PATH_MAX];
+ char rundir[PATH_MAX];
+ char pidfile[PATH_MAX];
+ char svfile[PATH_MAX];
+} service;
+
+/*
+ * Get information about the service.
+ */
+service *sv_init(service *sv, char *sv_name);
+
+/* proc.c */
+int getsvpid(service *sv);
+int checkprocess(int pid);
+int writesvpid(char *file, pid_t pid);
+
+/* env.c */
+char *getenv_fallback(char *name, char *fallback);
+void *setenv_fallback(char *name, char *fallback);
+
+/* io.c */
+void die(const char *msg, ...);
+
+
+/* enprintf.c */
+void enprintf(int, const char *, ...);
+void eprintf(const char *, ...);
+void weprintf(const char *, ...);
+
+/* strtonum.c */
+long long strtonum(const char *, long long, long long, const char **);
+long long enstrtonum(int, const char *, long long, long long);
+long long estrtonum(const char *, long long, long long);