#include <arpa/inet.h>
#include <errno.h>
#include <popt.h>
#include <resolv.h>
#include <net/if.h>
#include <newt.h>
#include <stdlib.h>
#include <string.h>

#ifdef __STANDALONE__
#include <netdb.h>
#include <libintl.h>
#include <locale.h>

#define _(String) gettext((String))

#define LOADER_BACK 2
#define LOADER_ERROR -1;

#include "net.h"

#else

# include "isys/dns.h"
#include "pump/pump.h"

#include "kickstart.h"
#include "lang.h"
#include "loader.h"
#include "log.h"
#include "net.h"
#include "windows.h"

#endif /* __STANDALONE__ */

struct intfconfig_s {
   newtComponent ipEntry, nmEntry, gwEntry, nsEntry;
   char * ip, * nm, * gw, * ns;
};

typedef int int32;

#ifdef __STANDALONE__
static FILE * logfile = NULL;

#define FL_TESTING(foo) 0

void logMessage(const char * s, ...) {
       va_list args;

       if (!logfile) return;
       va_start(args, s);

       fprintf(logfile, "* ");
       vfprintf(logfile, s, args);
       fprintf(logfile, "\n");
       fflush(logfile);

       va_end(args);

       return;
}

/* yawn. This really should be in newt. */
void winStatus(int width, int height, char * title,
                              char * text, ...) {
       newtComponent t, f;
       char * buf = NULL;
       int size = 0;
       int i = 0;
       va_list args;

       va_start(args, text);

       do {
               size += 1000;
               if (buf) free(buf);
               buf = malloc(size);
               i = vsnprintf(buf, size, text, args);
       } while (i == size);

       va_end(args);

       newtCenteredWindow(width, height, title);

       t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
       newtTextboxSetText(t, buf);
       f = newtForm(NULL, NULL, 0);

       free(buf);

       newtFormAddComponent(f, t);

       newtDrawForm(f);
       newtRefresh();
       newtFormDestroy(f);
}

#endif

static void ipCallback(newtComponent co, void * dptr) {
   struct intfconfig_s * data = dptr;
   struct in_addr ipaddr, nmaddr, addr;
   char * ascii;
   int broadcast, network;

   if (co == data->ipEntry) {
       if (strlen(data->ip) && !strlen(data->nm)) {
           if (inet_aton(data->ip, &ipaddr)) {
               ipaddr.s_addr = ntohl(ipaddr.s_addr);
               if (((ipaddr.s_addr & 0xFF000000) >> 24) <= 127)
                   ascii = "255.0.0.0";
               else if (((ipaddr.s_addr & 0xFF000000) >> 24) <= 191)
                   ascii = "255.255.0.0";
               else
                   ascii = "255.255.255.0";
               newtEntrySet(data->nmEntry, ascii, 1);
           }
       }
   } else if (co == data->nmEntry) {
       if (!strlen(data->ip) || !strlen(data->nm)) return;
       if (!inet_aton(data->ip, &ipaddr)) return;
       if (!inet_aton(data->nm, &nmaddr)) return;

       network = ipaddr.s_addr & nmaddr.s_addr;
       broadcast = (ipaddr.s_addr & nmaddr.s_addr) | (~nmaddr.s_addr);

       if (!strlen(data->gw)) {
           addr.s_addr = htonl(ntohl(broadcast) - 1);
           newtEntrySet(data->gwEntry, inet_ntoa(addr), 1);
       }

       if (!strlen(data->ns)) {
           addr.s_addr = htonl(ntohl(network) + 1);
           newtEntrySet(data->nsEntry, inet_ntoa(addr), 1);
       }
   }
}

#ifndef __STANDALONE__
int nfsGetSetup(char ** hostptr, char ** dirptr) {
   struct newtWinEntry entries[3];
   char * newServer = *hostptr ? strdup(*hostptr) : NULL;
   char * newDir = *dirptr ? strdup(*dirptr) : NULL;
   int rc;

   entries[0].text = _("NFS server name:");
   entries[0].value = &newServer;
   entries[0].flags = NEWT_FLAG_SCROLL;
   entries[1].text = _("Red Hat directory:");
   entries[1].value = &newDir;
   entries[1].flags = NEWT_FLAG_SCROLL;
   entries[2].text = NULL;
   entries[2].value = NULL;

   rc = newtWinEntries(_("NFS Setup"),
               _("Please enter the following information:\n"
                 "\n"
                 "    o the name or IP number of your NFS server\n"
                 "    o the directory on that server containing\n"
                 "      Red Hat Linux for your architecture"), 60, 5, 15,
               24, entries, _("OK"), _("Back"), NULL);

   if (rc == 2) {
       if (newServer) free(newServer);
       if (newDir) free(newDir);
       return LOADER_BACK;
   }

   if (*hostptr) free(*hostptr);
   if (*dirptr) free(*dirptr);
   *hostptr = newServer;
   *dirptr = newDir;

   return 0;
}
#endif

static void fillInIpInfo(struct networkDeviceConfig * cfg) {
   if (!(cfg->dev.set & PUMP_INTFINFO_HAS_BROADCAST)) {
       *((int32 *) &cfg->dev.broadcast) = (*((int32 *) &cfg->dev.ip) &
                          *((int32 *) &cfg->dev.netmask)) |
                          ~(*((int32 *) &cfg->dev.netmask));
       cfg->dev.set |= PUMP_INTFINFO_HAS_BROADCAST;
   }

   if (!(cfg->dev.set & PUMP_INTFINFO_HAS_NETWORK)) {
       *((int32 *) &cfg->dev.network) =
               *((int32 *) &cfg->dev.ip) &
               *((int32 *) &cfg->dev.netmask);
       cfg->dev.set |= PUMP_INTFINFO_HAS_NETWORK;
   }
}

#ifndef __STANDALONE__
void initLoopback(void) {
   struct pumpNetIntf dev;

   strcpy(dev.device, "lo");
   inet_aton("127.0.0.1", &dev.ip);
   inet_aton("255.0.0.0", &dev.netmask);
   dev.set = PUMP_INTFINFO_HAS_NETMASK | PUMP_INTFINFO_HAS_IP;

   pumpSetupInterface(&dev);
}
#endif

static void dhcpBoxCallback(newtComponent co, void * ptr) {
   struct intfconfig_s * c = ptr;

   newtEntrySetFlags(c->ipEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
   newtEntrySetFlags(c->gwEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
   newtEntrySetFlags(c->nmEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
   newtEntrySetFlags(c->nsEntry, NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE);
}

int readNetConfig(char * device, struct networkDeviceConfig * cfg, int flags) {
   newtComponent text, f, okay, back, answer, dhcpCheckbox;
   newtGrid grid, subgrid, buttons;
   struct networkDeviceConfig newCfg;
   struct intfconfig_s c;
   int i;
   struct in_addr addr;
   char dhcpChoice;
   char * chptr;

   text = newtTextboxReflowed(-1, -1,
               _("Please enter the IP configuration for this machine. Each "
                 "item should be entered as an IP address in dotted-decimal "
                 "notation (for example, 1.2.3.4)."), 50, 5, 10, 0);

   subgrid = newtCreateGrid(2, 4);
   newtGridSetField(subgrid, 0, 0, NEWT_GRID_COMPONENT,
                    newtLabel(-1, -1, _("IP address:")),
                    0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
   newtGridSetField(subgrid, 0, 1, NEWT_GRID_COMPONENT,
                    newtLabel(-1, -1, _("Netmask:")),
                    0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
   newtGridSetField(subgrid, 0, 2, NEWT_GRID_COMPONENT,
                    newtLabel(-1, -1, _("Default gateway (IP):")),
                    0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
   newtGridSetField(subgrid, 0, 3, NEWT_GRID_COMPONENT,
                    newtLabel(-1, -1, _("Primary nameserver:")),
                    0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);

   c.ipEntry = newtEntry(-1, -1, NULL, 16, &c.ip, 0);
   c.nmEntry = newtEntry(-1, -1, NULL, 16, &c.nm, 0);
   c.gwEntry = newtEntry(-1, -1, NULL, 16, &c.gw, 0);
   c.nsEntry = newtEntry(-1, -1, NULL, 16, &c.ns, 0);

   if (!cfg->isDynamic) {
       if (cfg->dev.set & PUMP_INTFINFO_HAS_IP)
           newtEntrySet(c.ipEntry, inet_ntoa(cfg->dev.ip), 1);

       if (cfg->dev.set & PUMP_INTFINFO_HAS_NETMASK)
           newtEntrySet(c.nmEntry, inet_ntoa(cfg->dev.netmask), 1);

       if (cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)
           newtEntrySet(c.gwEntry, inet_ntoa(cfg->dev.gateway), 1);

       if (cfg->dev.numDns)
           newtEntrySet(c.nsEntry, inet_ntoa(cfg->dev.dnsServers[0]), 1);

       dhcpChoice = ' ';
   } else {
       dhcpChoice = '*';
   }

   dhcpCheckbox = newtCheckbox(-1, -1,
               _("Use dynamic IP configuration (BOOTP/DHCP)"),
               dhcpChoice, NULL, &dhcpChoice);
   newtComponentAddCallback(dhcpCheckbox, dhcpBoxCallback, &c);
   if (dhcpChoice == '*') dhcpBoxCallback(dhcpCheckbox, &c);

   newtGridSetField(subgrid, 1, 0, NEWT_GRID_COMPONENT, c.ipEntry,
                    1, 0, 0, 0, 0, 0);
   newtGridSetField(subgrid, 1, 1, NEWT_GRID_COMPONENT, c.nmEntry,
                    1, 0, 0, 0, 0, 0);
   newtGridSetField(subgrid, 1, 2, NEWT_GRID_COMPONENT, c.gwEntry,
                    1, 0, 0, 0, 0, 0);
   newtGridSetField(subgrid, 1, 3, NEWT_GRID_COMPONENT, c.nsEntry,
                    1, 0, 0, 0, 0, 0);

   buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);

   grid = newtCreateGrid(1, 4);
   newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
                    0, 0, 0, 1, 0, 0);
   newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, dhcpCheckbox,
                    0, 0, 0, 1, 0, 0);
   newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, subgrid,
                    0, 0, 0, 1, 0, 0);
   newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
                    0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);

   f = newtForm(NULL, NULL, 0);
   newtGridAddComponentsToForm(grid, f, 1);
   newtGridWrappedWindow(grid, _("Configure TCP/IP"));
   newtGridFree(grid, 1);

   newtComponentAddCallback(c.ipEntry, ipCallback, &c);
   newtComponentAddCallback(c.nmEntry, ipCallback, &c);

   do {
       answer = newtRunForm(f);

       if (answer == back) {
           newtFormDestroy(f);
           newtPopWindow();
           return LOADER_BACK;
       }

       if (dhcpChoice == ' ') {
           i = 0;
           memset(&newCfg, 0, sizeof(newCfg));
           if (*c.ip && inet_aton(c.ip, &addr)) {
               i++;
               newCfg.dev.ip = addr;
               newCfg.dev.set |= PUMP_INTFINFO_HAS_IP;
           }

           if (*c.nm && inet_aton(c.nm, &addr)) {
               i++;
               newCfg.dev.netmask = addr;
               newCfg.dev.set |= PUMP_INTFINFO_HAS_NETMASK;
           }

           if (i != 2) {
               newtWinMessage(_("Missing Information"), _("Retry"),
                           _("You must enter both a valid IP address and a "
                             "netmask."));
           }

           strcpy(newCfg.dev.device, device);
           newCfg.isDynamic = 0;
       } else {
           if (!FL_TESTING(flags)) {
               winStatus(50, 3, _("Dynamic IP"),
                         _("Sending request for IP information..."),
                           0);
               chptr = pumpDhcpRun(device, 0, 0, NULL, &newCfg.dev, NULL);
               newtPopWindow();
           } else {
               chptr = NULL;
           }

           if (!chptr) {
               i = 2;
               cfg->isDynamic = 1;
           } else {
               logMessage("pump told us: %s", chptr);
               i = 0;
           }
       }
   } while (i != 2);

   cfg->dev = newCfg.dev;

   fillInIpInfo(cfg);

   if (!(cfg->dev.set & PUMP_NETINFO_HAS_GATEWAY)) {
       if (*c.gw && inet_aton(c.gw, &addr)) {
           cfg->dev.gateway = addr;
           cfg->dev.set |= PUMP_NETINFO_HAS_GATEWAY;
       }
   }

   if (!(cfg->dev.numDns)) {
       if (*c.ns && inet_aton(c.ns, &addr)) {
           cfg->dev.dnsServers[0] = addr;
           cfg->dev.numDns = 1;
       }
   }

   newtPopWindow();

   if (!FL_TESTING(flags)) {
       configureNetwork(cfg);
       findHostAndDomain(cfg, flags);
       writeResolvConf(cfg);
   }

   return 0;
}

int configureNetwork(struct networkDeviceConfig * dev) {
   pumpSetupInterface(&dev->dev);

   if (dev->dev.set & PUMP_NETINFO_HAS_GATEWAY)
       pumpSetupDefaultGateway(&dev->dev.gateway);

   return 0;
}

int writeNetInfo(const char * fn, struct networkDeviceConfig * dev) {
   FILE * f;

   if (!(f = fopen(fn, "w"))) return -1;

   fprintf(f, "DEVICE=%s\n", dev->dev.device);
   if (dev->isDynamic) {
       fprintf(f, "BOOTPROTO=dhcp\n");
   } else {
       fprintf(f, "BOOTPROTO=static\n");
       fprintf(f, "IPADDR=%s\n", inet_ntoa(dev->dev.ip));
       fprintf(f, "NETMASK=%s\n", inet_ntoa(dev->dev.netmask));
       if (dev->dev.set & PUMP_NETINFO_HAS_GATEWAY)
           fprintf(f, "GATEWAY=%s\n", inet_ntoa(dev->dev.gateway));
   }
   if (dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME)
       fprintf(f, "HOSTNAME=%s\n", dev->dev.hostname);
   if (dev->dev.set & PUMP_NETINFO_HAS_DOMAIN)
       fprintf(f, "DOMAIN=%s\n", dev->dev.domain);

   fclose(f);

   return 0;
}

int writeResolvConf(struct networkDeviceConfig * net) {
   char * filename = "/etc/resolv.conf";
   FILE * f;
   int i;

   if (!(net->dev.set & PUMP_NETINFO_HAS_DOMAIN) && !net->dev.numDns)
       return LOADER_ERROR;

   f = fopen(filename, "w");
   if (!f) {
       logMessage("Cannot create %s: %s\n", filename, strerror(errno));
       return LOADER_ERROR;
   }

   if (net->dev.set & PUMP_NETINFO_HAS_DOMAIN)
       fprintf(f, "search %s\n", net->dev.domain);

   for (i = 0; i < net->dev.numDns; i++)
       fprintf(f, "nameserver %s\n", inet_ntoa(net->dev.dnsServers[i]));

   fclose(f);

   res_init();         /* reinit the resolver so DNS changes take affect */

   return 0;
}

int findHostAndDomain(struct networkDeviceConfig * dev, int flags) {
   char * name, * chptr;
#ifdef __STANDALONE__
   struct hostent * he;
#endif

   if (!FL_TESTING(flags)) {
       writeResolvConf(dev);
   }

   if (!(dev->dev.set & PUMP_NETINFO_HAS_HOSTNAME)) {
       winStatus(40, 3, _("Hostname"),
                 _("Determining host name and domain..."));
#ifdef __STANDALONE__
       he = gethostbyaddr( (char *) &dev->dev.ip, sizeof (dev->dev.ip), AF_INET);
       name = he->h_name;
#else
       name = mygethostbyaddr(inet_ntoa(dev->dev.ip));
#endif
       newtPopWindow();

       if (!name) {
           logMessage("reverse name lookup failed");
           return 1;
       }

       logMessage("reverse name lookup worked");

       dev->dev.hostname = strdup(name);
       dev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME;
   } else {
       name = dev->dev.hostname;
   }

   if (!(dev->dev.set & PUMP_NETINFO_HAS_DOMAIN)) {
       for (chptr = name; *chptr && (*chptr != '.'); chptr++) ;
       if (*chptr == '.') {
           if (dev->dev.domain) free(dev->dev.domain);
           dev->dev.domain = strdup(chptr + 1);
           dev->dev.set |= PUMP_NETINFO_HAS_DOMAIN;
       }
   }

   return 0;
}

#ifndef __STANDALONE__
int kickstartNetwork(char * device, struct networkDeviceConfig * netDev,
                    char * bootProto, int flags) {
   char ** ksArgv;
   int ksArgc;
   int netSet, rc;
   char * arg, * chptr;
   poptContext optCon;
   struct in_addr * parseAddress;
   struct poptOption ksOptions[] = {
           { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0 },
           { "gateway", '\0', POPT_ARG_STRING, NULL, 'g' },
           { "ip", '\0', POPT_ARG_STRING, NULL, 'i' },
           { "nameserver", '\0', POPT_ARG_STRING, NULL, 'n' },
           { "netmask", '\0', POPT_ARG_STRING, NULL, 'm' },
           { 0, 0, 0, 0, 0 }
   };

   if (!bootProto)
       bootProto = "dhcp";

   if (!bootProto) {
       if (ksGetCommand(KS_CMD_NETWORK, NULL, &ksArgc, &ksArgv)) {
           /* This is for compatibility with RH 5.0 */
           ksArgv = alloca(sizeof(*ksArgv) * 1);
           ksArgv[0] = "network";
           ksArgc = 1;
       }

       optCon = poptGetContext(NULL, ksArgc, ksArgv, ksOptions, 0);
       while ((rc = poptGetNextOpt(optCon)) >= 0) {
           parseAddress = NULL;
           netSet = 0;

           arg = poptGetOptArg(optCon);

           switch (rc) {
             case 'g':
               parseAddress = &netDev->dev.gateway;
               netSet = PUMP_NETINFO_HAS_GATEWAY;
               break;

             case 'i':
               parseAddress = &netDev->dev.ip;
               netSet = PUMP_INTFINFO_HAS_IP;
               break;

             case 'n':
               parseAddress = &netDev->dev.dnsServers[netDev->dev.numDns++];
               netSet = PUMP_NETINFO_HAS_DNS;
               break;

             case 'm':
               parseAddress = &netDev->dev.netmask;
               netSet = PUMP_INTFINFO_HAS_NETMASK;
               break;
           }

           if (!inet_aton(arg, parseAddress)) {
               logMessage("bad ip number in network command: %s", arg);
               return -1;
           }

           netDev->dev.set |= netSet;
       }

       if (rc < -1) {
           newtWinMessage(_("kickstart"),  _("OK"),
                      _("bad argument to kickstart network command %s: %s"),
                      poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
                      poptStrerror(rc));
       } else {
           poptFreeContext(optCon);
       }
   }

   if (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")) {
       logMessage("sending dhcp request through device %s", device);
       winStatus(50, 3, _("Dynamic IP"),
                 _("Sending request for IP information..."),
                   0);

       chptr = pumpDhcpRun(device, 0, 0, NULL, &netDev->dev, NULL);
       newtPopWindow();
       if (chptr) {
           logMessage("pump told us: %s", chptr);
           return -1;
       }
       netDev->isDynamic = 1;
   }

   fillInIpInfo(netDev);
   configureNetwork(netDev);
   findHostAndDomain(netDev, flags);
   writeResolvConf(netDev);

   return 0;
}
#endif

#ifdef __STANDALONE__
int main(int argc, char **argv) {
   int netSet, rc;
   int x;
   char * bootProto = NULL;
   char * device = NULL;
   char * hostname = NULL;
   char * domain = NULL;
   char * arg;
   char path[256];
   char roottext[80];
   poptContext optCon;
   struct networkDeviceConfig *netDev;
   struct in_addr * parseAddress;
   struct poptOption Options[] = {
           POPT_AUTOHELP
           { "bootproto", '\0', POPT_ARG_STRING, &bootProto, 0,
             _("Boot protocol to use"), "(dhcp|bootp|none)" },
           { "gateway", '\0', POPT_ARG_STRING, NULL, 'g',
             _("Network gateway"), NULL },
           { "ip", '\0', POPT_ARG_STRING, NULL, 'i',
             _("IP address"), NULL },
           { "nameserver", '\0', POPT_ARG_STRING, NULL, 'n',
             _("Nameserver"), NULL },
           { "netmask", '\0', POPT_ARG_STRING, NULL, 'm',
             _("Netmask"), NULL },
           { "hostname", '\0', POPT_ARG_STRING, &hostname, 0,
             _("Hostname"), NULL
           },
           { "domain", '\0', POPT_ARG_STRING, &domain, 0,
             _("Domain name"), NULL
           },
           { "device", 'd', POPT_ARG_STRING, &device, 0,
             _("Network device"), NULL
           },
           { 0, 0, 0, 0, 0 }
   };


   netDev = malloc(sizeof(struct networkDeviceConfig));
   memset(netDev,'\0',sizeof(struct networkDeviceConfig));
   optCon = poptGetContext("netconfig", argc, argv, Options, 0);
   while ((rc = poptGetNextOpt(optCon)) >= 0) {
       parseAddress = NULL;
       netSet = 0;

       arg = poptGetOptArg(optCon);

       switch (rc) {
         case 'g':
           parseAddress = &netDev->dev.gateway;
           netSet = PUMP_NETINFO_HAS_GATEWAY;
           break;

         case 'i':
           parseAddress = &netDev->dev.ip;
           netSet = PUMP_INTFINFO_HAS_IP;
           break;

         case 'n':
           parseAddress = &netDev->dev.dnsServers[netDev->dev.numDns++];
           netSet = PUMP_NETINFO_HAS_DNS;
           break;

         case 'm':
           parseAddress = &netDev->dev.netmask;
           netSet = PUMP_INTFINFO_HAS_NETMASK;
           break;
       }

       if (!inet_aton(arg, parseAddress)) {
           logMessage("bad ip number in network command: %s", arg);
           return -1;
       }

       netDev->dev.set |= netSet;
   }

   if (rc < -1) {
       fprintf(stderr, "%s: %s\n",
                  poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
                  poptStrerror(rc));
   } else {
       poptFreeContext(optCon);
   }

   if (netDev->dev.set ||
       (bootProto && (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")))) {
           if (!device) device="eth0";
           if (bootProto && (!strcmp(bootProto, "dhcp") || !strcmp(bootProto, "bootp")))
               netDev->isDynamic++;
           strncpy(netDev->dev.device,device,10);
           if (hostname) {
                   netDev->dev.hostname=strdup(hostname);
                   netDev->dev.set |= PUMP_NETINFO_HAS_HOSTNAME;
           }
           if (domain) {
                   netDev->dev.domain=strdup(domain);
                   netDev->dev.set |= PUMP_NETINFO_HAS_DOMAIN;
           }
           snprintf(path,256,"/etc/sysconfig/network-scripts/ifcfg-%s",device);
           writeNetInfo(path,netDev);
   } else {
           newtInit();
           newtCls();
           newtPushHelpLine(_(" <Tab>/<Alt-Tab> between elements   |   <Space> selects  |   <F12> next screen"));
           snprintf(roottext,80,_("netconfig %s  (C) 1999 Red Hat, Inc."), VERSION);
           newtDrawRootText(0, 0, roottext);
           x=newtWinChoice(_("Network configuration"),_("Yes"),_("No"),
                         _("Would you like to set up networking?"));
           if (x==2) {
                   newtFinished();
                   exit(0);
           }
           if (!device) device="eth0";
           readNetConfig(device,netDev,0);
           snprintf(path,256,"/etc/sysconfig/network-scripts/ifcfg-%s",device);
           writeNetInfo(path,netDev);
           newtFinished();
   }
   exit(0);
}
#endif