not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kdm / backend / bootman.c
blob071f8bcd279e3b6a85284a74f820be478b0f74c8
1 /*
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
10 documentation.
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
34 * Boot options
37 #include "dm.h"
38 #include "dm_error.h"
40 #include <string.h>
41 #include <unistd.h>
42 #include <stdio.h>
43 #include <ctype.h>
45 static int
46 getNull( char ***opts ATTR_UNUSED, int *def ATTR_UNUSED, int *cur ATTR_UNUSED )
48 return BO_NOMAN;
51 static int
52 setNull( const char *opt ATTR_UNUSED, SdRec *sdr ATTR_UNUSED )
54 return BO_NOMAN;
57 static char *
58 match( char *obuf, int *blen, const char *key, int klen )
60 char *buf = obuf;
61 if (memcmp( buf, key, klen ) || !isspace( buf[klen] ))
62 return 0;
63 buf += klen + 1;
64 for (; isspace( *buf ); buf++);
65 if (!*buf)
66 return 0;
67 *blen -= buf - obuf;
68 return buf;
71 #define GRUB_MENU "/boot/grub/menu.lst"
73 static char *grub;
75 static int
76 getGrub( char ***opts, int *def, int *cur )
78 FILE *f;
79 char *ptr, *linp;
80 int len;
81 char line[1000];
83 if (!grub && !(grub = locate( "grub" )))
84 return BO_NOMAN;
86 *def = 0;
87 *cur = -1;
88 *opts = initStrArr( 0 );
90 if (!(f = fopen( GRUB_MENU, "r" )))
91 return errno == ENOENT ? BO_NOMAN : BO_IO;
92 while ((len = fGets( line, sizeof(line), f )) != -1) {
93 for (linp = line; isspace( *linp ); linp++, len--);
94 if ((ptr = match( linp, &len, "default", 7 )))
95 *def = atoi( ptr );
96 else if ((ptr = match( linp, &len, "title", 5 ))) {
97 for (; isspace( ptr[len - 1] ); len--);
98 *opts = addStrArr( *opts, ptr, len );
101 fclose( f );
103 return BO_OK;
106 static int
107 setGrub( const char *opt, SdRec *sdr )
109 FILE *f;
110 char *ptr;
111 int len, i;
112 char line[1000];
114 if (!(f = fopen( GRUB_MENU, "r" )))
115 return errno == ENOENT ? BO_NOMAN : BO_IO;
116 for (i = 0; (len = fGets( line, sizeof(line), f )) != -1; )
117 if ((ptr = match( line, &len, "title", 5 ))) {
118 if (!strcmp( ptr, opt )) {
119 fclose( f );
120 sdr->osindex = i;
121 sdr->bmstamp = mTime( GRUB_MENU );
122 return BO_OK;
124 i++;
126 fclose( f );
127 return BO_NOENT;
130 static void
131 commitGrub( void )
133 FILE *f;
134 int pid;
135 static const char *args[] = { 0, "--batch", "--no-floppy", 0 };
137 if (sdRec.bmstamp != mTime( GRUB_MENU ) &&
138 setGrub( sdRec.osname, &sdRec ) != BO_OK)
139 return;
141 args[0] = grub;
142 if ((f = pOpen( (char **)args, 'w', &pid ))) {
143 fprintf( f, "savedefault --default=%d --once\n", sdRec.osindex );
144 pClose( f, &pid );
148 static char *lilo;
150 static int
151 getLilo( char ***opts, int *def, int *cur )
153 FILE *f;
154 int cdef, pid, len, ret = BO_OK;
155 static const char *args[5] = { 0, "-w", "-v", "-q", 0 };
156 char buf[256], next[256];
158 if (!lilo && !(lilo = locate( "lilo" )))
159 return BO_NOMAN;
161 args[0] = lilo;
162 if (!(f = pOpen( (char **)args, 'r', &pid )))
163 return BO_IO;
164 *opts = 0;
165 next[0] = 0;
166 for (;;) {
167 if ((len = fGets( buf, sizeof(buf), f )) == -1) {
168 ret = BO_NOMAN;
169 goto out;
171 if (!memcmp( buf, "Images:", 7 ))
172 break;
173 #define Ldeflin " Default boot command line:"
174 if (!memcmp( buf, Ldeflin, strlen(Ldeflin) )) {
175 memcpy( next, buf + strlen(Ldeflin) + 2, len - strlen(Ldeflin) - 3 );
176 next[len - strlen(Ldeflin) - 3] = 0;
179 cdef = *def = 0;
180 *cur = -1;
181 *opts = initStrArr( 0 );
182 while ((len = fGets( buf, sizeof(buf), f )) != -1)
183 if (buf[0] == ' ' && buf[1] == ' ' && buf[2] != ' ') {
184 if (buf[len - 1] == '*') {
185 *def = cdef;
186 len--;
188 for (; buf[len - 1] == ' '; len--);
189 *opts = addStrArr( *opts, buf + 2, len - 2 );
190 if (!strcmp( (*opts)[cdef], next ))
191 *cur = cdef;
192 cdef++;
194 out:
195 if (pClose( f, &pid )) {
196 if (*opts)
197 freeStrArr( *opts );
198 return BO_IO;
200 return ret;
203 static int
204 setLilo( const char *opt, SdRec *sdr ATTR_UNUSED )
206 char **opts;
207 int def, cur, ret, i;
209 if ((ret = getLilo( &opts, &def, &cur )) != BO_OK)
210 return ret;
211 if (!*opt)
212 opt = 0;
213 else {
214 for (i = 0; opts[i]; i++)
215 if (!strcmp( opts[i], opt ))
216 goto oke;
217 freeStrArr( opts );
218 return BO_NOENT;
220 oke:
221 freeStrArr( opts );
222 return BO_OK;
225 static void
226 commitLilo( void )
228 static const char *args[5] = { 0, "-w", "-R", 0, 0 };
230 args[0] = lilo;
231 args[3] = sdRec.osname;
232 runAndWait( (char **)args, environ );
235 static struct {
236 int (*get)( char ***, int *, int * );
237 int (*set)( const char *, SdRec * );
238 void (*commit)( void );
239 } bootOpts[] = {
240 { getNull, setNull, 0 },
241 { getGrub, setGrub, commitGrub },
242 { getLilo, setLilo, commitLilo },
246 getBootOptions( char ***opts, int *def, int *cur )
248 return bootOpts[bootManager].get( opts, def, cur );
252 setBootOption( const char *opt, SdRec *sdr )
254 int ret;
256 if (sdr->osname) {
257 free( sdr->osname );
258 sdr->osname = 0;
260 if (opt) {
261 if ((ret = bootOpts[bootManager].set( opt, sdr )) != BO_OK)
262 return ret;
263 if (!strDup( &sdr->osname, opt ))
264 return BO_IO; /* BO_NOMEM */
266 return BO_OK;
269 void
270 commitBootOption( void )
272 if (sdRec.osname) {
273 bootOpts[bootManager].commit();
275 free( sdRec.osname );
276 sdRec.osname = 0;