summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/network.c')
-rw-r--r--mdk-stage1/network.c1232
1 files changed, 0 insertions, 1232 deletions
diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c
deleted file mode 100644
index cbc90126b..000000000
--- a/mdk-stage1/network.c
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- * Guillaume Cottenceau (gc@mandrakesoft.com)
- *
- * Copyright 2000 Mandrakesoft
- *
- * This software may be freely redistributed under the terms of the GNU
- * public license.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/*
- * Portions from Erik Troan (ewt@redhat.com)
- *
- * Copyright 1996 Red Hat Software
- *
- */
-
-#include <stdlib.h>
-/* define _GNU_SOURCE so strndup is available */
-#define _GNU_SOURCE
-#include <string.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <arpa/inet.h>
-#include <net/route.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <stdio.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <sys/utsname.h>
-
-#include "stage1.h"
-#include "frontend.h"
-#include "modules.h"
-#include "probing.h"
-#include "log.h"
-#include "mount.h"
-#include "automatic.h"
-#include "dhcp.h"
-#include "adsl.h"
-#include "url.h"
-#include "dns.h"
-
-#include "network.h"
-#include "directory.h"
-#include "wireless.h"
-
-#ifndef DISABLE_KA
-#include "ka.h"
-#endif
-
-static void error_message_net(void) /* reduce code size */
-{
- stg1_error_message("Could not configure network.");
-}
-
-
-int configure_net_device(struct interface_info * intf)
-{
- struct ifreq req;
- struct rtentry route;
- int s;
- struct sockaddr_in addr;
- struct in_addr ia;
- char ip[20], nm[20], nw[20], bc[20];
-
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
-
- memcpy(&ia, &intf->ip, sizeof(intf->ip));
- strcpy(ip, inet_ntoa(ia));
-
- memcpy(&ia, &intf->netmask, sizeof(intf->netmask));
- strcpy(nm, inet_ntoa(ia));
-
- memcpy(&ia, &intf->broadcast, sizeof(intf->broadcast));
- strcpy(bc, inet_ntoa(ia));
-
- memcpy(&ia, &intf->network, sizeof(intf->network));
- strcpy(nw, inet_ntoa(ia));
-
- log_message("configuring device %s ip: %s nm: %s nw: %s bc: %s", intf->device, ip, nm, nw, bc);
-
- if (IS_TESTING)
- return 0;
-
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- log_perror("socket");
- error_message_net();
- return 1;
- }
-
- strcpy(req.ifr_name, intf->device);
-
- if (intf->is_up == 1) {
- log_message("interface already up, downing before reconfigure");
-
- req.ifr_flags = 0;
- if (ioctl(s, SIOCSIFFLAGS, &req)) {
- close(s);
- log_perror("SIOCSIFFLAGS (downing)");
- error_message_net();
- return 1;
- }
- }
-
- /* sets IP address */
- addr.sin_port = 0;
- memcpy(&addr.sin_addr, &intf->ip, sizeof(intf->ip));
- memcpy(&req.ifr_addr, &addr, sizeof(addr));
- if (ioctl(s, SIOCSIFADDR, &req)) {
- close(s);
- log_perror("SIOCSIFADDR");
- error_message_net();
- return 1;
- }
-
- /* sets broadcast */
- memcpy(&addr.sin_addr, &intf->broadcast, sizeof(intf->broadcast));
- memcpy(&req.ifr_broadaddr, &addr, sizeof(addr));
- if (ioctl(s, SIOCSIFBRDADDR, &req)) {
- close(s);
- log_perror("SIOCSIFBRDADDR");
- error_message_net();
- return 1;
- }
-
- /* sets netmask */
- memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask));
- memcpy(&req.ifr_netmask, &addr, sizeof(addr));
- if (ioctl(s, SIOCSIFNETMASK, &req)) {
- close(s);
- log_perror("SIOCSIFNETMASK");
- error_message_net();
- return 1;
- }
-
- if (intf->is_ptp)
- req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_POINTOPOINT | IFF_NOARP;
- else
- req.ifr_flags = IFF_UP | IFF_RUNNING | IFF_BROADCAST;
-
- /* brings up networking! */
- if (ioctl(s, SIOCSIFFLAGS, &req)) {
- close(s);
- log_perror("SIOCSIFFLAGS (upping)");
- error_message_net();
- return 1;
- }
-
- memset(&route, 0, sizeof(route));
- route.rt_dev = intf->device;
- route.rt_flags = RTF_UP;
-
- memcpy(&addr.sin_addr, &intf->network, sizeof(intf->network));
- memcpy(&route.rt_dst, &addr, sizeof(addr));
-
- memcpy(&addr.sin_addr, &intf->netmask, sizeof(intf->netmask));
- memcpy(&route.rt_genmask, &addr, sizeof(addr));
-
- /* adds route */
- if (ioctl(s, SIOCADDRT, &route)) {
- close(s);
- log_perror("SIOCADDRT");
- error_message_net();
- return 1;
- }
-
- close(s);
-
- intf->is_up = 1;
-
- if (intf->boot_proto != BOOTPROTO_DHCP && !streq(intf->device, "lo")) {
- /* I need to sleep a bit in order for kernel to finish
- init of the network device; if not, first sendto() for
- gethostbyaddr will get an EINVAL. */
- wait_message("Bringing up networking...");
- sleep(2);
- remove_wait_message();
- }
-
- return 0;
-}
-
-/* host network informations */
-char * hostname = NULL;
-char * domain = NULL;
-struct in_addr gateway = { 0 };
-struct in_addr dns_server = { 0 };
-struct in_addr dns_server2 = { 0 };
-
-static int add_default_route(void)
-{
- int s;
- struct rtentry route;
- struct sockaddr_in addr;
-
- if (IS_TESTING)
- return 0;
-
- if (gateway.s_addr == 0) {
- log_message("no gateway provided, can't add default route");
- return 0;
- }
-
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- close(s);
- log_perror("socket");
- error_message_net();
- return 1;
- }
-
- memset(&route, 0, sizeof(route));
-
- addr.sin_family = AF_INET;
- addr.sin_port = 0;
- addr.sin_addr = gateway;
- memcpy(&route.rt_gateway, &addr, sizeof(addr));
-
- addr.sin_addr.s_addr = INADDR_ANY;
- memcpy(&route.rt_dst, &addr, sizeof(addr));
- memcpy(&route.rt_genmask, &addr, sizeof(addr));
-
- route.rt_flags = RTF_UP | RTF_GATEWAY;
- route.rt_metric = 0;
-
- if (ioctl(s, SIOCADDRT, &route)) {
- close(s);
- log_perror("SIOCADDRT");
- error_message_net();
- return 1;
- }
-
- close(s);
-
- return 0;
-}
-
-
-static int write_resolvconf(void)
-{
- char * filename = "/etc/resolv.conf";
- FILE * f;
-
- if (dns_server.s_addr == 0) {
- log_message("resolvconf needs a dns server");
- return -1;
- }
-
- f = fopen(filename, "w");
- if (!f) {
- log_perror(filename);
- return -1;
- }
-
- if (domain)
- fprintf(f, "search %s\n", domain); /* we can live without the domain search (user will have to enter fully-qualified names) */
- fprintf(f, "nameserver %s\n", inet_ntoa(dns_server));
- if (dns_server2.s_addr != 0)
- fprintf(f, "nameserver %s\n", inet_ntoa(dns_server2));
-
- fclose(f);
- res_init(); /* reinit the resolver so DNS changes take affect */
-
- return 0;
-}
-
-
-static int save_netinfo(struct interface_info * intf)
-{
- char * file_network = "/tmp/network";
- char file_intf[500];
- FILE * f;
-
- f = fopen(file_network, "w");
- if (!f) {
- log_perror(file_network);
- return -1;
- }
-
- fprintf(f, "NETWORKING=yes\n");
- fprintf(f, "FORWARD_IPV4=false\n");
-
- if (hostname && !intf->boot_proto == BOOTPROTO_DHCP)
- fprintf(f, "HOSTNAME=%s\n", hostname);
- if (gateway.s_addr != 0)
- fprintf(f, "GATEWAY=%s\n", inet_ntoa(gateway));
-
- fclose(f);
-
-
- strcpy(file_intf, "/tmp/ifcfg-");
- strcat(file_intf, intf->device);
-
- f = fopen(file_intf, "w");
- if (!f) {
- log_perror(file_intf);
- return -1;
- }
-
- fprintf(f, "DEVICE=%s\n", intf->device);
-
- if (intf->boot_proto == BOOTPROTO_DHCP) {
- fprintf(f, "BOOTPROTO=dhcp\n");
- if (dhcp_hostname && !streq(dhcp_hostname, ""))
- fprintf(f, "DHCP_HOSTNAME=%s\n", dhcp_hostname);
- } else if (intf->boot_proto == BOOTPROTO_STATIC) {
- fprintf(f, "BOOTPROTO=static\n");
- fprintf(f, "IPADDR=%s\n", inet_ntoa(intf->ip));
- fprintf(f, "NETMASK=%s\n", inet_ntoa(intf->netmask));
- fprintf(f, "NETWORK=%s\n", inet_ntoa(intf->network));
- fprintf(f, "BROADCAST=%s\n", inet_ntoa(intf->broadcast));
- } else if (intf->boot_proto == BOOTPROTO_ADSL_PPPOE) {
- fprintf(f, "BOOTPROTO=adsl_pppoe\n");
- fprintf(f, "USER=%s\n", intf->user);
- fprintf(f, "PASS=%s\n", intf->pass);
- fprintf(f, "ACNAME=%s\n", intf->acname);
- }
-
- fclose(f);
-
- return 0;
-}
-
-
-char * guess_netmask(char * ip_addr)
-{
- struct in_addr addr;
- unsigned long int tmp;
-
- if (streq(ip_addr, "") || !inet_aton(ip_addr, &addr))
- return "";
-
- log_message("guessing netmask");
-
- tmp = ntohl(addr.s_addr);
-
- if (((tmp & 0xFF000000) >> 24) <= 127)
- return "255.0.0.0";
- else if (((tmp & 0xFF000000) >> 24) <= 191)
- return "255.255.0.0";
- else
- return "255.255.255.0";
-}
-
-
-char * guess_domain_from_hostname(char *hostname)
-{
- char *domain = strchr(strdup(hostname), '.');
- if (!domain || domain[1] == '\0') {
- log_message("unable to guess domain from hostname: %s", hostname);
- return NULL;
- }
- return domain + 1; /* skip '.' */
-}
-
-
-static void static_ip_callback(char ** strings)
-{
- struct in_addr addr;
-
- static int done = 0;
- if (done)
- return;
- if (streq(strings[0], "") || !inet_aton(strings[0], &addr))
- return;
- done = 1;
-
- if (!strcmp(strings[1], "")) {
- char * ptr;
- strings[1] = strdup(strings[0]);
- ptr = strrchr(strings[1], '.');
- if (ptr)
- *(ptr+1) = '\0';
- }
-
- if (!strcmp(strings[2], ""))
- strings[2] = strdup(strings[1]);
-
- if (!strcmp(strings[3], ""))
- strings[3] = strdup(guess_netmask(strings[0]));
-}
-
-
-static enum return_type setup_network_interface(struct interface_info * intf)
-{
- enum return_type results;
- char * bootprotos[] = { "Static", "DHCP", "ADSL", NULL };
- char * bootprotos_auto[] = { "static", "dhcp", "adsl" };
- char * choice;
-
- results = ask_from_list_auto("Please select your network connection type.", bootprotos, &choice, "network", bootprotos_auto);
- if (results != RETURN_OK)
- return results;
-
- if (!strcmp(choice, "Static")) {
- char * questions[] = { "IP of this machine", "IP of DNS", "IP of default gateway", "Netmask", NULL };
- char * questions_auto[] = { "ip", "dns", "gateway", "netmask" };
- static char ** answers = NULL;
- struct in_addr addr;
-
- results = ask_from_entries_auto("Please enter the network information. (leave netmask blank for Internet standard)",
- questions, &answers, 16, questions_auto, static_ip_callback);
- if (results != RETURN_OK)
- return setup_network_interface(intf);
-
- if (streq(answers[0], "") || !inet_aton(answers[0], &addr)) {
- stg1_error_message("Invalid IP address.");
- return setup_network_interface(intf);
- }
- memcpy(&intf->ip, &addr, sizeof(addr));
-
- if (!inet_aton(answers[1], &dns_server)) {
- log_message("invalid DNS");
- dns_server.s_addr = 0; /* keep an understandable state */
- }
-
- if (streq(answers[0], answers[1])) {
- log_message("IP and DNS are the same, guess you don't want a DNS, disabling it");
- dns_server.s_addr = 0; /* keep an understandable state */
- }
-
- if (!inet_aton(answers[2], &gateway)) {
- log_message("invalid gateway");
- gateway.s_addr = 0; /* keep an understandable state */
- }
-
- if ((streq(answers[3], "") && inet_aton(guess_netmask(answers[0]), &addr))
- || inet_aton(answers[3], &addr))
- memcpy(&intf->netmask, &addr, sizeof(addr));
- else {
- stg1_error_message("Invalid netmask.");
- return setup_network_interface(intf);
- }
-
- *((uint32_t *) &intf->broadcast) = (*((uint32_t *) &intf->ip) &
- *((uint32_t *) &intf->netmask)) | ~(*((uint32_t *) &intf->netmask));
-
- inet_aton("255.255.255.255", &addr);
- if (!memcmp(&addr, &intf->netmask, sizeof(addr))) {
- log_message("netmask is 255.255.255.255 -> point to point device");
- intf->network = gateway;
- intf->is_ptp = 1;
- } else {
- *((uint32_t *) &intf->network) = *((uint32_t *) &intf->ip) & *((uint32_t *) &intf->netmask);
- intf->is_ptp = 0;
- }
- intf->boot_proto = BOOTPROTO_STATIC;
-
- if (configure_net_device(intf))
- return RETURN_ERROR;
-
- } else if (streq(choice, "DHCP")) {
- results = perform_dhcp(intf);
-
- if (results == RETURN_BACK)
- return setup_network_interface(intf);
- if (results == RETURN_ERROR)
- return results;
- intf->boot_proto = BOOTPROTO_DHCP;
-
- if (configure_net_device(intf))
- return RETURN_ERROR;
-
- } else if (streq(choice, "ADSL")) {
- results = perform_adsl(intf);
-
- if (results == RETURN_BACK)
- return setup_network_interface(intf);
- if (results == RETURN_ERROR)
- return results;
- } else
- return RETURN_ERROR;
-
- return add_default_route();
-}
-
-
-static enum return_type configure_network(struct interface_info * intf)
-{
- char * dnshostname;
-
- if (hostname && domain)
- return RETURN_OK;
-
- dnshostname = mygethostbyaddr(inet_ntoa(intf->ip));
-
- if (dnshostname) {
- if (intf->boot_proto == BOOTPROTO_STATIC)
- hostname = strdup(dnshostname);
- domain = guess_domain_from_hostname(dnshostname);
- if (domain) {
- log_message("got hostname and domain from dns entry, %s and %s", dnshostname, domain);
- return RETURN_OK;
- }
- } else
- log_message("reverse name lookup on self failed");
-
- if (domain)
- return RETURN_OK;
-
- dnshostname = NULL;
- if (dns_server.s_addr != 0) {
- wait_message("Trying to resolve dns...");
- dnshostname = mygethostbyaddr(inet_ntoa(dns_server));
- remove_wait_message();
- if (dnshostname) {
- log_message("got DNS fullname, %s", dnshostname);
- domain = guess_domain_from_hostname(dnshostname);
- } else
- log_message("reverse name lookup on DNS failed");
- } else
- log_message("no DNS, unable to guess domain");
-
- if (domain) {
- log_message("got domain from DNS fullname, %s", domain);
- } else {
- enum return_type results;
- char * questions[] = { "Host name", "Domain name", NULL };
- char * questions_auto[] = { "hostname", "domain" };
- static char ** answers = NULL;
- char * boulet;
-
- if (dhcp_hostname || dhcp_domain) {
- answers = (char **) malloc(sizeof(questions));
- answers[0] = strdup(dhcp_hostname);
- answers[1] = strdup(dhcp_domain);
- }
-
- if (!dhcp_hostname || !dhcp_hostname) {
- results = ask_from_entries_auto("I could not guess hostname and domain name; please fill in this information. "
- "Valid answers are for example: `mybox' for hostname and `mynetwork.com' for "
- "domain name, for a machine called `mybox.mynetwork.com' on the Internet.",
- questions, &answers, 32, questions_auto, NULL);
- if (results != RETURN_OK)
- return results;
- }
-
- hostname = answers[0];
- if ((boulet = strchr(hostname, '.')) != NULL)
- boulet[0] = '\0';
- domain = answers[1];
- }
-
- log_message("using hostname %s", hostname);
- log_message("using domain %s", domain);
-
- return RETURN_OK;
-}
-
-
-static enum return_type bringup_networking(struct interface_info * intf)
-{
- static struct interface_info loopback;
- enum return_type results;
-
- my_insmod("af_packet", ANY_DRIVER_TYPE, NULL, 1);
-
- do {
- results = configure_wireless(intf->device);
- } while (results == RETURN_ERROR);
-
- if (results == RETURN_BACK)
- return RETURN_BACK;
-
- do {
- results = setup_network_interface(intf);
- if (results != RETURN_OK)
- return results;
- write_resolvconf();
- results = configure_network(intf);
- } while (results == RETURN_ERROR);
-
- if (results == RETURN_BACK)
- return bringup_networking(intf);
-
- write_resolvconf(); /* maybe we have now domain to write also */
-
- if (loopback.is_up == 0) {
- int rc;
- strcpy(loopback.device, "lo");
- loopback.is_ptp = 0;
- loopback.is_up = 0;
- loopback.ip.s_addr = htonl(0x7f000001);
- loopback.netmask.s_addr = htonl(0xff000000);
- loopback.broadcast.s_addr = htonl(0x7fffffff);
- loopback.network.s_addr = htonl(0x7f000000);
- rc = configure_net_device(&loopback);
- if (rc)
- return RETURN_ERROR;
- }
-
- return RETURN_OK;
-}
-
-
-static char * auto_select_up_intf(void)
-{
-#define SIOCETHTOOL 0x8946
-#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
-
- struct ethtool_value {
- uint32_t cmd;
- uint32_t data;
- };
-
- char ** interfaces, ** ptr;
- interfaces = get_net_devices();
-
- int s;
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s < 0) {
- return NULL;
- }
-
- ptr = interfaces;
- while (ptr && *ptr) {
- struct ifreq ifr;
- struct ethtool_value edata;
- strncpy(ifr.ifr_name, *ptr, IFNAMSIZ);
- edata.cmd = ETHTOOL_GLINK;
- ifr.ifr_data = (caddr_t)&edata;
- if (ioctl(s, SIOCETHTOOL, &ifr) == 0 && edata.data) {
- close(s);
- return *ptr;
- }
- ptr++;
- }
-
- close(s);
-
- return NULL;
-}
-
-
-static char * interface_select(void)
-{
- char ** interfaces, ** ptr;
- char * descriptions[50];
- char * choice;
- int i, count = 0;
- enum return_type results;
-
- interfaces = get_net_devices();
-
- ptr = interfaces;
- while (ptr && *ptr) {
- count++;
- ptr++;
- }
-
- if (count == 0) {
- stg1_error_message("No NET device found.\n"
- "Hint: if you're using a Laptop, note that PCMCIA Network adapters are now supported either with `pcmcia.img' or `network.img', please try both these bootdisks.");
- i = ask_insmod(NETWORK_DEVICES);
- if (i == RETURN_BACK)
- return NULL;
- return interface_select();
- }
-
- if (count == 1)
- return *interfaces;
-
- /* this can't be done in ask_from_list_comments_auto because "auto" isn't in the interfaces list */
- if (IS_AUTOMATIC && streq(get_auto_value("interface"), "auto")) {
- choice = auto_select_up_intf();
- if (choice)
- return choice;
- }
-
- i = 0;
- while (interfaces[i]) {
- descriptions[i] = get_net_intf_description(interfaces[i]);
- i++;
- }
-
- results = ask_from_list_comments_auto("Please choose the NET device to use for the installation.",
- interfaces, descriptions, &choice, "interface", interfaces);
-
- if (results != RETURN_OK)
- return NULL;
-
- return choice;
-}
-
-#ifndef MANDRAKE_MOVE
-static enum return_type get_http_proxy(char **http_proxy_host, char **http_proxy_port)
-{
- char *questions[] = { "HTTP proxy host", "HTTP proxy port", NULL };
- char *questions_auto[] = { "proxy_host", "proxy_port", NULL };
- static char ** answers = NULL;
- enum return_type results;
-
- results = ask_from_entries_auto("Please enter HTTP proxy host and port if you need it, else leave them blank or cancel.",
- questions, &answers, 40, questions_auto, NULL);
- if (results == RETURN_OK) {
- *http_proxy_host = answers[0];
- *http_proxy_port = answers[1];
- } else {
- *http_proxy_host = NULL;
- *http_proxy_port = NULL;
- }
-
- return results;
-}
-
-
-static int mirrorlist_entry_split(const char *entry, char *mirror[4]) /* mirror = { medium, protocol, host, path } */
-{
- char *medium_sep, *protocol_sep, *host_sep, *path_sep;
-
- medium_sep = strchr(entry, ':');
- if (!medium_sep || medium_sep == entry) {
- log_message("NETWORK: no medium in \"%s\"", entry);
- return -1;
- }
-
- mirror[0] = strndup(entry, medium_sep - entry);
- entry = medium_sep + 1;
-
- protocol_sep = strstr(entry, "://");
- if (!protocol_sep || protocol_sep == entry) {
- log_message("NETWORK: no protocol in \"%s\"", entry);
- return -1;
- }
-
- mirror[1] = strndup(entry, protocol_sep - entry);
- entry = protocol_sep + 3;
-
- host_sep = strchr(entry, '/');
- if (!host_sep || host_sep == entry) {
- log_message("NETWORK: no hostname in \"%s\"", entry);
- return -1;
- }
-
- mirror[2] = strndup(entry, host_sep - entry);
- entry = host_sep;
-
- path_sep = strstr(entry, "/media/main");
- if (!path_sep || path_sep == entry) {
- log_message("NETWORK: this path isn't valid : \"%s\"", entry);
- return -1;
- }
-
- mirror[3] = strndup(entry, path_sep - entry);
-
- return 0;
-}
-
-
-#define MIRRORLIST_MAX_ITEMS 500
-#define MIRRORLIST_MAX_MEDIA 10
-
-static int choose_mirror_from_host_list(char *mirrorlist[][4], const char *protocol, char *medium, char **selected_host, char **filepath)
-{
- enum return_type results;
- char *hostlist[MIRRORLIST_MAX_ITEMS+1] = { "Specify the mirror manually", "-----" };
- int hostlist_index = 2, mirrorlist_index;
-
- /* select hosts matching medium and protocol */
- for (mirrorlist_index = 0; mirrorlist[mirrorlist_index][0]; mirrorlist_index++) {
- if (!strcmp(mirrorlist[mirrorlist_index][0], medium) &&
- !strcmp(mirrorlist[mirrorlist_index][1], protocol)) {
- hostlist[hostlist_index] = mirrorlist[mirrorlist_index][2];
- hostlist_index++;
- if (hostlist_index == MIRRORLIST_MAX_ITEMS)
- break;
- }
- }
- hostlist[hostlist_index] = NULL;
-
- do {
- results = ask_from_list("Please select a mirror from the list below.",
- hostlist, selected_host);
-
- if (results == RETURN_BACK) {
- return RETURN_ERROR;
- } else if (results == RETURN_OK) {
- if (!strcmp(*selected_host, hostlist[0])) {
- /* enter the mirror manually */
- return RETURN_OK;
- } else if (!strcmp(*selected_host, hostlist[1])) {
- /* the separator has been selected */
- results = RETURN_ERROR;
- continue;
- }
- }
-
- /* select the path according to medium, protocol and host */
- for (mirrorlist_index = 0; mirrorlist[mirrorlist_index][0]; mirrorlist_index++) {
- if (!strcmp(mirrorlist[mirrorlist_index][0], medium) &&
- !strcmp(mirrorlist[mirrorlist_index][1], protocol) &&
- !strcmp(mirrorlist[mirrorlist_index][2], *selected_host)) {
- *filepath = mirrorlist[mirrorlist_index][3];
- return RETURN_OK;
- }
- }
-
- stg1_info_message("Unable to find the path for this mirror, please select another one");
- results = RETURN_ERROR;
-
- } while (results == RETURN_ERROR);
-
- return RETURN_ERROR;
-}
-
-
-static int choose_mirror_from_list(char *http_proxy_host, char *http_proxy_port, const char *protocol, char **selected_host, char **filepath)
-{
- enum return_type results;
- char *mirrorlist[MIRRORLIST_MAX_ITEMS+1][4];
- int mirrorlist_number = 0;
- char *medialist[MIRRORLIST_MAX_MEDIA+1] = { "Specify the mirror manually", "-----" };
- int media_number = 2;
- char *selected_medium;
- int fd, size, line_pos = 0;
- char line[500];
- int use_http_proxy = http_proxy_host && http_proxy_port && !streq(http_proxy_host, "") && !streq(http_proxy_port, "");
-
- fd = http_download_file(MIRRORLIST_HOST, MIRRORLIST_PATH, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
- if (fd < 0) {
- log_message("HTTP: unable to get mirrors list");
- return RETURN_ERROR;
- }
-
- while (read(fd, line + line_pos, 1) > 0) {
- if (line[line_pos] == '\n') {
- line[line_pos] = '\0';
- line_pos = 0;
-
- /* skip medium if it looks like an updates one */
- if (strstr(line, "updates"))
- continue;
-
- if (mirrorlist_entry_split(line, mirrorlist[mirrorlist_number]) < 0)
- continue;
-
- /* add medium in media list if different from previous one */
- if (media_number == 2 ||
- strcmp(mirrorlist[mirrorlist_number][0], medialist[media_number-1])) {
- medialist[media_number] = mirrorlist[mirrorlist_number][0];
- media_number++;
- }
-
- mirrorlist_number++;
- } else {
- line_pos++;
- }
-
- if (mirrorlist_number >= MIRRORLIST_MAX_ITEMS || media_number >= MIRRORLIST_MAX_MEDIA)
- break;
- }
- close(fd);
-
- mirrorlist[mirrorlist_number][0] = NULL;
- medialist[media_number] = NULL;
-
- do {
- results = ask_from_list("Please select a medium from the list below.",
- medialist, &selected_medium);
-
- if (results == RETURN_BACK) {
- return RETURN_BACK;
- } else if (results == RETURN_OK) {
- if (!strcmp(selected_medium, medialist[0])) {
- /* enter the mirror manually */
- return RETURN_OK;
- } else if (!strcmp(selected_medium, medialist[1])) {
- /* the separator has been selected */
- results = RETURN_ERROR;
- continue;
- } else {
- /* a medium has been selected */
- results = choose_mirror_from_host_list(mirrorlist, protocol, selected_medium, selected_host, filepath);
- }
- }
- } while (results == RETURN_ERROR);
-
- return results;
-}
-#endif
-
-
-/* -=-=-- */
-
-
-enum return_type intf_select_and_up()
-{
- static struct interface_info intf[20];
- static int num_interfaces = 0;
- struct interface_info * sel_intf = NULL;
- int i;
- enum return_type results;
- char * iface = interface_select();
-
- if (iface == NULL)
- return RETURN_BACK;
-
- for (i = 0; i < num_interfaces ; i++)
- if (!strcmp(intf[i].device, iface))
- sel_intf = &(intf[i]);
-
- if (sel_intf == NULL) {
- sel_intf = &(intf[num_interfaces]);
- strcpy(sel_intf->device, iface);
- sel_intf->is_up = 0;
- num_interfaces++;
- }
-
- results = bringup_networking(sel_intf);
-
- if (results == RETURN_OK)
- save_netinfo(sel_intf);
-
- return results;
-}
-
-
-
-enum return_type nfs_prepare(void)
-{
- char * questions[] = { "NFS server name", DISTRIB_NAME " directory", NULL };
- char * questions_auto[] = { "server", "directory", NULL };
- static char ** answers = NULL;
- char * nfs_own_mount = IMAGE_LOCATION_DIR "nfsimage";
- char * nfsmount_location;
- enum return_type results = intf_select_and_up(NULL, NULL);
-
- if (results != RETURN_OK)
- return results;
-
- do {
- results = ask_from_entries_auto("Please enter the name or IP address of your NFS server, "
- "and the directory containing the " DISTRIB_NAME " Distribution.",
- questions, &answers, 40, questions_auto, NULL);
- if (results != RETURN_OK || streq(answers[0], "")) {
- unset_automatic(); /* we are in a fallback mode */
- return nfs_prepare();
- }
-
- nfsmount_location = malloc(strlen(answers[0]) + strlen(answers[1]) + 2);
- strcpy(nfsmount_location, answers[0]);
- strcat(nfsmount_location, ":");
- strcat(nfsmount_location, answers[1]);
-
- if (my_mount(nfsmount_location, nfs_own_mount, "nfs", 0) == -1) {
- stg1_error_message("I can't mount the directory from the NFS server.");
- results = RETURN_BACK;
- continue;
- }
-
- results = try_with_directory(nfs_own_mount, "nfs", "nfs-iso");
- if (results != RETURN_OK)
- umount(nfs_own_mount);
- if (results == RETURN_ERROR)
- return RETURN_ERROR;
- }
- while (results == RETURN_BACK);
-
- return RETURN_OK;
-}
-
-
-#ifndef MANDRAKE_MOVE
-enum return_type ftp_prepare(void)
-{
- char * questions[] = { "FTP server", DISTRIB_NAME " directory", "Login", "Password", NULL };
- char * questions_auto[] = { "server", "directory", "user", "pass", NULL };
- static char ** answers = NULL;
- enum return_type results;
- struct utsname kernel_uname;
- char *http_proxy_host, *http_proxy_port;
- int use_http_proxy;
-
- if (!ramdisk_possible()) {
- stg1_error_message("FTP install needs more than %d Mbytes of memory (detected %d Mbytes). You may want to try an NFS install.",
- MEM_LIMIT_DRAKX, total_memory());
- return RETURN_ERROR;
- }
-
- results = intf_select_and_up();
-
- if (results != RETURN_OK)
- return results;
-
- get_http_proxy(&http_proxy_host, &http_proxy_port);
- use_http_proxy = http_proxy_host && http_proxy_port && !streq(http_proxy_host, "") && !streq(http_proxy_port, "");
-
- uname(&kernel_uname);
-
- do {
- char location_full[500];
- int ftp_serv_response = -1;
- int fd, size;
- char ftp_hostname[500];
-
- if (!IS_AUTOMATIC) {
- if (answers == NULL)
- answers = (char **) malloc(sizeof(questions));
-
- results = choose_mirror_from_list(http_proxy_host, http_proxy_port, "ftp", &answers[0], &answers[1]);
-
- if (results == RETURN_BACK)
- return ftp_prepare();
-
- if (use_http_proxy) {
- results = ask_yes_no("Do you want to use this HTTP proxy for FTP connections too ?");
-
- if (results == RETURN_BACK)
- return ftp_prepare();
-
- use_http_proxy = results == RETURN_OK;
- }
- }
-
- results = ask_from_entries_auto("Please enter the name or IP address of the FTP server, "
- "the directory containing the " DISTRIB_NAME " Distribution, "
- "and the login/pass if necessary (leave login blank for anonymous). ",
- questions, &answers, 40, questions_auto, NULL);
- if (results != RETURN_OK || streq(answers[0], "")) {
- unset_automatic(); /* we are in a fallback mode */
- return ftp_prepare();
- }
-
- strcpy(location_full, answers[1][0] == '/' ? "" : "/");
- strcat(location_full, answers[1]);
-
- if (use_http_proxy) {
- log_message("FTP: don't connect to %s directly, will use proxy", answers[0]);
- } else {
- char *kernels_list_file, *kernels_list;
-
- log_message("FTP: trying to connect to %s", answers[0]);
- ftp_serv_response = ftp_open_connection(answers[0], answers[2], answers[3], "");
- if (ftp_serv_response < 0) {
- log_message("FTP: error connect %d", ftp_serv_response);
- if (ftp_serv_response == FTPERR_BAD_HOSTNAME)
- stg1_error_message("Error: bad hostname.");
- else if (ftp_serv_response == FTPERR_FAILED_CONNECT)
- stg1_error_message("Error: failed to connect to remote host.");
- else
- stg1_error_message("Error: couldn't connect.");
- results = RETURN_BACK;
- continue;
- }
- kernels_list_file = asprintf_("%s/" CLP_LOCATION_REL "mdkinst.kernels", location_full);
-
- log_message("FTP: trying to retrieve %s", kernels_list_file);
- fd = ftp_start_download(ftp_serv_response, kernels_list_file, &size);
-
- if (fd < 0) {
- char *msg = str_ftp_error(fd);
- log_message("FTP: error get %d for remote file %s", fd, kernels_list_file);
- stg1_error_message("Error: %s.", msg ? msg : "couldn't retrieve list of kernel versions");
- results = RETURN_BACK;
- continue;
- }
-
- kernels_list = alloca(size);
- size = read(fd, kernels_list, size);
- close(fd);
- ftp_end_data_command(ftp_serv_response);
-
- if (!strstr(kernels_list, asprintf_("%s\n", kernel_uname.release))) {
- stg1_info_message("The modules for this kernel (%s) can't be found on this mirror, please update your boot disk", kernel_uname.release);
- results = RETURN_BACK;
- continue;
- }
- }
-
- strcat(location_full, CLP_FILE_REL("/"));
-
- log_message("FTP: trying to retrieve %s", location_full);
-
- if (use_http_proxy) {
- if (strcmp(answers[2], "")) {
- strcpy(ftp_hostname, answers[2]); /* user name */
- strcat(ftp_hostname, ":");
- strcat(ftp_hostname, answers[3]); /* password */
- strcat(ftp_hostname, "@");
- } else {
- strcpy(ftp_hostname, "");
- }
- strcat(ftp_hostname, answers[0]);
- fd = http_download_file(ftp_hostname, location_full, &size, "ftp", http_proxy_host, http_proxy_port);
- } else {
- fd = ftp_start_download(ftp_serv_response, location_full, &size);
- }
-
- if (fd < 0) {
- char *msg = str_ftp_error(fd);
- log_message("FTP: error get %d for remote file %s", fd, location_full);
- stg1_error_message("Error: %s.", msg ? msg : "couldn't retrieve Installation program");
- results = RETURN_BACK;
- continue;
- }
-
- log_message("FTP: size of download %d bytes", size);
-
- results = load_clp_fd(fd, size);
- if (results == RETURN_OK) {
- if (!use_http_proxy)
- ftp_end_data_command(ftp_serv_response);
- } else {
- unset_automatic(); /* we are in a fallback mode */
- return results;
- }
-
- if (use_http_proxy) {
- add_to_env("METHOD", "http");
- sprintf(location_full, "ftp://%s%s", ftp_hostname, answers[1]);
- add_to_env("URLPREFIX", location_full);
- add_to_env("PROXY", http_proxy_host);
- add_to_env("PROXYPORT", http_proxy_port);
- } else {
- add_to_env("METHOD", "ftp");
- add_to_env("HOST", answers[0]);
- add_to_env("PREFIX", answers[1]);
- if (!streq(answers[2], "")) {
- add_to_env("LOGIN", answers[2]);
- add_to_env("PASSWORD", answers[3]);
- }
- }
- }
- while (results == RETURN_BACK);
-
- return RETURN_OK;
-}
-
-enum return_type http_prepare(void)
-{
- char * questions[] = { "HTTP server", DISTRIB_NAME " directory", NULL };
- char * questions_auto[] = { "server", "directory", NULL };
- static char ** answers = NULL;
- enum return_type results;
- char *http_proxy_host, *http_proxy_port;
-
- if (!ramdisk_possible()) {
- stg1_error_message("HTTP install needs more than %d Mbytes of memory (detected %d Mbytes). You may want to try an NFS install.",
- MEM_LIMIT_DRAKX, total_memory());
- return RETURN_ERROR;
- }
-
- results = intf_select_and_up();
-
- if (results != RETURN_OK)
- return results;
-
- get_http_proxy(&http_proxy_host, &http_proxy_port);
-
- do {
- char location_full[500];
- int fd, size;
- int use_http_proxy;
-
- results = ask_from_entries_auto("Please enter the name or IP address of the HTTP server, "
- "and the directory containing the " DISTRIB_NAME " Distribution.",
- questions, &answers, 40, questions_auto, NULL);
- if (results != RETURN_OK || streq(answers[0], "")) {
- unset_automatic(); /* we are in a fallback mode */
- return http_prepare();
- }
-
- strcpy(location_full, answers[1][0] == '/' ? "" : "/");
- strcat(location_full, answers[1]);
- strcat(location_full, CLP_FILE_REL("/"));
-
- log_message("HTTP: trying to retrieve %s from %s", location_full, answers[0]);
-
- use_http_proxy = http_proxy_host && http_proxy_port && !streq(http_proxy_host, "") && !streq(http_proxy_port, "");
-
- fd = http_download_file(answers[0], location_full, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
- if (fd < 0) {
- log_message("HTTP: error %d", fd);
- if (fd == FTPERR_FAILED_CONNECT)
- stg1_error_message("Error: couldn't connect to server.");
- else
- stg1_error_message("Error: couldn't get file (%s).", location_full);
- results = RETURN_BACK;
- continue;
- }
-
- log_message("HTTP: size of download %d bytes", size);
-
- if (load_clp_fd(fd, size) != RETURN_OK) {
- unset_automatic(); /* we are in a fallback mode */
- return RETURN_ERROR;
- }
-
- add_to_env("METHOD", "http");
- sprintf(location_full, "http://%s%s%s", answers[0], answers[1][0] == '/' ? "" : "/", answers[1]);
- add_to_env("URLPREFIX", location_full);
- if (!streq(http_proxy_host, ""))
- add_to_env("PROXY", http_proxy_host);
- if (!streq(http_proxy_port, ""))
- add_to_env("PROXYPORT", http_proxy_port);
- }
- while (results == RETURN_BACK);
-
- return RETURN_OK;
-
-}
-
-#ifndef DISABLE_KA
-enum return_type ka_prepare(void)
-{
- enum return_type results;
-
- if (!ramdisk_possible()) {
- stg1_error_message("KA install needs more than %d Mbytes of memory (detected %d Mbytes).",
- MEM_LIMIT_DRAKX, total_memory());
- return RETURN_ERROR;
- }
-
- results = intf_select_and_up();
-
- if (results != RETURN_OK)
- return results;
-
- return perform_ka();
-}
-#endif
-
-#endif