summaryrefslogtreecommitdiff
path: root/com32/cmenu/complex.c
blob: 94627c4f79878ee996a83913c27958a3e24364c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
/* -*- c -*- ------------------------------------------------------------- *
 *
 *   Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
 *   Boston MA 02111-1307, USA; either version 2 of the License, or
 *   (at your option) any later version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

#ifndef NULL
#define NULL ((void *) 0)
#endif

#include "menu.h"
#include "com32io.h"
#include "help.h"
#include "passwords.h"
#include "des.h"
#include <stdlib.h>
#include <stdio.h>

/* Global variables */
char infoline[160];
char buffer[80];

// Different network options
static char nonet[] = "<n>etwork [none]";
static char dhcpnet[]="<n>etwork [dhcp]";
static char statnet[]="<n>etwork [static]";

static char loginstr[] = "<L>ogin  ";
static char logoutstr[]= "<L>ogout ";

struct {
    unsigned int baseurl : 1; // Do we need to specify by url
    unsigned int mountcd : 1; // Should we mount the cd
    unsigned int winrep  : 1; // Want to repair windows?
    unsigned int linrep  : 1; // Want to repair linux?
} flags;

// Some menu options
t_menuitem *baseurl,*mountcd,*network,*runprep,*winrep,*linrep;
t_menuitem * stat,*dhcp,*none,*prepopt,*secret;

// all the menus we are going to declare
unsigned char TESTING,RESCUE,MAIN,PREPMENU,NETMENU,LONGMENU,SECRETMENU;

char username[12]; // Name of user currently using the system

/* End globals */

TIMEOUTCODE ontimeout()
{
  beep();
  return CODE_WAIT;
}


#define INFLINE 22
#define PWDLINE 3
#define PWDPROMPT 21
#define PWDCOLUMN 60
#define PWDATTR 0x74
#define EDITPROMPT 21

void keys_handler(t_menusystem *ms, t_menuitem *mi,unsigned int scancode)
{
   char nc;

   if ((scancode >> 8) == F1) { // If scancode of F1
      runhelpsystem(mi->helpid);
   }
   // If user hit TAB, and item is an "executable" item
   // and user has privileges to edit it, edit it in place.
   if (((scancode & 0xFF) == 0x09) && (mi->action == OPT_RUN) &&
       (isallowed(username,"editcmd") || isallowed(username,"root"))) {
     nc = getnumcols();
     // User typed TAB and has permissions to edit command line
     gotoxy(EDITPROMPT,1,ms->menupage);
     csprint("Command line:",0x07);
     editstring(mi->data,ACTIONLEN);
     gotoxy(EDITPROMPT,1,ms->menupage);
     cprint(' ',0x07,nc-1,ms->menupage);
   }
}

t_handler_return login_handler(t_menusystem *ms, t_menuitem *mi)
{
  (void)mi; // Unused
  char pwd[40];
  char login[40];
  char nc;
  t_handler_return rv;

  if (mi->item == loginstr) { /* User wants to login */
    nc = getnumcols();
    gotoxy(PWDPROMPT,1,ms->menupage);
    csprint("Enter Username: ",0x07);
    getstring(login, sizeof username);
    gotoxy(PWDPROMPT,1,ms->menupage);
    cprint(' ',0x07,nc,ms->menupage);
    csprint("Enter Password: ",0x07);
    getpwd(pwd, sizeof pwd);
    gotoxy(PWDPROMPT,1,ms->menupage);
    cprint(' ',0x07,nc,ms->menupage);

    if (authenticate_user(login,pwd))
    {
      strcpy(username,login);
      mi->item = logoutstr; // Change item to read "Logout"
    }
    else strcpy(username,GUEST_USER);
  }
  else // User needs to logout
  {
    strcpy(username,GUEST_USER);
    mi->item = loginstr;
  }

  if (strcmp(username,GUEST_USER)==0)
  {
     prepopt->action = OPT_INACTIVE;
     secret->action = OPT_INVISIBLE;
  }
  else
  {
     prepopt->action = OPT_SUBMENU;
     prepopt->itemdata.radiomenunum = PREPMENU;
     secret->action = OPT_SUBMENU;
     secret->itemdata.submenunum = SECRETMENU;
  }
  rv.valid = 0;
  rv.refresh = 1;
  return rv;
}

void msys_handler(t_menusystem *ms, t_menuitem *mi)
{
    char nc;
    void *v;
    nc = getnumcols(); // Get number of columns

    gotoxy(PWDLINE,PWDCOLUMN,ms->menupage);
    csprint("User: ",PWDATTR);
    cprint(ms->fillchar,ms->fillattr,sizeof username,ms->menupage);
    gotoxy(PWDLINE,PWDCOLUMN +6,ms->menupage);
    csprint(username,PWDATTR);

    if (mi->parindex != PREPMENU) // If we are not in the PREP MENU
    {
        gotoxy(INFLINE,0,ms->menupage);
        cprint(' ',0x07,nc,ms->menupage);
        gotoxy(INFLINE+1,0,ms->menupage);
        cprint(' ',0x07,nc,ms->menupage);
        return;
    }
    strcpy (infoline," ");
    if (flags.baseurl) strcat(infoline,"baseurl=http://192.168.11.12/gui ");
    if (flags.mountcd) strcat(infoline,"mountcd=yes ");
    v = (void *)network->data;
    if (v!=NULL) // Some network option specified
      {
	strcat(infoline,"network=");
	strcat(infoline,(char *)(((t_menuitem *)v)->data));
      }
    if (flags.winrep) strcat(infoline,"repair=win ");
    if (flags.linrep) strcat(infoline,"repair=lin ");

    gotoxy(INFLINE,0,ms->menupage);
    cprint(' ',0x07,nc,ms->menupage);
    gotoxy(INFLINE+1,0,ms->menupage);
    cprint(' ',0x07,nc,ms->menupage);
    gotoxy(INFLINE,0,ms->menupage);
    csprint("Kernel Arguments:",0x07);
    gotoxy(INFLINE,17,ms->menupage);
    csprint(infoline,0x07);
}

t_handler_return network_handler(t_menusystem *ms, t_menuitem *mi)
{
  // mi=network since this is handler only for that.
  (void)ms; // Unused

  if (mi->data == (void *)none) mi->item = nonet;
  if (mi->data == (void *)stat) mi->item = statnet;
  if (mi->data == (void *)dhcp) mi->item = dhcpnet;
  return ACTION_INVALID;  // VALID or INVALID does not matter
}

t_handler_return checkbox_handler(t_menusystem *ms, t_menuitem *mi)
{
  (void)ms; /* Unused */

    if (mi->action != OPT_CHECKBOX) return ACTION_INVALID;

    if (strcmp(mi->data,"baseurl") == 0) flags.baseurl = (mi->itemdata.checked ? 1 : 0);
    if (strcmp(mi->data,"winrepair") == 0) {
        if (mi->itemdata.checked)
        {
            flags.winrep = 1;
            linrep->action = OPT_INACTIVE;
        }
        else
        {
            flags.winrep = 0;
            linrep->action = OPT_CHECKBOX;
        }
    }
    if (strcmp(mi->data,"linrepair") == 0) {
        if (mi->itemdata.checked)
        {
            flags.linrep = 1;
            winrep->action = OPT_INACTIVE;
        }
        else
        {
            flags.winrep = 0;
            winrep->action = OPT_CHECKBOX;
        }
    }
    if (strcmp(mi->data,"mountcd") == 0) flags.mountcd = (mi->itemdata.checked ? 1 : 0);
  return ACTION_VALID;
}

/*
  Clears keyboard buffer and then
  wait for stepsize*numsteps milliseconds for user to press any key
  checks for keypress every stepsize milliseconds.
  Returns: 1 if user pressed a key (not read from the buffer),
           0 if time elapsed
*/
int checkkeypress(int stepsize, int numsteps)
{
  int i;
  clearkbdbuf();
  for (i=0; i < numsteps; i++)
    {
      if (checkkbdbuf()) return 1;
      sleep(stepsize);
    }
  return 0;
}

int main()
{
  t_menuitem * curr;
  char cmd[160];
  char ip[30];

  // Set default username as guest
  strcpy(username,GUEST_USER);

  // Switch video mode here
  // setvideomode(0x18); // or whatever mode you want

  // Choose the default title and setup default values for all attributes....
  init_passwords("/isolinux/password");
  init_help("/isolinux/help");
  init_menusystem(NULL);
  set_window_size(1,1,20,78); // Leave some space around

  // Choose the default values for all attributes and char's
  // -1 means choose defaults (Actually the next 4 lines are not needed)
  //set_normal_attr (-1,-1,-1,-1);
  //set_status_info (-1,-1); // Display status on the last line
  //set_title_info  (-1,-1);
  //set_misc_info(-1,-1,-1,-1);

  // Register the menusystem handler
  reg_handler(HDLR_SCREEN,&msys_handler);
  reg_handler(HDLR_KEYS,&keys_handler);
  // Register the ontimeout handler, with a time out of 10 seconds
  reg_ontimeout(ontimeout,1000,0);

  NETMENU = add_menu(" Init Network ",-1);
  none = add_item("<N>one","Dont start network",OPT_RADIOITEM,"no ",0);
  dhcp = add_item("<d>hcp","Use DHCP",OPT_RADIOITEM,"dhcp ",0);
  stat = add_item("<s>tatic","Use static IP I will specify later",OPT_RADIOITEM,"static ",0);

  TESTING = add_menu(" Testing ",-1);
  set_menu_pos(5,55);
  add_item("<M>emory Test","Perform extensive memory testing",OPT_RUN, "memtest",0);
  add_item("<I>nvisible","You dont see this",OPT_INVISIBLE,"junk",0);
  add_item("<E>xit this menu","Go one level up",OPT_EXITMENU,"exit",0);

  RESCUE = add_menu(" Rescue Options ",-1);
  add_item("<L>inux Rescue","linresc",OPT_RUN,"linresc",0);
  add_item("<D>os Rescue","dosresc",OPT_RUN,"dosresc",0);
  add_item("<W>indows Rescue","winresc",OPT_RUN,"winresc",0);
  add_item("<E>xit this menu","Go one level up",OPT_EXITMENU,"exit",0);

  PREPMENU = add_menu(" Prep options ",-1);
  baseurl = add_item("<b>aseurl by IP?","Specify gui baseurl by IP address",OPT_CHECKBOX,"baseurl",0);
  mountcd = add_item("<m>ountcd?","Mount the cdrom drive?",OPT_CHECKBOX,"mountcd",0);
  network = add_item(dhcpnet,"How to initialise network device?",OPT_RADIOMENU,NULL,NETMENU);
  add_sep();
  winrep  = add_item("Reinstall <w>indows","Re-install the windows side of a dual boot setup",OPT_CHECKBOX,"winrepair",0);
  linrep  = add_item("Reinstall <l>inux","Re-install the linux side of a dual boot setup",OPT_CHECKBOX,"linrepair",0);
  add_sep();
  runprep = add_item("<R>un prep now","Execute prep with the above options",OPT_RUN,"prep",0);
  add_item("<E>xit this menu","Go up one level",OPT_EXITMENU,"exitmenu",0);
  baseurl->handler = &checkbox_handler;
  mountcd->handler = &checkbox_handler;
  winrep->handler = &checkbox_handler;
  linrep->handler = &checkbox_handler;
  network->handler = &network_handler;
  flags.baseurl = 0;
  flags.mountcd = 0;
  flags.winrep = 0;
  flags.linrep = 0;

  SECRETMENU = add_menu(" Secret Menu ",-1);
  add_item("secret 1","Secret",OPT_RUN,"A",0);
  add_item("secret 2","Secret",OPT_RUN,"A",0);

  LONGMENU = add_menu(" Long Menu ",40); // Override default here
  add_item("<A>a","Aa",OPT_RUN,"A",0);
  add_item("<B>b","Ab",OPT_RUN,"A",0);
  add_item("<C>","A",OPT_RUN,"A",0);
  add_item("<D>","A",OPT_RUN,"A",0);
  add_item("<E>","A",OPT_RUN,"A",0);
  add_item("<F>","A",OPT_RUN,"A",0);
  add_item("<G>","A",OPT_RUN,"A",0);
  add_item("<H>","A",OPT_RUN,"A",0);
  add_item("<I>","A",OPT_RUN,"A",0);
  add_item("<J>","A",OPT_RUN,"A",0);
  add_item("<K>","A",OPT_RUN,"A",0);
  add_item("<L>","A",OPT_RUN,"A",0);
  add_item("<J>","A",OPT_RUN,"A",0);
  add_item("<K>","A",OPT_RUN,"A",0);
  add_item("<L>","A",OPT_RUN,"A",0);
  add_item("<M>","A",OPT_RUN,"A",0);
  add_item("<N>","A",OPT_RUN,"A",0);
  add_item("<O>","A",OPT_RUN,"A",0);
  add_item("<P>","A",OPT_RUN,"A",0);
  add_item("<Q>","A",OPT_RUN,"A",0);
  add_item("<R>","A",OPT_RUN,"A",0);
  add_item("<S>","A",OPT_RUN,"A",0);
  add_item("<T>","A",OPT_RUN,"A",0);
  add_item("<U>","A",OPT_RUN,"A",0);
  add_item("<V>","A",OPT_RUN,"A",0);
  add_item("<W>","A",OPT_RUN,"A",0);
  add_item("<X>","A",OPT_RUN,"A",0);
  add_item("<Y>","A",OPT_RUN,"A",0);
  add_item("<Z>","A",OPT_RUN,"A",0);
  add_item("<1>","A",OPT_RUN,"A",0);
  add_item("<2>","A",OPT_RUN,"A",0);
  add_item("<3>","A",OPT_RUN,"A",0);
  add_item("<4>","A",OPT_RUN,"A",0);
  add_item("<5>","A",OPT_RUN,"A",0);
  add_item("<6>","A",OPT_RUN,"A",0);
  add_item("<7>","A",OPT_RUN,"A",0);
  add_item("<8>","A",OPT_RUN,"A",0);
  add_item("<9>","A",OPT_RUN,"A",0);

  MAIN = add_menu(" Main Menu ",8);
  curr = add_item(loginstr,"Login as a privileged user",OPT_RUN,NULL,0);
  set_item_options(-1,23);
  curr->handler = &login_handler;

  add_item("<P>repare","prep",OPT_RUN,"prep",0);
  set_item_options(-1,24);
  prepopt = add_item("<P>rep options...","Options for prep image: Requires authenticated user",OPT_INACTIVE,NULL,PREPMENU);
  set_item_options(-1,25);

  add_item("<R>escue options...","Troubleshoot a system",OPT_SUBMENU,NULL,RESCUE);
  set_item_options(-1,26);
  add_item("<T>esting...","Options to test hardware",OPT_SUBMENU,NULL,TESTING);
  set_item_options(-1,27);
  add_item("<L>ong Menu...","test menu system",OPT_SUBMENU,NULL,LONGMENU);
  set_item_options(-1,28);
  secret = add_item("<S>ecret Menu...","Secret menu",OPT_INVISIBLE,NULL,SECRETMENU);
  set_item_options(-1,29);
  add_item("<E>xit to prompt", "Exit the menu system", OPT_EXITMENU, "exit", 0);
  set_item_options(-1,30);
  csprint("Press any key within 5 seconds to show menu...",0x07);
  if (!checkkeypress(100,50)) // Granularity of 100 milliseconds
    {
      csprint("Sorry! Time's up.\r\n",0x07);
      return 1;
    }
  else clearkbdbuf(); // Just in case user pressed something important
  curr = showmenus(MAIN);
  if (curr)
  {
        if (curr->action == OPT_RUN)
        {
            strcpy(cmd,curr->data);
            if (curr == runprep)
            {
                strcat(cmd,infoline);
		if (network->data == (void *)stat) // We want static
                {
                    csprint("Enter IP address (last two octets only): ",0x07);
                    strcpy(ip, "Junk");
                    editstring(ip, sizeof ip);
                    strcat(cmd,"ipaddr=192.168.");
                    strcat(cmd,ip);
                }
            }
            if (issyslinux())
               runsyslinuxcmd(cmd);
            else csprint(cmd,0x07);
            return 1; // Should not happen when run from SYSLINUX
        }
  }
  // If user quits the menu system, control comes here
  // If you want to execute some specific command uncomment the next two lines

  // if (syslinux) runcommand(YOUR_COMMAND_HERE);
  // else csprint(YOUR_COMMAND_HERE,0x07);

  // Deallocate space used for these data structures
  close_passwords();
  close_help();
  close_menusystem();

  // Return to prompt
  return 0;
}