aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-03-06 15:25:06 +0200
committerSergey Poznyakoff <gray@gnu.org>2016-03-06 15:27:39 +0200
commit1a37a444eea3d238e45d01d47ac157b470f536ac (patch)
tree5a992298b9cdc93c31ffce6a7db302670e8eb0b9 /src
parentad5bd6e401657b9cb0fed04d15cdc6feeef91e15 (diff)
downloadpies-1a37a444eea3d238e45d01d47ac157b470f536ac.tar.gz
pies-1a37a444eea3d238e45d01d47ac157b470f536ac.tar.bz2
Reimplement the telinit legacy interface.
pies -T is now fully compatible with the legacy telinit command * src/telinit.opt: New file. * src/Makefile.am: Add telinit.opt * src/cmdline.opt (-T): Remove explicit variable. Rest of command line is processed specially. * src/pies.h (telinit): Change prototype. * src/sysvinit.c (telinit): Rewrite. * src/.gitignore: Update. * doc/pies.texi: Document telinit.
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/cmdline.opt6
-rw-r--r--src/pies.h2
-rw-r--r--src/sysvinit.c28
-rw-r--r--src/telinit.opt89
6 files changed, 111 insertions, 23 deletions
diff --git a/src/.gitignore b/src/.gitignore
index a83b9ab..3bf90ef 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -8,3 +8,4 @@ pies
8pies.rc 8pies.rc
9piesctl 9piesctl
10piesctl-cl.h 10piesctl-cl.h
11telinit.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 6515804..b0e9b6f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,13 +41,14 @@ noinst_HEADERS = \
41 meta1parse.h\ 41 meta1parse.h\
42 pies.h\ 42 pies.h\
43 prog.h\ 43 prog.h\
44 piesctl-cl.h 44 piesctl-cl.h\
45 telinit.h
45 46
46BUILT_SOURCES=cmdline.h piesctl-cl.h 47BUILT_SOURCES=cmdline.h piesctl-cl.h telinit.h
47 48
48incdir=$(pkgdatadir)/$(VERSION)/include 49incdir=$(pkgdatadir)/$(VERSION)/include
49inc_DATA = pp-setup 50inc_DATA = pp-setup
50EXTRA_DIST = cmdline.opt piesctl-cl.opt pp-setup inetd.in 51EXTRA_DIST = cmdline.opt piesctl-cl.opt telinit.opt pp-setup inetd.in
51 52
52SUFFIXES=.opt .c .h 53SUFFIXES=.opt .c .h
53.opt.h: 54.opt.h:
@@ -55,6 +56,7 @@ SUFFIXES=.opt .c .h
55 56
56cmdline.h: cmdline.opt 57cmdline.h: cmdline.opt
57piesctl-cl.h: piesctl-cl.opt 58piesctl-cl.h: piesctl-cl.opt
59telinit.h: telinit.opt
58 60
59pies_LDADD = \ 61pies_LDADD = \
60 ../ident/libident.a\ 62 ../ident/libident.a\
diff --git a/src/cmdline.opt b/src/cmdline.opt
index 7d6f7d4..d8bd02f 100644
--- a/src/cmdline.opt
+++ b/src/cmdline.opt
@@ -112,11 +112,11 @@ BEGIN
112 lint_mode = 1; 112 lint_mode = 1;
113END 113END
114 114
115OPTION(telinit,T,RUNLEVEL, 115OPTION(telinit,T,,
116 [<emulate telinit command>]) 116 [<telinit command: run "pies -T --help" for help>])
117BEGIN 117BEGIN
118 log_to_stderr_only = 1; 118 log_to_stderr_only = 1;
119 exit (telinit (optarg)); 119 exit (telinit (argc - (optind - 1), argv + (optind - 1)));
120END 120END
121 121
122GROUP(Preprocessor) 122GROUP(Preprocessor)
diff --git a/src/pies.h b/src/pies.h
index 4eb2aca..b0cc746 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -535,7 +535,7 @@ void sysvinit_begin (void);
535int is_comp_wait (struct component *comp); 535int is_comp_wait (struct component *comp);
536int is_valid_runlevel (int c); 536int is_valid_runlevel (int c);
537int console_open (int mode); 537int console_open (int mode);
538int telinit (const char *arg); 538int telinit (int argc, char **argv);
539int inittab_parse (const char *file); 539int inittab_parse (const char *file);
540int sysvinit_sigtrans (int sig, int *pact); 540int sysvinit_sigtrans (int sig, int *pact);
541void sysvinit_runlevel_setup (int mask); 541void sysvinit_runlevel_setup (int mask);
diff --git a/src/sysvinit.c b/src/sysvinit.c
index a150058..9043619 100644
--- a/src/sysvinit.c
+++ b/src/sysvinit.c
@@ -529,6 +529,8 @@ sysvinit_fifo_handler (int fd, void *data)
529 { 529 {
530 debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d", 530 debug (1, ("INITREQ: cmd=%d, runlevel=%d, sleeptime=%d",
531 buf.req.cmd, buf.req.runlevel, buf.req.sleeptime)); 531 buf.req.cmd, buf.req.runlevel, buf.req.sleeptime));
532 if (buf.req.sleeptime > 0)
533 shutdown_timeout = buf.req.sleeptime;
532 switch (buf.req.cmd) 534 switch (buf.req.cmd)
533 { 535 {
534 case INIT_CMD_RUNLVL: 536 case INIT_CMD_RUNLVL:
@@ -907,25 +909,19 @@ is_comp_wait (struct component *comp)
907 } 909 }
908 return 0; 910 return 0;
909} 911}
910 912
913#include "telinit.h"
914
911int 915int
912telinit (const char *arg) 916telinit (int argc, char **argv)
913{ 917{
914 int fd; 918 int fd;
915 struct sysvinit_request req; 919 struct sysvinit_request req;
916 920
917 if (arg[1] || !is_valid_runlevel (*arg))
918 {
919 logmsg (LOG_CRIT, "invalid argument");
920 exit (EX_USAGE);
921 }
922 memset (&req, 0, sizeof (req)); 921 memset (&req, 0, sizeof (req));
923 req.magic = INIT_MAGIC; 922 req.magic = INIT_MAGIC;
924 req.cmd = INIT_CMD_RUNLVL; 923
925 req.runlevel = *arg; 924 telinit_parser (&req, argc, argv);
926#if 0
927 req.sleeptime = sltime;
928#endif
929 925
930 signal (SIGALRM, SIG_DFL); 926 signal (SIGALRM, SIG_DFL);
931 alarm (5); 927 alarm (5);
@@ -933,17 +929,17 @@ telinit (const char *arg)
933 if (fd < 0) 929 if (fd < 0)
934 { 930 {
935 logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno)); 931 logmsg (LOG_ERR, _("cannot open %s: %s"), init_fifo, strerror (errno));
936 exit (EX_UNAVAILABLE); 932 return EX_UNAVAILABLE;
937 } 933 }
938 if (write (fd, &req, sizeof (req)) != sizeof (req)) 934 if (write (fd, &req, sizeof (req)) != sizeof (req))
939 { 935 {
940 logmsg (LOG_ERR, _("error writing to %s: %s"), 936 logmsg (LOG_ERR, _("error writing to %s: %s"),
941 init_fifo, strerror (errno)); 937 init_fifo, strerror (errno));
942 exit (EX_UNAVAILABLE); 938 return EX_UNAVAILABLE;
943 } 939 }
944 alarm (0); 940 alarm (0);
945 close (fd); 941 close (fd);
946 exit (0); 942 return 0;
947} 943}
948 944
949static char * 945static char *
diff --git a/src/telinit.opt b/src/telinit.opt
new file mode 100644
index 0000000..f052a53
--- /dev/null
+++ b/src/telinit.opt
@@ -0,0 +1,89 @@
1/* This file is part of GNU Pies. -*- c -*-
2 Copyright (C) 2016 Sergey Poznyakoff
3
4 GNU Pies is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Pies is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */
16
17OPTIONS_COMMAND_BEGIN("pies",
18 [<>],
19 [<send command to init process via the legacy interface>],
20 [<[RUNLEVEL]>],
21 [<gnu>],
22 [<noversion>])
23
24OPTION(timeout,t,[<SECONDS>],
25 [<set interval between sending TERM and KILL signals>])
26BEGIN
27 char *p;
28 errno = 0;
29 shutdown_timeout = strtoul (optarg, &p, 0);
30 if (*p || errno)
31 {
32 logmsg (LOG_ERR, _("invalid number: %s"), optarg);
33 exit (EX_USAGE);
34 }
35END
36
37OPTION(environment,e,[<VAR=[VAL]>],[<change environment>])
38BEGIN
39 size_t len = strlen (optarg);
40 if (envsize + len + 2 > sizeof(req->data))
41 {
42 logmsg (LOG_ERR, _("-e argument too long"));
43 exit (EX_USAGE);
44 }
45 memcpy (req->data + envsize, optarg, len);
46 envsize += len;
47 req->data[envsize++] = 0;
48END
49
50OPTIONS_END
51
52static void
53telinit_parser (struct sysvinit_request *req, int argc, char *argv[])
54{
55 int i;
56 char *cmds[] = { "-T", NULL };
57 size_t envsize = 0;
58
59 proginfo.subcmd = cmds;
60 GETOPT(argc, argv, i);
61 argc -= i;
62 argv += i;
63 if (envsize)
64 {
65 req->data[envsize++] = 0;
66 req->cmd = INIT_CMD_SETENV;
67 if (argc)
68 {
69 logmsg (LOG_ERR, _("too many arguments"));
70 exit (EX_USAGE);
71 }
72 }
73 else
74 {
75 if (argc != 1)
76 {
77 logmsg (LOG_ERR, _("bad number of arguments"));
78 exit (EX_USAGE);
79 }
80 if (argv[0][1] || !is_valid_runlevel (argv[0][0]))
81 {
82 logmsg (LOG_ERR, _("invalid runlevel: %s"), argv[0]);
83 exit (EX_USAGE);
84 }
85 req->cmd = INIT_CMD_RUNLVL;
86 req->runlevel = argv[0][0];