diff --git a/release/sysinstall/tcpip.c b/release/sysinstall/tcpip.c index 8ec3fec0fbc3..017cc2b7e832 100644 --- a/release/sysinstall/tcpip.c +++ b/release/sysinstall/tcpip.c @@ -1,5 +1,5 @@ /* - * $Id: tcpip.c,v 1.1 1995/05/16 02:53:28 jkh Exp $ + * $Id: tcpip.c,v 1.3 1995/05/16 20:00:51 gpalmer Exp $ * * Copyright (c) 1995 * Gary J Palmer. All rights reserved. @@ -49,80 +49,98 @@ #include "rc.h" #include "sysinstall.h" +/* These are nasty, but they make the layout structure a lot easier ... */ + static char hostname[256], domainname[256], gateway[32], nameserver[32], iface[8]; static int okbutton, cancelbutton; static char ipaddr[32], netmask[32], extras[256]; +/* What the screen size is meant to be */ #define TCP_DIALOG_Y 0 #define TCP_DIALOG_X 8 #define TCP_DIALOG_WIDTH COLS - 16 #define TCP_DIALOG_HEIGHT LINES - 2 +/* The per interface set of records */ typedef struct _interface { - char ipaddr[32]; - char netmask[32]; - char extras[256]; - Device *dev; + char ipaddr[32]; + char netmask[32]; + char extras[256]; /* Extra stuff for ifconfig (link0, etc) */ + int valid; } Interface; /* The names and details of the available interfaces, for the list */ Interface if_list[INTERFACE_MAX]; char *iface_names[INTERFACE_MAX]; +/* The screen layout structure */ typedef struct _layout { - int y; + int y; /* x & Y co-ordinates */ int x; - int len; - int maxlen; - char *prompt; - char *help; - void *var; - int type; - void *obj; + int len; /* The size of the dialog on the screen */ + int maxlen; /* How much the user can type in ... */ + char *prompt; /* The string for the prompt */ + char *help; /* The display for the help line */ + void *var; /* The var to set when this changes */ + int type; /* The type of the dialog to create */ + void *obj; /* The obj pointer returned by libdialog */ } Layout; static Layout layout[] = { { 1, 2, 25, 255, "Host name:", "The name of your machine on a network, e.g. foo.bar.com", hostname, STRINGOBJ, NULL }, +#define LAYOUT_HOSTNAME 0 { 1, 35, 20, 255, "Domain name:", "The name of the domain that your machine is in, e.g. bar.com", domainname, STRINGOBJ, NULL }, +#define LAYOUT_DOMAINNAME 1 { 5, 2, 18, 15, "Gateway:", "IP address of host forwarding packets to non-local hosts or nets", gateway, STRINGOBJ, NULL }, +#define LAYOUT_GATEWAY 2 { 5, 35, 18, 15, "Name server:", "IP address of your local DNS server", nameserver, STRINGOBJ, NULL }, +#define LAYOUT_NAMESERVER 3 { 9, 2, 9, 6, - "Interface:", "One of potentially several network interfaces", + "Interface:", + "Network devices found on boot (use to exit from here)", iface, LISTOBJ, NULL }, +#define LAYOUT_IFACE 4 { 10, 18, 18, 15, "IP Address:", "The IP address to be used for your host - use 127.0.0.1 for loopback", ipaddr, STRINGOBJ, NULL }, +#define LAYOUT_IPADDR 5 { 10, 37, 18, 15, "Netmask:", "The netmask for your network, e.g. 0xffffff00 for a class C network", netmask, STRINGOBJ, NULL }, +#define LAYOUT_NETMASK 6 { 14, 18, 37, 255, "Extra options to ifconfig:", "Any options to ifconfig you'd like to specify manually", extras, STRINGOBJ, NULL }, +#define LAYOUT_EXTRAS 7 { 19, 10, 0, 0, "OK", "Select this if you are happy with these settings", &okbutton, BUTTONOBJ, NULL }, +#define LAYOUT_OKBUTTON 8 { 19, 30, 0, 0, "CANCEL", "Select this if you wish to cancel this screen", &cancelbutton, BUTTONOBJ, NULL }, +#define LAYOUT_CANCELBUTTON 9 { NULL }, }; #define _validByte(b) ((b) > 0 && (b) < 255) +/* A JKH special - inform the user of an unusal error in a controlled + fashion */ static void feepout(char *msg) { @@ -130,6 +148,7 @@ feepout(char *msg) dialog_notify(msg); } +/* Very basic IP address integrity check - could be drastically improved */ static int verifyIP(char *ip) { @@ -143,19 +162,26 @@ verifyIP(char *ip) return 0; } +/* Check for the settings on the screen - the per interface stuff is + moved to the main handling code now to do it on the fly - sigh */ + static int verifySettings(void) { if (!hostname[0]) feepout("Must specify a host name of some sort!"); +#if 0 else if (!verifyIP(ipaddr)) feepout("Invalid or missing value for IP address"); +#endif else if (gateway[0] && !verifyIP(gateway)) feepout("Invalid gateway IP address specified"); else if (nameserver[0] && !verifyIP(nameserver)) feepout("Invalid name server IP address specified"); +#if 0 else if (netmask[0] < '0' || netmask[0] > '9') feepout("Invalid or missing netmask"); +#endif else return 1; return 0; @@ -174,10 +200,12 @@ tcpOpenDialog(char *str) Device **devs; char old_iface[8]; + /* We need a curses window */ ds_win = newwin(LINES, COLS, 0, 0); if (ds_win == 0) msgFatal("Cannot open TCP/IP dialog window!!"); + /* Look for net.devices for us to configure */ devs = deviceFind(NULL, DEVICE_TYPE_NETWORK); if (!devs) { msgConfirm("Couldn't find any potential network devices!"); @@ -190,6 +218,7 @@ tcpOpenDialog(char *str) } n_iface = --n; + /* Setup a nice screen for us to splat stuff onto */ draw_box(ds_win, TCP_DIALOG_Y, TCP_DIALOG_X, TCP_DIALOG_HEIGHT, TCP_DIALOG_WIDTH, dialog_attr, border_attr); @@ -203,11 +232,13 @@ tcpOpenDialog(char *str) mvwaddstr(ds_win, TCP_DIALOG_Y + 9, TCP_DIALOG_X + 24, " Per Interface Configuration "); - + /* Initialise vars so that dialog has something to chew on */ strcpy(ipaddr, if_list[0].ipaddr); strcpy(netmask, if_list[0].netmask); strcpy(extras, if_list[0].extras); + /* Look up values already recorded with the system, or blank the + string variables ready to accept some new data */ tmp = getenv(VAR_HOSTNAME); if (tmp) strcpy(hostname, tmp); @@ -229,6 +260,8 @@ tcpOpenDialog(char *str) else bzero(nameserver, sizeof(nameserver)); + /* Loop over the layout list, create the objects, and add them + onto the chain of objects that dialog uses for traversal*/ n = 0; #define lt layout[n] while (lt.help != NULL) { @@ -256,38 +289,61 @@ tcpOpenDialog(char *str) n++; } max = n - 1; - + + /* Find the last object we can traverse to */ last = obj; while (last->next) last = last->next; - /* find the first object in the list */ + /* Find the first object in the list */ first = obj; while (first->prev) first = first->prev; + /* Some more initialisation before we go into the main input loop */ n = 0; cancelbutton = okbutton = 0; strcpy(iface, iface_names[0]); + if_list[0].valid = FALSE; strcpy(old_iface, iface); + /* Incoming user data - DUCK! */ while (!quit) { char help_line[80]; int i, len = strlen(lt.help); + /* Display the help line at the bottom of the screen */ for (i = 0; i < 79; i++) help_line[i] = (i < len) ? lt.help[i] : ' '; help_line[i] = '\0'; use_helpline(help_line); display_helpline(ds_win, LINES - 1, COLS - 1); + /* Ask for libdialog to do its stuff */ ret = PollObj(&obj); + /* We are in the Hostname field - calculate the domainname */ + if (n == 0) { + if ((tmp = index(hostname, '.')) != NULL) { + strncpy(domainname, tmp + 1, strlen(tmp + 1)); + domainname[strlen(tmp+1)] = '\0'; + RefreshStringObj(layout[1].obj); + } + } + + /* Handle special case stuff that libdialog misses. Sigh */ switch (ret) { + /* Bail out */ case SEL_ESC: quit = TRUE, cancel=TRUE; break; + /* This doesn't work for list dialogs. Oh well. Perhaps + should special case the move from the OK button ``up'' + to make it go to the interface list, but then it gets + awkward for the user to go back and correct screw up's + in the per-interface section */ + case KEY_UP: if (obj->prev !=NULL ) { obj = obj->prev; @@ -298,9 +354,13 @@ tcpOpenDialog(char *str) } break; + /* More special case handling - if we are at the interface + list, move to the OK button - the user hasn't selected + one of the entries in the list by pressing CR, so (s)he + must be wanting to skip to & */ case KEY_DOWN: - if (n == 7) { - n = 4; + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; } else if (obj->next != NULL) { obj = obj->next; @@ -311,21 +371,32 @@ tcpOpenDialog(char *str) } break; + /* Same as KEY_DOWN, but dialog has already move us to the + next object on the list, which makes this slightly + different. */ case SEL_TAB: - if (n == 7) { - n = 4; + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; } else if (obj->next != NULL) { ++n; } else { n = 0; } - if (n == 5) { - n = 8; + + /* This looks double dutch, but we have already MOVED onto + the next field, so we special case around getting to + that field, rather than moving off the previous + one. Hence we are really testing for + (n ==_IFACE) */ + + if (n == LAYOUT_IPADDR) { + n = LAYOUT_OKBUTTON; obj = ((obj->next)->next)->next; } break; + /* The user has pressed enter over a button object */ case SEL_BUTTON: if (cancelbutton) { cancel = TRUE, quit = TRUE; @@ -335,8 +406,12 @@ tcpOpenDialog(char *str) } break; + /* Generic CR handler */ case SEL_CR: + /* Has the user selected a new interface? */ if (strcmp(old_iface, iface)) { + /* Moved to a different condition for better handling */ +#if 0 /* First, find the old value */ n_iface = 0; while (strcmp(old_iface, iface_names[n_iface]) && @@ -345,10 +420,31 @@ tcpOpenDialog(char *str) if (iface_names[n_iface] == NULL) msgFatal("Erk - run off the end of the list of interfaces!"); + + /* Sanity check what the user supplied - this could probably + be better :-( */ + + if (!verifyIP(ipaddr)) { + feepout("Invalid or missing IP address!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + if (netmask[0] < '0' || netmask[0] > '9') { + feepout("Invalid or missing netmask!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + strcpy(if_list[n_iface].ipaddr, ipaddr); strcpy(if_list[n_iface].netmask, netmask); strcpy(if_list[n_iface].extras, extras); - + if_list[n_iface].valid = TRUE; +#endif /* if 0 */ /* Now go find the new location */ n_iface = 0; while (strcmp(iface, iface_names[n_iface]) && @@ -359,23 +455,62 @@ tcpOpenDialog(char *str) strcpy(ipaddr, if_list[n_iface].ipaddr); strcpy(netmask, if_list[n_iface].netmask); strcpy(extras, if_list[n_iface].extras); + if_list[n_iface].valid = FALSE; - RefreshStringObj(layout[5].obj); - RefreshStringObj(layout[6].obj); - RefreshStringObj(layout[7].obj); + RefreshStringObj(layout[LAYOUT_IPADDR].obj); + RefreshStringObj(layout[LAYOUT_NETMASK].obj); + RefreshStringObj(layout[LAYOUT_EXTRAS].obj); strcpy(old_iface, iface); } - if (n == 7) { - n = 4; + /* Loop back to the interface list from the extras box - + now we handle the case of saving out the data the user + typed in (and also do basic verification of it's + sanity) */ + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; + /* First, find the old value */ + n_iface = 0; + while (strcmp(old_iface, iface_names[n_iface]) && + (iface_names[n_iface] != NULL)) + ++n_iface; + + if (iface_names[n_iface] == NULL) + msgFatal("Erk - run off the end of the list of interfaces!"); + + /* Sanity check what the user supplied - this could probably + be better :-( */ + + if (!verifyIP(ipaddr)) { + feepout("Invalid or missing IP address!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + if (netmask[0] < '0' || netmask[0] > '9') { + feepout("Invalid or missing netmask!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + strcpy(if_list[n_iface].ipaddr, ipaddr); + strcpy(if_list[n_iface].netmask, netmask); + strcpy(if_list[n_iface].extras, extras); + if_list[n_iface].valid = TRUE; } else if (n < max) ++n; else n = 0; break; + /* This doesn't seem to work anymore - dunno why. Foo */ + case SEL_BACKTAB: if (n) --n; @@ -383,29 +518,50 @@ tcpOpenDialog(char *str) n = max; break; + /* They tried some key combination we don't support - tell them! */ default: beep(); } - - if (n == 1) { - if ((tmp = index(hostname, '.')) != NULL) { - strncpy(domainname, tmp + 1, strlen(tmp + 1)); - domainname[strlen(tmp+1)] = '\0'; - RefreshStringObj(layout[1].obj); - } + + /* BODGE ALERT! */ + if ((tmp = index(hostname, '.')) != NULL) { + strncpy(domainname, tmp + 1, strlen(tmp + 1)); + domainname[strlen(tmp+1)] = '\0'; + RefreshStringObj(layout[1].obj); } } + /* Clear this crap off the screen */ dialog_clear(); refresh(); + + /* We actually need to inform the rest of sysinstall about this + data now - if the user hasn't selected cancel, save the stuff + out to the environment via the variable_set layers */ if (!cancel) { + int foo; variable_set2(VAR_HOSTNAME, hostname); variable_set2(VAR_DOMAINNAME, domainname); if (gateway[0]) variable_set2(VAR_GATEWAY, gateway); if (nameserver[0]) variable_set2(VAR_NAMESERVER, nameserver); + + /* Loop over the per-interface data saving data which has been + validated ... */ + foo = 0; + for (foo = 0 ; foo < INTERFACE_MAX ; foo++) { + if (if_list[foo].valid == TRUE) { + char temp[512], ifn[64]; + sprintf(temp, "inet %s %s netmask %s", + if_list[foo].ipaddr, if_list[foo].extras, + if_list[foo].netmask); + sprintf(ifn, "ifconfig_%s", iface_names[foo]); + variable_set2(ifn, temp); + } + } + return 1; } diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c index 8ec3fec0fbc3..017cc2b7e832 100644 --- a/usr.sbin/sysinstall/tcpip.c +++ b/usr.sbin/sysinstall/tcpip.c @@ -1,5 +1,5 @@ /* - * $Id: tcpip.c,v 1.1 1995/05/16 02:53:28 jkh Exp $ + * $Id: tcpip.c,v 1.3 1995/05/16 20:00:51 gpalmer Exp $ * * Copyright (c) 1995 * Gary J Palmer. All rights reserved. @@ -49,80 +49,98 @@ #include "rc.h" #include "sysinstall.h" +/* These are nasty, but they make the layout structure a lot easier ... */ + static char hostname[256], domainname[256], gateway[32], nameserver[32], iface[8]; static int okbutton, cancelbutton; static char ipaddr[32], netmask[32], extras[256]; +/* What the screen size is meant to be */ #define TCP_DIALOG_Y 0 #define TCP_DIALOG_X 8 #define TCP_DIALOG_WIDTH COLS - 16 #define TCP_DIALOG_HEIGHT LINES - 2 +/* The per interface set of records */ typedef struct _interface { - char ipaddr[32]; - char netmask[32]; - char extras[256]; - Device *dev; + char ipaddr[32]; + char netmask[32]; + char extras[256]; /* Extra stuff for ifconfig (link0, etc) */ + int valid; } Interface; /* The names and details of the available interfaces, for the list */ Interface if_list[INTERFACE_MAX]; char *iface_names[INTERFACE_MAX]; +/* The screen layout structure */ typedef struct _layout { - int y; + int y; /* x & Y co-ordinates */ int x; - int len; - int maxlen; - char *prompt; - char *help; - void *var; - int type; - void *obj; + int len; /* The size of the dialog on the screen */ + int maxlen; /* How much the user can type in ... */ + char *prompt; /* The string for the prompt */ + char *help; /* The display for the help line */ + void *var; /* The var to set when this changes */ + int type; /* The type of the dialog to create */ + void *obj; /* The obj pointer returned by libdialog */ } Layout; static Layout layout[] = { { 1, 2, 25, 255, "Host name:", "The name of your machine on a network, e.g. foo.bar.com", hostname, STRINGOBJ, NULL }, +#define LAYOUT_HOSTNAME 0 { 1, 35, 20, 255, "Domain name:", "The name of the domain that your machine is in, e.g. bar.com", domainname, STRINGOBJ, NULL }, +#define LAYOUT_DOMAINNAME 1 { 5, 2, 18, 15, "Gateway:", "IP address of host forwarding packets to non-local hosts or nets", gateway, STRINGOBJ, NULL }, +#define LAYOUT_GATEWAY 2 { 5, 35, 18, 15, "Name server:", "IP address of your local DNS server", nameserver, STRINGOBJ, NULL }, +#define LAYOUT_NAMESERVER 3 { 9, 2, 9, 6, - "Interface:", "One of potentially several network interfaces", + "Interface:", + "Network devices found on boot (use to exit from here)", iface, LISTOBJ, NULL }, +#define LAYOUT_IFACE 4 { 10, 18, 18, 15, "IP Address:", "The IP address to be used for your host - use 127.0.0.1 for loopback", ipaddr, STRINGOBJ, NULL }, +#define LAYOUT_IPADDR 5 { 10, 37, 18, 15, "Netmask:", "The netmask for your network, e.g. 0xffffff00 for a class C network", netmask, STRINGOBJ, NULL }, +#define LAYOUT_NETMASK 6 { 14, 18, 37, 255, "Extra options to ifconfig:", "Any options to ifconfig you'd like to specify manually", extras, STRINGOBJ, NULL }, +#define LAYOUT_EXTRAS 7 { 19, 10, 0, 0, "OK", "Select this if you are happy with these settings", &okbutton, BUTTONOBJ, NULL }, +#define LAYOUT_OKBUTTON 8 { 19, 30, 0, 0, "CANCEL", "Select this if you wish to cancel this screen", &cancelbutton, BUTTONOBJ, NULL }, +#define LAYOUT_CANCELBUTTON 9 { NULL }, }; #define _validByte(b) ((b) > 0 && (b) < 255) +/* A JKH special - inform the user of an unusal error in a controlled + fashion */ static void feepout(char *msg) { @@ -130,6 +148,7 @@ feepout(char *msg) dialog_notify(msg); } +/* Very basic IP address integrity check - could be drastically improved */ static int verifyIP(char *ip) { @@ -143,19 +162,26 @@ verifyIP(char *ip) return 0; } +/* Check for the settings on the screen - the per interface stuff is + moved to the main handling code now to do it on the fly - sigh */ + static int verifySettings(void) { if (!hostname[0]) feepout("Must specify a host name of some sort!"); +#if 0 else if (!verifyIP(ipaddr)) feepout("Invalid or missing value for IP address"); +#endif else if (gateway[0] && !verifyIP(gateway)) feepout("Invalid gateway IP address specified"); else if (nameserver[0] && !verifyIP(nameserver)) feepout("Invalid name server IP address specified"); +#if 0 else if (netmask[0] < '0' || netmask[0] > '9') feepout("Invalid or missing netmask"); +#endif else return 1; return 0; @@ -174,10 +200,12 @@ tcpOpenDialog(char *str) Device **devs; char old_iface[8]; + /* We need a curses window */ ds_win = newwin(LINES, COLS, 0, 0); if (ds_win == 0) msgFatal("Cannot open TCP/IP dialog window!!"); + /* Look for net.devices for us to configure */ devs = deviceFind(NULL, DEVICE_TYPE_NETWORK); if (!devs) { msgConfirm("Couldn't find any potential network devices!"); @@ -190,6 +218,7 @@ tcpOpenDialog(char *str) } n_iface = --n; + /* Setup a nice screen for us to splat stuff onto */ draw_box(ds_win, TCP_DIALOG_Y, TCP_DIALOG_X, TCP_DIALOG_HEIGHT, TCP_DIALOG_WIDTH, dialog_attr, border_attr); @@ -203,11 +232,13 @@ tcpOpenDialog(char *str) mvwaddstr(ds_win, TCP_DIALOG_Y + 9, TCP_DIALOG_X + 24, " Per Interface Configuration "); - + /* Initialise vars so that dialog has something to chew on */ strcpy(ipaddr, if_list[0].ipaddr); strcpy(netmask, if_list[0].netmask); strcpy(extras, if_list[0].extras); + /* Look up values already recorded with the system, or blank the + string variables ready to accept some new data */ tmp = getenv(VAR_HOSTNAME); if (tmp) strcpy(hostname, tmp); @@ -229,6 +260,8 @@ tcpOpenDialog(char *str) else bzero(nameserver, sizeof(nameserver)); + /* Loop over the layout list, create the objects, and add them + onto the chain of objects that dialog uses for traversal*/ n = 0; #define lt layout[n] while (lt.help != NULL) { @@ -256,38 +289,61 @@ tcpOpenDialog(char *str) n++; } max = n - 1; - + + /* Find the last object we can traverse to */ last = obj; while (last->next) last = last->next; - /* find the first object in the list */ + /* Find the first object in the list */ first = obj; while (first->prev) first = first->prev; + /* Some more initialisation before we go into the main input loop */ n = 0; cancelbutton = okbutton = 0; strcpy(iface, iface_names[0]); + if_list[0].valid = FALSE; strcpy(old_iface, iface); + /* Incoming user data - DUCK! */ while (!quit) { char help_line[80]; int i, len = strlen(lt.help); + /* Display the help line at the bottom of the screen */ for (i = 0; i < 79; i++) help_line[i] = (i < len) ? lt.help[i] : ' '; help_line[i] = '\0'; use_helpline(help_line); display_helpline(ds_win, LINES - 1, COLS - 1); + /* Ask for libdialog to do its stuff */ ret = PollObj(&obj); + /* We are in the Hostname field - calculate the domainname */ + if (n == 0) { + if ((tmp = index(hostname, '.')) != NULL) { + strncpy(domainname, tmp + 1, strlen(tmp + 1)); + domainname[strlen(tmp+1)] = '\0'; + RefreshStringObj(layout[1].obj); + } + } + + /* Handle special case stuff that libdialog misses. Sigh */ switch (ret) { + /* Bail out */ case SEL_ESC: quit = TRUE, cancel=TRUE; break; + /* This doesn't work for list dialogs. Oh well. Perhaps + should special case the move from the OK button ``up'' + to make it go to the interface list, but then it gets + awkward for the user to go back and correct screw up's + in the per-interface section */ + case KEY_UP: if (obj->prev !=NULL ) { obj = obj->prev; @@ -298,9 +354,13 @@ tcpOpenDialog(char *str) } break; + /* More special case handling - if we are at the interface + list, move to the OK button - the user hasn't selected + one of the entries in the list by pressing CR, so (s)he + must be wanting to skip to & */ case KEY_DOWN: - if (n == 7) { - n = 4; + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; } else if (obj->next != NULL) { obj = obj->next; @@ -311,21 +371,32 @@ tcpOpenDialog(char *str) } break; + /* Same as KEY_DOWN, but dialog has already move us to the + next object on the list, which makes this slightly + different. */ case SEL_TAB: - if (n == 7) { - n = 4; + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; } else if (obj->next != NULL) { ++n; } else { n = 0; } - if (n == 5) { - n = 8; + + /* This looks double dutch, but we have already MOVED onto + the next field, so we special case around getting to + that field, rather than moving off the previous + one. Hence we are really testing for + (n ==_IFACE) */ + + if (n == LAYOUT_IPADDR) { + n = LAYOUT_OKBUTTON; obj = ((obj->next)->next)->next; } break; + /* The user has pressed enter over a button object */ case SEL_BUTTON: if (cancelbutton) { cancel = TRUE, quit = TRUE; @@ -335,8 +406,12 @@ tcpOpenDialog(char *str) } break; + /* Generic CR handler */ case SEL_CR: + /* Has the user selected a new interface? */ if (strcmp(old_iface, iface)) { + /* Moved to a different condition for better handling */ +#if 0 /* First, find the old value */ n_iface = 0; while (strcmp(old_iface, iface_names[n_iface]) && @@ -345,10 +420,31 @@ tcpOpenDialog(char *str) if (iface_names[n_iface] == NULL) msgFatal("Erk - run off the end of the list of interfaces!"); + + /* Sanity check what the user supplied - this could probably + be better :-( */ + + if (!verifyIP(ipaddr)) { + feepout("Invalid or missing IP address!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + if (netmask[0] < '0' || netmask[0] > '9') { + feepout("Invalid or missing netmask!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + strcpy(if_list[n_iface].ipaddr, ipaddr); strcpy(if_list[n_iface].netmask, netmask); strcpy(if_list[n_iface].extras, extras); - + if_list[n_iface].valid = TRUE; +#endif /* if 0 */ /* Now go find the new location */ n_iface = 0; while (strcmp(iface, iface_names[n_iface]) && @@ -359,23 +455,62 @@ tcpOpenDialog(char *str) strcpy(ipaddr, if_list[n_iface].ipaddr); strcpy(netmask, if_list[n_iface].netmask); strcpy(extras, if_list[n_iface].extras); + if_list[n_iface].valid = FALSE; - RefreshStringObj(layout[5].obj); - RefreshStringObj(layout[6].obj); - RefreshStringObj(layout[7].obj); + RefreshStringObj(layout[LAYOUT_IPADDR].obj); + RefreshStringObj(layout[LAYOUT_NETMASK].obj); + RefreshStringObj(layout[LAYOUT_EXTRAS].obj); strcpy(old_iface, iface); } - if (n == 7) { - n = 4; + /* Loop back to the interface list from the extras box - + now we handle the case of saving out the data the user + typed in (and also do basic verification of it's + sanity) */ + if (n == LAYOUT_EXTRAS) { + n = LAYOUT_IFACE; obj = (((first->next)->next)->next)->next; + /* First, find the old value */ + n_iface = 0; + while (strcmp(old_iface, iface_names[n_iface]) && + (iface_names[n_iface] != NULL)) + ++n_iface; + + if (iface_names[n_iface] == NULL) + msgFatal("Erk - run off the end of the list of interfaces!"); + + /* Sanity check what the user supplied - this could probably + be better :-( */ + + if (!verifyIP(ipaddr)) { + feepout("Invalid or missing IP address!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + if (netmask[0] < '0' || netmask[0] > '9') { + feepout("Invalid or missing netmask!"); + strcpy(iface, old_iface); + n = LAYOUT_IFACE; + obj = (((first->next)->next)->next)->next; + RefreshListObj(layout[LAYOUT_IFACE].obj); + } + + strcpy(if_list[n_iface].ipaddr, ipaddr); + strcpy(if_list[n_iface].netmask, netmask); + strcpy(if_list[n_iface].extras, extras); + if_list[n_iface].valid = TRUE; } else if (n < max) ++n; else n = 0; break; + /* This doesn't seem to work anymore - dunno why. Foo */ + case SEL_BACKTAB: if (n) --n; @@ -383,29 +518,50 @@ tcpOpenDialog(char *str) n = max; break; + /* They tried some key combination we don't support - tell them! */ default: beep(); } - - if (n == 1) { - if ((tmp = index(hostname, '.')) != NULL) { - strncpy(domainname, tmp + 1, strlen(tmp + 1)); - domainname[strlen(tmp+1)] = '\0'; - RefreshStringObj(layout[1].obj); - } + + /* BODGE ALERT! */ + if ((tmp = index(hostname, '.')) != NULL) { + strncpy(domainname, tmp + 1, strlen(tmp + 1)); + domainname[strlen(tmp+1)] = '\0'; + RefreshStringObj(layout[1].obj); } } + /* Clear this crap off the screen */ dialog_clear(); refresh(); + + /* We actually need to inform the rest of sysinstall about this + data now - if the user hasn't selected cancel, save the stuff + out to the environment via the variable_set layers */ if (!cancel) { + int foo; variable_set2(VAR_HOSTNAME, hostname); variable_set2(VAR_DOMAINNAME, domainname); if (gateway[0]) variable_set2(VAR_GATEWAY, gateway); if (nameserver[0]) variable_set2(VAR_NAMESERVER, nameserver); + + /* Loop over the per-interface data saving data which has been + validated ... */ + foo = 0; + for (foo = 0 ; foo < INTERFACE_MAX ; foo++) { + if (if_list[foo].valid == TRUE) { + char temp[512], ifn[64]; + sprintf(temp, "inet %s %s netmask %s", + if_list[foo].ipaddr, if_list[foo].extras, + if_list[foo].netmask); + sprintf(ifn, "ifconfig_%s", iface_names[foo]); + variable_set2(ifn, temp); + } + } + return 1; }