| 1 |
/*
|
| 2 |
rc-update
|
| 3 |
Manage init scripts and runlevels
|
| 4 |
Copyright 2007 Gentoo Foundation
|
| 5 |
Released under the GPLv2
|
| 6 |
*/
|
| 7 |
|
| 8 |
#include <errno.h>
|
| 9 |
#include <limits.h>
|
| 10 |
#include <stdbool.h>
|
| 11 |
#include <stdio.h>
|
| 12 |
#include <stdlib.h>
|
| 13 |
#include <string.h>
|
| 14 |
#include <unistd.h>
|
| 15 |
|
| 16 |
#include "builtins.h"
|
| 17 |
#include "einfo.h"
|
| 18 |
#include "rc.h"
|
| 19 |
#include "rc-misc.h"
|
| 20 |
#include "strlist.h"
|
| 21 |
|
| 22 |
static char *applet = NULL;
|
| 23 |
|
| 24 |
static bool add (const char *runlevel, const char *service)
|
| 25 |
{
|
| 26 |
bool retval = true;
|
| 27 |
|
| 28 |
if (! rc_runlevel_exists (runlevel)) {
|
| 29 |
ewarn ("runlevel `%s' does not exist", runlevel);
|
| 30 |
return (false);
|
| 31 |
}
|
| 32 |
if (rc_service_in_runlevel (service, runlevel)) {
|
| 33 |
ewarn ("%s already installed in runlevel `%s'; skipping",
|
| 34 |
service, runlevel);
|
| 35 |
return (false);
|
| 36 |
}
|
| 37 |
|
| 38 |
if (rc_service_add (runlevel, service))
|
| 39 |
einfo ("%s added to runlevel %s", service, runlevel);
|
| 40 |
else {
|
| 41 |
eerror ("%s: failed to add service `%s' to runlevel `%s': %s",
|
| 42 |
applet, service, runlevel, strerror (errno));
|
| 43 |
retval = false;
|
| 44 |
}
|
| 45 |
|
| 46 |
return (retval);
|
| 47 |
}
|
| 48 |
|
| 49 |
int rc_update (int argc, char **argv)
|
| 50 |
{
|
| 51 |
int i;
|
| 52 |
int j;
|
| 53 |
char *service;
|
| 54 |
char **runlevels = NULL;
|
| 55 |
char *runlevel;
|
| 56 |
|
| 57 |
applet = argv[0];
|
| 58 |
if (argc < 2 ||
|
| 59 |
strcmp (argv[1], "show") == 0 ||
|
| 60 |
strcmp (argv[1], "-s") == 0)
|
| 61 |
{
|
| 62 |
bool verbose = false;
|
| 63 |
char **services = rc_services_in_runlevel (NULL);
|
| 64 |
|
| 65 |
for (i = 2; i < argc; i++) {
|
| 66 |
if (strcmp (argv[i], "--verbose") == 0 ||
|
| 67 |
strcmp (argv[i], "-v") == 0)
|
| 68 |
verbose = true;
|
| 69 |
else
|
| 70 |
runlevels = rc_strlist_add (runlevels, argv[i]);
|
| 71 |
}
|
| 72 |
|
| 73 |
if (! runlevels)
|
| 74 |
runlevels = rc_get_runlevels ();
|
| 75 |
|
| 76 |
STRLIST_FOREACH (services, service, i) {
|
| 77 |
char **in = NULL;
|
| 78 |
bool inone = false;
|
| 79 |
|
| 80 |
STRLIST_FOREACH (runlevels, runlevel, j) {
|
| 81 |
if (rc_service_in_runlevel (service, runlevel)) {
|
| 82 |
in = rc_strlist_add (in, runlevel);
|
| 83 |
inone = true;
|
| 84 |
} else {
|
| 85 |
char buffer[PATH_MAX];
|
| 86 |
memset (buffer, ' ', strlen (runlevel));
|
| 87 |
buffer[strlen (runlevel)] = 0;
|
| 88 |
in = rc_strlist_add (in, buffer);
|
| 89 |
}
|
| 90 |
}
|
| 91 |
|
| 92 |
if (! inone && ! verbose)
|
| 93 |
continue;
|
| 94 |
|
| 95 |
printf (" %20s |", service);
|
| 96 |
STRLIST_FOREACH (in, runlevel, j)
|
| 97 |
printf (" %s", runlevel);
|
| 98 |
printf ("\n");
|
| 99 |
}
|
| 100 |
|
| 101 |
return (EXIT_SUCCESS);
|
| 102 |
}
|
| 103 |
|
| 104 |
if (geteuid () != 0)
|
| 105 |
eerrorx ("%s: must be root to add or delete services from runlevels",
|
| 106 |
applet);
|
| 107 |
|
| 108 |
if (! (service = argv[2]))
|
| 109 |
eerrorx ("%s: no service specified", applet);
|
| 110 |
|
| 111 |
if (strcmp (argv[1], "add") == 0 ||
|
| 112 |
strcmp (argv[1], "-a") == 0)
|
| 113 |
{
|
| 114 |
if (! service)
|
| 115 |
eerrorx ("%s: no service specified", applet);
|
| 116 |
if (! rc_service_exists (service))
|
| 117 |
eerrorx ("%s: service `%s' does not exist", applet, service);
|
| 118 |
|
| 119 |
if (argc < 4)
|
| 120 |
add (rc_get_runlevel (), service);
|
| 121 |
|
| 122 |
for (i = 3; i < argc; i++)
|
| 123 |
add (argv[i], service);
|
| 124 |
|
| 125 |
return (EXIT_SUCCESS);
|
| 126 |
}
|
| 127 |
|
| 128 |
if (strcmp (argv[1], "delete") == 0 ||
|
| 129 |
strcmp (argv[1], "del") == 0 ||
|
| 130 |
strcmp (argv[1], "-d") == 0)
|
| 131 |
{
|
| 132 |
for (i = 3; i < argc; i++)
|
| 133 |
runlevels = rc_strlist_add (runlevels, argv[i]);
|
| 134 |
|
| 135 |
if (! runlevels)
|
| 136 |
runlevels = rc_strlist_add (runlevels, rc_get_runlevel ());
|
| 137 |
|
| 138 |
STRLIST_FOREACH (runlevels, runlevel, i) {
|
| 139 |
if (rc_service_in_runlevel (service, runlevel)) {
|
| 140 |
if (rc_service_delete (runlevel, service))
|
| 141 |
einfo ("%s removed from runlevel %s", service, runlevel);
|
| 142 |
else
|
| 143 |
eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
|
| 144 |
applet, service, runlevel, strerror (errno));
|
| 145 |
}
|
| 146 |
}
|
| 147 |
|
| 148 |
return (EXIT_SUCCESS);
|
| 149 |
}
|
| 150 |
|
| 151 |
eerrorx ("%s: unknown command `%s'", applet, argv[1]);
|
| 152 |
}
|