/[baselayout]/trunk/src/rc-update.c
Gentoo

Contents of /trunk/src/rc-update.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2882 - (show annotations) (download) (as text)
Tue Sep 18 11:36:55 2007 UTC (6 years, 10 months ago) by uberlord
File MIME type: text/x-csrc
File size: 5352 byte(s)
    API change! rc_strlist_add and friends now take char *** instead of
    char ** and return a pointer to the item added instead of the new
    list head. This is so we can easily tell if the item was successfully
    added or not instead of iterating through the list looking for it.

    list = rc_strlist_add (list, item);
    becomes
    rc_strlist_add (&list, item);
1 /*
2 rc-update
3 Manage init scripts and runlevels
4 Copyright 2007 Gentoo Foundation
5 Released under the GPLv2
6 */
7
8 #define APPLET "rc-update"
9
10 #include <errno.h>
11 #include <getopt.h>
12 #include <limits.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include "builtins.h"
20 #include "einfo.h"
21 #include "rc.h"
22 #include "rc-misc.h"
23 #include "strlist.h"
24
25 static char *applet = NULL;
26
27 static bool add (const char *runlevel, const char *service)
28 {
29 bool retval = false;
30
31 if (! rc_service_exists (service))
32 eerror ("%s: service `%s' does not exist", applet, service);
33 else if (! rc_runlevel_exists (runlevel))
34 eerror ("%s: runlevel `%s' does not exist", applet, runlevel);
35 else if (rc_service_in_runlevel (service, runlevel)) {
36 ewarn ("%s: %s already installed in runlevel `%s'; skipping",
37 applet, service, runlevel);
38 retval = true;
39 } else if (rc_service_add (runlevel, service)) {
40 einfo ("%s added to runlevel %s", service, runlevel);
41 retval = true;
42 } else
43 eerror ("%s: failed to add service `%s' to runlevel `%s': %s",
44 applet, service, runlevel, strerror (errno));
45
46 return (retval);
47 }
48
49 static bool delete (const char *runlevel, const char *service)
50 {
51 bool retval = false;
52
53 if (rc_service_in_runlevel (service, runlevel)) {
54 if (rc_service_delete (runlevel, service)) {
55 einfo ("%s removed from runlevel %s", service, runlevel);
56 retval = true;
57 } else
58 eerror ("%s: failed to remove service `%s' from runlevel `%s': %s",
59 applet, service, runlevel, strerror (errno));
60 } else if (! rc_service_exists (service))
61 eerror ("%s: service `%s' does not exist", applet, service);
62 else if (! rc_runlevel_exists (runlevel))
63 eerror ("%s: runlevel `%s' does not exist", applet, runlevel);
64 else
65 retval = true;
66 return (retval);
67 }
68
69 static void show (char **runlevels, bool verbose)
70 {
71 char *service;
72 char **services = rc_services_in_runlevel (NULL);
73 char *runlevel;
74 int i;
75 int j;
76
77 STRLIST_FOREACH (services, service, i) {
78 char **in = NULL;
79 bool inone = false;
80
81 STRLIST_FOREACH (runlevels, runlevel, j) {
82 if (rc_service_in_runlevel (service, runlevel)) {
83 rc_strlist_add (&in, runlevel);
84 inone = true;
85 } else {
86 char buffer[PATH_MAX];
87 memset (buffer, ' ', strlen (runlevel));
88 buffer[strlen (runlevel)] = 0;
89 rc_strlist_add (&in, buffer);
90 }
91 }
92
93 if (! inone && ! verbose)
94 continue;
95
96 printf (" %20s |", service);
97 STRLIST_FOREACH (in, runlevel, j)
98 printf (" %s", runlevel);
99 printf ("\n");
100 rc_strlist_free (in);
101 }
102
103 rc_strlist_free (services);
104 }
105
106 #include "_usage.h"
107 #define getoptstring "adsv" getoptstring_COMMON
108 static struct option longopts[] = {
109 { "add", 0, NULL, 'a'},
110 { "delete", 0, NULL, 'd'},
111 { "show", 0, NULL, 's'},
112 { "verbose", 0, NULL, 'v'},
113 longopts_COMMON
114 { NULL, 0, NULL, 0}
115 };
116 #include "_usage.c"
117
118 #define DOADD (1 << 0)
119 #define DODELETE (1 << 1)
120 #define DOSHOW (1 << 2)
121
122 int rc_update (int argc, char **argv)
123 {
124 int i;
125 char *service = NULL;
126 char **runlevels = NULL;
127 char *runlevel;
128 int action = 0;
129 bool verbose = false;
130 int opt;
131 int retval = EXIT_FAILURE;
132
133 applet = argv[0];
134
135 while ((opt = getopt_long (argc, argv, getoptstring,
136 longopts, (int *) 0)) != -1)
137 {
138 switch (opt) {
139 case 'a':
140 action |= DOADD;
141 break;
142 case 'd':
143 action |= DODELETE;
144 break;
145 case 's':
146 action |= DOSHOW;
147 break;
148 case 'v':
149 verbose = true;
150 break;
151
152 case_RC_COMMON_GETOPT
153 }
154 }
155
156 if ((action & DOSHOW && action != DOSHOW) ||
157 (action & DOADD && action != DOADD) ||
158 (action & DODELETE && action != DODELETE))
159 eerrorx ("%s: cannot mix commands", applet);
160
161 /* We need to be backwards compatible */
162 if (! action) {
163 if (optind < argc) {
164 if (strcmp (argv[optind], "add") == 0)
165 action = DOADD;
166 else if (strcmp (argv[optind], "delete") == 0 ||
167 strcmp (argv[optind], "del") == 0)
168 action = DODELETE;
169 else if (strcmp (argv[optind], "show") == 0)
170 action = DOSHOW;
171 if (action)
172 optind++;
173 else
174 eerrorx ("%s: invalid command `%s'", applet, argv[optind]);
175 }
176 if (! action && opt)
177 action = DOSHOW;
178 }
179
180 if (optind >= argc) {
181 if (! action & DOSHOW)
182 eerrorx ("%s: no service specified", applet);
183 } else {
184 service = argv[optind];
185 optind++;
186
187 while (optind < argc)
188 if (rc_runlevel_exists (argv[optind]))
189 rc_strlist_add (&runlevels, argv[optind++]);
190 else {
191 rc_strlist_free (runlevels);
192 eerrorx ("%s: `%s' is not a valid runlevel", applet, argv[optind]);
193 }
194 }
195
196 if (action & DOSHOW) {
197 if (service)
198 rc_strlist_add (&runlevels, service);
199 if (! runlevels)
200 runlevels = rc_get_runlevels ();
201
202 show (runlevels, verbose);
203 retval = EXIT_SUCCESS;
204 } else {
205 if (! service)
206 eerror ("%s: no service specified", applet);
207 else if (! rc_service_exists (service))
208 eerror ("%s: service `%s' does not exist", applet, service);
209 else {
210 retval = EXIT_SUCCESS;
211 if (! runlevels)
212 rc_strlist_add (&runlevels, rc_get_runlevel ());
213 STRLIST_FOREACH (runlevels, runlevel, i) {
214 if (action & DOADD) {
215 if (! add (runlevel, service))
216 retval = EXIT_FAILURE;
217 } else if (action & DODELETE) {
218 if (! delete (runlevel, service))
219 retval = EXIT_FAILURE;
220 }
221 }
222 }
223 }
224
225 rc_strlist_free (runlevels);
226
227 return (retval);
228 }

  ViewVC Help
Powered by ViewVC 1.1.20