1 /* -*- c -*- ------------------------------------------------------------- *
3 * Copyright 2004-2006 Murali Krishnan Ganapathy - All Rights Reserved
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 * Boston MA 02111-1307, USA; either version 2 of the License, or
9 * (at your option) any later version; incorporated herein by reference.
11 * ----------------------------------------------------------------------- */
14 #define NULL ((void *) 0)
19 #include "passwords.h"
25 #define MAX_CMD_LINE_LENGTH 514
27 typedef struct s_xtra
{
28 long ipappend
; // Stores the ipappend flag to send (useful for PXELINUX only)
29 char *argsmenu
; // Stores the name of menu which contains options for the given RUN item
30 char *perms
; // stores the permissions required to activate the item
33 typedef t_xtra
*pt_xtra
; // Pointer to extra datastructure
35 // Types of dot commands for which caller takes responsibility of handling
36 // In some case some commands may not make sense, it is up to the caller
37 // to handle cases which do not make sense
38 typedef enum {QUIT_CMD
, REPEAT_CMD
, ENTER_CMD
, ESCAPE_CMD
} t_dotcmd
;
41 /*----------------- Global Variables */
44 #define GUEST_USER "guest"
46 // for local commands. return value of execdotcmd
50 char username
[12]; // Name of user currently using the system
52 int PWD_ROW
; // Line number where user authentication happens
53 int EDIT_ROW
; // row where User Tab
55 char loginstr
[] = "<L>ogin ";
58 int vmode
; // The video mode we want to be in
59 char timeoutcmd
[MAX_CMD_LINE_LENGTH
]; // Command to execute on timeout
60 char totaltimeoutcmd
[MAX_CMD_LINE_LENGTH
]; // Command to execute on totaltimeout
62 char QUITSTR
[] = ".quit"; // same as exit
63 char IGNORESTR
[]=".ignore"; // same as repeat, wait
65 /*---------------- End globals */
67 // returns pointer to first non-space char
68 // and advances end of str by removing trailing spaces
69 char * strip(char *str
)
72 if (!str
) return NULL
;
78 // mark start of string or record the last visited non-space char
79 if (!s
) s
=p
; else e
=p
;
83 *(++e
)='\0'; // kill string earlier
87 // executes a list of % separated commands
88 // non-dot commands are assumed to be syslinux commands
89 // All syslinux commands are appended with the contents of kerargs
90 // If it fails (kernel not found) then the next one is tried in the
92 // returns QUIT_CMD or RPT_CMD
93 t_dotcmd
execdotcmd(const char *cmd
, char *defcmd
, const char *kerargs
)
95 char cmdline
[MAX_CMD_LINE_LENGTH
];
96 char dotcmd
[MAX_CMD_LINE_LENGTH
];
97 char *curr
,*next
,*p
,*args
;
103 while (*next
) { // if something to do
105 p
= strchr(next
,'%');
108 while (*p
== ' ') p
--;
109 *(++p
)='\0'; // remove trailing spaces
111 if (*defcmd
) { // execute defcmd next
113 defcmd
=NULL
; // exec def cmd only once
116 // now we just need to execute the command "curr"
118 if (curr
[0] != '.') { // just run the kernel
119 strcpy(cmdline
,curr
);
120 if (kerargs
) strcat(cmdline
,kerargs
);
121 runsyslinuximage(cmdline
,0); // No IPAppend
122 } else { // We have a DOT command
123 // split command into command and args (may be empty)
125 while ( (*args
!= ' ') && (*args
!= '\0') ) args
++;
126 if (*args
) { // found a space
128 while (*args
== ' ') args
++; // skip over spaces
130 if ( (strcmp(curr
,".exit")==0) ||
131 (strcmp(curr
,".quit")==0)
134 if ( (strcmp(curr
,".repeat")==0) ||
135 (strcmp(curr
,".ignore")==0) ||
136 (strcmp(curr
,".wait")==0)
139 if (strcmp(curr
,".beep")==0) {
140 if ((args
) && ('0' <= args
[0]) && (args
[0] <= '9'))
143 for (;ctr
>0; ctr
--) beep();
145 if (strcmp(curr
,".help")==0) runhelp(args
);
148 return RPT_CMD
; // by default we do not quit
152 TIMEOUTCODE
timeout(const char *cmd
)
155 c
= execdotcmd(cmd
,".wait",NULL
);
166 TIMEOUTCODE
ontimeout(void)
168 return timeout(timeoutcmd
);
171 TIMEOUTCODE
ontotaltimeout(void)
173 return timeout(totaltimeoutcmd
);
176 void keys_handler(t_menusystem
* ms
__attribute__ (( unused
)), t_menuitem
* mi
, int scancode
)
180 if (getscreensize(1, &nr
, &nc
)) {
181 /* Unknown screen size? */
186 if ( (scancode
== KEY_F1
) && (mi
->helpid
!= 0xFFFF) ) { // If scancode of F1 and non-trivial helpid
187 runhelpsystem(mi
->helpid
);
190 // If user hit TAB, and item is an "executable" item
191 // and user has privileges to edit it, edit it in place.
192 if ((scancode
== KEY_TAB
) && (mi
->action
== OPT_RUN
) &&
193 (EDIT_ROW
< nr
) && (EDIT_ROW
> 0) &&
194 (isallowed(username
,"editcmd") || isallowed(username
,"root"))) {
195 // User typed TAB and has permissions to edit command line
197 csprint("Command line:",0x07);
198 editstring(mi
->data
,ACTIONLEN
);
200 cprint(' ',0x07,nc
-1);
204 t_handler_return
login_handler(t_menusystem
*ms
, t_menuitem
*mi
)
215 if (PWD_ROW
< 0) return rv
; // No need to authenticate
217 if (mi
->item
== loginstr
) { /* User wants to login */
218 if (getscreensize(1, &nr
, &nc
)) {
219 /* Unknown screen size? */
225 csprint("Enter Username: ",0x07);
226 getstring(login
, sizeof username
);
229 csprint("Enter Password: ",0x07);
230 getpwd(pwd
, sizeof pwd
);
234 if (authenticate_user(login
,pwd
))
236 strcpy(username
,login
);
237 strcpy(logoutstr
,"<L>ogout ");
238 strcat(logoutstr
,username
);
239 mi
->item
= logoutstr
; // Change item to read "Logout"
240 rv
.refresh
= 1; // refresh the screen (as item contents changed)
242 else strcpy(username
,GUEST_USER
);
244 else // User needs to logout
246 strcpy(username
,GUEST_USER
);
247 strcpy(logoutstr
,"");
254 t_handler_return
check_perms(t_menusystem
*ms
, t_menuitem
*mi
)
259 (void) ms
; // To keep compiler happy
261 x
= (pt_xtra
) mi
->extra_data
;
262 perms
= ( x
? x
->perms
: NULL
);
263 if (!perms
) return ACTION_VALID
;
265 if (isallowed(username
,"root") || isallowed(username
,perms
)) // If allowed
267 else return ACTION_INVALID
;
270 // Compute the full command line to add and if non-trivial
271 // prepend the string prepend to final command line
272 // Assume cmdline points to buffer long enough to hold answer
273 void gencommand(pt_menuitem mi
, char *cmdline
)
277 strcat(cmdline
,mi
->data
);
278 x
= (pt_xtra
) mi
->extra_data
;
279 if ( (x
) && (x
->argsmenu
)) gen_append_line(x
->argsmenu
,cmdline
);
283 // run the given command together with additional options which may need passing
284 void runcommand(pt_menuitem mi
)
290 line
= (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH
);
292 x
= (pt_xtra
) mi
->extra_data
;
293 ipappend
= (x
? x
->ipappend
: 0);
295 runsyslinuximage(line
,x
->ipappend
);
299 // set the extra info for the specified menu item.
300 void set_xtra(pt_menuitem mi
, const char *argsmenu
, const char *perms
, unsigned int helpid
, long ipappend
)
303 int bad_argsmenu
, bad_perms
, bad_ipappend
;
305 mi
->extra_data
= NULL
; // initalize
306 mi
->helpid
= helpid
; // set help id
308 if (mi
->action
!= OPT_RUN
) return;
310 bad_argsmenu
= bad_perms
= bad_ipappend
= 0;
311 if ( (argsmenu
==NULL
) || (strlen(argsmenu
)==0)) bad_argsmenu
= 1;
312 if ( (perms
==NULL
) || (strlen(perms
)==0)) bad_perms
= 1;
313 if ( ipappend
==0) bad_ipappend
= 1;
315 if (bad_argsmenu
&& bad_perms
&& bad_ipappend
) return;
317 xtra
= (pt_xtra
) malloc(sizeof(t_xtra
));
318 mi
->extra_data
= (void *) xtra
;
319 xtra
->argsmenu
= xtra
->perms
= NULL
;
320 xtra
->ipappend
= ipappend
;
322 xtra
->argsmenu
= (char *) malloc(sizeof(char)*(strlen(argsmenu
)+1));
323 strcpy(xtra
->argsmenu
,argsmenu
);
326 xtra
->perms
= (char *) malloc(sizeof(char)*(strlen(perms
)+1));
327 strcpy(xtra
->perms
,perms
);
328 mi
->handler
= &check_perms
;
336 char exitcmd
[MAX_CMD_LINE_LENGTH
];
337 char exitcmdroot
[MAX_CMD_LINE_LENGTH
];
338 char onerrcmd
[MAX_CMD_LINE_LENGTH
];
339 char startfile
[MAX_CMD_LINE_LENGTH
];
340 char *ecmd
; // effective exit command or onerrorcmd
342 char skipcmd
[MAX_CMD_LINE_LENGTH
];
343 int timeout
; // time in multiples of 0.1 seconds
344 int totaltimeout
; // time in multiples of 0.1 seconds
345 t_dotcmd dotrv
; // to store the return value of execdotcmd
348 strcpy(username
,GUEST_USER
);
349 /* ---- Initializing menu system parameters --- */
351 skipbits
= SHIFT_PRESSED
| CAPSLOCK_ON
;
354 strcpy(onerrcmd
,".beep 2 % % .help hlp00025.txt % .exit");
355 strcpy(exitcmd
,".exit");
356 strcpy(exitcmdroot
,"");
357 // If not specified exitcmdroot = exitcmd
358 if (exitcmdroot
[0] == '\0') strcpy(exitcmdroot
,exitcmd
);
361 strcpy(timeoutcmd
,".wait");
363 strcpy(totaltimeoutcmd
,"chain.c32 hd 0");
364 strcpy(startfile
,"hlp00026.txt");
366 init_help("/isolinux/help");
367 init_passwords("/isolinux/password");
368 init_menusystem(" COMBOOT Menu System ");
369 set_window_size(1,1,21,79);
371 // Register the ontimeout handler, with a time out of 10 seconds
372 reg_ontimeout(ontimeout
,timeout
*10,0);
373 reg_ontotaltimeout(ontotaltimeout
,totaltimeout
*10);
375 // Register menusystem handlers
376 reg_handler(HDLR_KEYS
,&keys_handler
);
377 /* ---- End of initialization --- */
379 /* ------- MENU netmenu ----- */
380 add_named_menu("netmenu"," Init Network ",-1);
382 curr
= add_item("<N>one","Dont start network",OPT_RADIOITEM
,"network=no",0);
383 set_xtra(curr
,"","",65535,0); // Set associated extra info
386 curr
= add_item("<d>hcp","Use DHCP",OPT_RADIOITEM
,"network=dhcp",0);
387 set_xtra(curr
,"","",65535,0); // Set associated extra info
390 /* ------- MENU testing ----- */
391 add_named_menu("testing"," Testing ",-1);
393 curr
= add_item("<M>emory Test","Perform extensive memory testing",OPT_RUN
,"memtest",0);
394 set_xtra(curr
,"","",25,3); // Set associated extra info
397 curr
= add_item("<I>nvisible","You dont see this",OPT_INVISIBLE
,"",0);
398 set_xtra(curr
,"","",65535,0); // Set associated extra info
401 curr
= add_item("<E>xit menu","Go one level up",OPT_EXITMENU
,"",0);
402 set_xtra(curr
,"","",65535,0); // Set associated extra info
405 /* ------- MENU rescue ----- */
406 add_named_menu("rescue"," Rescue Options ",-1);
408 curr
= add_item("<L>inux Rescue","Run linresc",OPT_RUN
,"linresc",0);
409 set_xtra(curr
,"","",65535,0); // Set associated extra info
412 curr
= add_item("<D>os Rescue","dosresc",OPT_RUN
,"dosresc",0);
413 set_xtra(curr
,"","",65535,0); // Set associated extra info
416 curr
= add_item("<W>indows Rescue","winresc",OPT_RUN
,"winresc",0);
417 set_xtra(curr
,"","",65535,0); // Set associated extra info
420 curr
= add_item("<E>xit this menu","Go one level up",OPT_EXITMENU
,"",0);
421 set_xtra(curr
,"","",65535,0); // Set associated extra info
424 /* ------- MENU prep ----- */
425 add_named_menu("prep"," Prep options ",-1);
427 curr
= add_item("<b>aseurl by IP?","Specify gui baseurl by IP address",OPT_CHECKBOX
,"baseurl=http://192.168.0.1",0);
428 set_xtra(curr
,"","",65535,0); // Set associated extra info
431 curr
= add_item("<m>ountcd?","Mount the cdrom drive?",OPT_CHECKBOX
,"mountcd",0);
432 set_xtra(curr
,"","",65535,0); // Set associated extra info
435 curr
= add_item("Network Initialization","How to initialise network device?",OPT_RADIOMENU
,"netmenu",0);
436 set_xtra(curr
,"","",65535,0); // Set associated extra info
439 curr
= add_item("","",OPT_SEP
,"",0);
440 set_xtra(curr
,"","",65535,0); // Set associated extra info
443 curr
= add_item("Reinstall <w>indows","Re-install the windows side of a dual boot setup",OPT_CHECKBOX
,"repair=win",0);
444 set_xtra(curr
,"","",65535,0); // Set associated extra info
447 curr
= add_item("Reinstall <l>inux","Re-install the linux side of a dual boot setup",OPT_CHECKBOX
,"repair=lin",0);
448 set_xtra(curr
,"","",65535,0); // Set associated extra info
451 curr
= add_item("","",OPT_SEP
,"",0);
452 set_xtra(curr
,"","",65535,0); // Set associated extra info
455 curr
= add_item("<R>un prep now","Execute prep with the above options",OPT_RUN
,"prep",0);
456 set_xtra(curr
,"prep","",65535,0); // Set associated extra info
459 curr
= add_item("<E>xit this menu","Go up one level",OPT_EXITMENU
,"",0);
460 set_xtra(curr
,"","",65535,0); // Set associated extra info
463 /* ------- MENU main ----- */
464 add_named_menu("main"," Main Menu ",-1);
466 curr
= add_item(loginstr
,"Login/Logout of authentication system",OPT_RUN
,NULL
,0);
467 curr
->helpid
= 65535;
468 curr
->handler
= &login_handler
;
470 curr
= add_item("<P>repare","prep",OPT_RUN
,"prep",0);
471 set_xtra(curr
,"","",65535,0); // Set associated extra info
474 curr
= add_item("<P>rep options...","Options for prep",OPT_SUBMENU
,"prep",0);
475 set_xtra(curr
,"","",65535,0); // Set associated extra info
478 curr
= add_item("<R>escue options...","Troubleshoot a system",OPT_SUBMENU
,"rescue",0);
479 set_xtra(curr
,"","",26,0); // Set associated extra info
482 curr
= add_item("<T>esting...","Options to test hardware",OPT_SUBMENU
,"testing",0);
483 set_xtra(curr
,"","",65535,0); // Set associated extra info
486 curr
= add_item("<E>xit to prompt","Exit the menu system",OPT_EXITMENU
,"",0);
487 set_xtra(curr
,"","",65535,0); // Set associated extra info
489 /* ------- END OF MENU declarations ----- */
491 // Check if we should skip the menu altogether
492 quit
= 0; // Dont skip the menu
493 if (getshiftflags() & skipbits
) { // we must skip the menu altogther and execute skipcmd
494 dotrv
= execdotcmd(skipcmd
,".beep%.exit",NULL
); // Worst case we beep and exit
495 if (dotrv
== QUIT_CMD
) quit
= 1;
498 // Switch vide mode if required
499 if (vmode
!= 0xFF) setvideomode(vmode
);
501 // Do we have a startfile to display?
502 if (startfile
[0] != '\0') runhelp(startfile
);
505 while (quit
== 0) { // As long as quit is zero repeat
506 curr
= showmenus(find_menu_num("main")); // Initial menu is the one called "main"
509 if (curr
->action
== OPT_RUN
) {
510 ecmd
= (char *)malloc(sizeof(char)*MAX_CMD_LINE_LENGTH
);
511 gencommand(curr
,ecmd
);
512 temp
= (curr
->extra_data
? ((pt_xtra
)curr
->extra_data
)->ipappend
: 0);
513 runsyslinuximage(ecmd
,temp
);
514 // kernel not found so execute the appropriate dot command
515 dotrv
= execdotcmd(onerrcmd
,".quit",ecmd
); // pass bad cmdline as arg
516 if (dotrv
== QUIT_CMD
) quit
= 1;
517 free(ecmd
); ecmd
= NULL
;
519 else csprint("Error in programming!",0x07);
521 // find effective exit command
522 ecmd
= ( isallowed(username
,"root") ? exitcmdroot
: exitcmd
);
523 dotrv
= execdotcmd(ecmd
,".repeat",NULL
);
524 quit
= (dotrv
== QUIT_CMD
? 1 : 0); // should we exit now
528 // Deallocate space used and quit