3
Copyright 2005 Stephan Kulow <coolo@kde.org>
4
Copyright 2005 Oswald Buddenhagen <ossi@kde.org>
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included
13
in all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
OTHER DEALINGS IN THE SOFTWARE.
23
Except as contained in this notice, the name of a copyright holder shall
24
not be used in advertising or otherwise to promote the sale, use or
25
other dealings in this Software without prior written authorization
26
from the copyright holder.
31
* xdm - display manager daemon
32
* Author: Keith Packard, MIT X Consortium
46
getNull(char ***opts ATTR_UNUSED, int *def ATTR_UNUSED, int *cur ATTR_UNUSED)
52
setNull(const char *opt ATTR_UNUSED, SdRec *sdr ATTR_UNUSED)
58
match(char *obuf, int *blen, const char *key, int klen)
61
if (memcmp(buf, key, klen) || !isspace(buf[klen]))
64
for (; isspace(*buf); buf++);
71
#define GRUB_MENU "/boot/grub/menu.lst"
73
static char *grubSetDefault;
77
getGrub(char ***opts, int *def, int *cur)
84
if (!grubSetDefault && !grub &&
85
!(grubSetDefault = locate("grub-set-default")) &&
86
!(grub = locate("grub")))
91
*opts = initStrArr(0);
93
if (!(f = fopen(GRUB_MENU, "r")))
94
return errno == ENOENT ? BO_NOMAN : BO_IO;
95
while ((len = fGets(line, sizeof(line), f)) != -1) {
96
for (linp = line; isspace(*linp); linp++, len--);
97
if ((ptr = match(linp, &len, "default", 7))) {
99
} else if ((ptr = match(linp, &len, "title", 5))) {
100
for (; isspace(ptr[len - 1]); len--);
101
*opts = addStrArr(*opts, ptr, len);
110
setGrub(const char *opt, SdRec *sdr)
117
if (!(f = fopen(GRUB_MENU, "r")))
118
return errno == ENOENT ? BO_NOMAN : BO_IO;
119
for (i = 0; (len = fGets(line, sizeof(line), f)) != -1;)
120
if ((ptr = match(line, &len, "title", 5))) {
121
if (!strcmp(ptr, opt)) {
124
sdr->bmstamp = mTime(GRUB_MENU);
136
if (sdRec.bmstamp != mTime(GRUB_MENU) &&
137
setGrub(sdRec.osname, &sdRec) != BO_OK)
140
if (grubSetDefault) {
141
/* The grub-set-default command must be used, which is
142
* not so good because there is no way of setting an
143
* entry for the next boot only. */
145
const char *args[] = { grubSetDefault, index, 0 };
146
sprintf(index, "%d", sdRec.osindex);
147
runAndWait((char **)args, environ);
149
/* The grub shell can be used with `savedefault'.
150
* That requires a (widely distributed) patch to grub, e.g.
151
* grub-0.97-once.patch. It won't work with a vanilla grub.*/
154
static const char *args[] = { 0, "--batch", "--no-floppy", 0 };
156
if ((f = pOpen((char **)args, 'w', &pid))) {
157
fprintf(f, "savedefault --default=%d --once\n", sdRec.osindex);
163
#define GRUB2_MENU "/boot/grub/grub.cfg"
165
static char *grubReboot;
168
getGrub2(char ***opts, int *def, int *cur)
172
int len, ret = BO_NOMAN, i;
175
if (!grubReboot && !(grubReboot = locate("grub-reboot")))
180
*opts = initStrArr(0);
182
if (!(f = fopen(GRUB2_MENU, "r")))
183
return errno == ENOENT ? BO_NOMAN : BO_IO;
184
while ((len = fGets(line, sizeof(line), f)) != -1) {
185
for (linp = line; isspace(*linp); linp++, len--);
186
if ((ptr = match(linp, &len, "set", 3)) && !memcmp(ptr, "default=\"${saved_entry}\"", 24)) {
188
} else if ((ptr = match(linp, &len, "menuentry", 9))) {
191
for (i = 0, linp++; *linp && *linp != '\''; linp++)
193
} else if (*linp == '"') {
194
for (i = 0, linp++; *linp && *linp != '"'; linp++) {
198
return BO_IO; /* Unexpected end */
211
for (i = 0; *linp && !isspace(*linp); linp++) {
212
if (*linp == '\\' && !*(++linp))
213
return BO_IO; /* Unexpected end */
217
*opts = addStrArr(*opts, ptr, i);
226
setGrub2(const char *opt, SdRec *sdr)
229
int def, cur, ret, i;
231
if ((ret = getGrub2(&opts, &def, &cur)) != BO_OK)
233
for (i = 0; opts[i]; i++) {
234
if (!strcmp(opts[i], opt)) {
236
sdr->bmstamp = mTime(GRUB2_MENU);
248
if (sdRec.bmstamp != mTime(GRUB2_MENU) &&
249
setGrub2(sdRec.osname, &sdRec) != BO_OK)
254
const char *args[] = { grubReboot, index, 0 };
255
sprintf(index, "%d", sdRec.osindex);
256
runAndWait((char **)args, environ);
263
getLilo(char ***opts, int *def, int *cur)
266
int cdef, pid, len, ret = BO_OK;
267
static const char *args[5] = { 0, "-w", "-v", "-q", 0 };
268
char buf[256], next[256];
270
if (!lilo && !(lilo = locate("lilo")))
274
if (!(f = pOpen((char **)args, 'r', &pid)))
279
if ((len = fGets(buf, sizeof(buf), f)) == -1) {
283
if (!memcmp(buf, "Images:", 7))
285
#define Ldeflin " Default boot command line:"
286
if (!memcmp(buf, Ldeflin, strlen(Ldeflin))) {
287
memcpy(next, buf + strlen(Ldeflin) + 2, len - strlen(Ldeflin) - 3);
288
next[len - strlen(Ldeflin) - 3] = 0;
293
*opts = initStrArr(0);
294
while ((len = fGets(buf, sizeof(buf), f)) != -1)
295
if (buf[0] == ' ' && buf[1] == ' ' && buf[2] != ' ') {
296
if (buf[len - 1] == '*') {
300
for (; buf[len - 1] == ' '; len--);
301
*opts = addStrArr(*opts, buf + 2, len - 2);
302
if (!strcmp((*opts)[cdef], next))
307
if (pClose(f, &pid)) {
316
setLilo(const char *opt, SdRec *sdr ATTR_UNUSED)
319
int def, cur, ret, i;
321
if ((ret = getLilo(&opts, &def, &cur)) != BO_OK)
326
for (i = 0; opts[i]; i++)
327
if (!strcmp(opts[i], opt))
340
static const char *args[5] = { 0, "-w", "-R", 0, 0 };
343
args[3] = sdRec.osname;
344
runAndWait((char **)args, environ);
347
static const struct {
348
int (*get)(char ***, int *, int *);
349
int (*set)(const char *, SdRec *);
350
void (*commit)(void);
352
{ getNull, setNull, 0 },
353
{ getGrub, setGrub, commitGrub },
354
{ getGrub2, setGrub2, commitGrub2 },
355
{ getLilo, setLilo, commitLilo },
359
getBootOptions(char ***opts, int *def, int *cur)
361
return bootOpts[bootManager].get(opts, def, cur);
365
setBootOption(const char *opt, SdRec *sdr)
372
if ((ret = bootOpts[bootManager].set(opt, sdr)) != BO_OK)
374
if (!strDup(&sdr->osname, opt))
375
return BO_IO; /* BO_NOMEM */
381
commitBootOption(void)
384
bootOpts[bootManager].commit();