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.c460
1 files changed, 282 insertions, 178 deletions
diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c
index a931ab8fb..ab512399a 100644
--- a/mdk-stage1/network.c
+++ b/mdk-stage1/network.c
@@ -1,7 +1,7 @@
/*
- * Guillaume Cottenceau (gc@mandrakesoft.com)
+ * Guillaume Cottenceau (gc)
*
- * Copyright 2000 Mandrakesoft
+ * Copyright 2000 Mandriva
*
* This software may be freely redistributed under the terms of the GNU
* public license.
@@ -19,7 +19,10 @@
*
*/
+#include "stage1.h"
+
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -28,15 +31,17 @@
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <stdio.h>
+#include <fcntl.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 "tools.h"
+#include "utils.h"
#include "mount.h"
#include "automatic.h"
#include "dhcp.h"
@@ -46,9 +51,11 @@
#include "network.h"
#include "directory.h"
+#include "wireless.h"
-/* include it after config-stage1.h so that _GNU_SOURCE is defined and strndup is available */
-#include <string.h>
+#ifndef DISABLE_KA
+#include "ka.h"
+#endif
static void error_message_net(void) /* reduce code size */
{
@@ -284,13 +291,8 @@ static int save_netinfo(struct interface_info * intf)
fprintf(f, "NETWORKING=yes\n");
fprintf(f, "FORWARD_IPV4=false\n");
- if (hostname && !intf->boot_proto == BOOTPROTO_DHCP)
+ if (hostname && !(intf->boot_proto == BOOTPROTO_DHCP))
fprintf(f, "HOSTNAME=%s\n", hostname);
- if (domain)
- fprintf(f, "DOMAINNAME=%s\n", domain);
- if (dhcp_hostname && !streq(dhcp_hostname, ""))
- fprintf(f, "DHCP_HOSTNAME=%s\n", dhcp_hostname);
-
if (gateway.s_addr != 0)
fprintf(f, "GATEWAY=%s\n", inet_ntoa(gateway));
@@ -308,14 +310,22 @@ static int save_netinfo(struct interface_info * intf)
fprintf(f, "DEVICE=%s\n", intf->device);
- if (intf->boot_proto == BOOTPROTO_DHCP)
+ if (intf->boot_proto == BOOTPROTO_DHCP) {
fprintf(f, "BOOTPROTO=dhcp\n");
- else if (intf->boot_proto == BOOTPROTO_STATIC) {
+ 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));
+ if (domain)
+ fprintf(f, "DOMAIN=%s\n", domain);
+ if (dns_server.s_addr != 0)
+ fprintf(f, "DNS1=%s\n", inet_ntoa(dns_server));
+ if (dns_server2.s_addr != 0)
+ fprintf(f, "DNS2=%s\n", inet_ntoa(dns_server2));
} else if (intf->boot_proto == BOOTPROTO_ADSL_PPPOE) {
fprintf(f, "BOOTPROTO=adsl_pppoe\n");
fprintf(f, "USER=%s\n", intf->user);
@@ -391,8 +401,8 @@ static void static_ip_callback(char ** strings)
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 * bootprotos[] = { "DHCP", "Static", "ADSL", NULL };
+ char * bootprotos_auto[] = { "dhcp", "static", "adsl" };
char * choice;
results = ask_from_list_auto("Please select your network connection type.", bootprotos, &choice, "network", bootprotos_auto);
@@ -528,12 +538,12 @@ static enum return_type configure_network(struct interface_info * intf)
char * boulet;
if (dhcp_hostname || dhcp_domain) {
- answers = (char **) malloc(sizeof(questions));
+ answers = (char **) calloc(1, sizeof(questions));
answers[0] = strdup(dhcp_hostname);
answers[1] = strdup(dhcp_domain);
}
- if (!dhcp_hostname || !dhcp_hostname) {
+ if (!dhcp_hostname || !dhcp_domain) {
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.",
@@ -549,7 +559,7 @@ static enum return_type configure_network(struct interface_info * intf)
}
log_message("using hostname %s", hostname);
- log_message("using daomin %s", domain);
+ log_message("using domain %s", domain);
return RETURN_OK;
}
@@ -558,17 +568,34 @@ static enum return_type configure_network(struct interface_info * intf)
static enum return_type bringup_networking(struct interface_info * intf)
{
static struct interface_info loopback;
- enum return_type results = RETURN_ERROR;
-
- my_insmod("af_packet", ANY_DRIVER_TYPE, NULL, 1);
+ enum return_type results;
+ int fd;
- while (results != RETURN_OK) {
+ /* try to find if module already loaded or built-in to avoid failing */
+ /* badly */
+ fd = open("/proc/net/packet", O_RDONLY);
+ if (fd < 0)
+ my_modprobe("af_packet", ANY_DRIVER_TYPE, NULL);
+ else
+ close(fd);
+
+ 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 */
@@ -590,6 +617,63 @@ static enum return_type bringup_networking(struct interface_info * intf)
}
+static char * auto_select_up_intf(int detection_mode)
+{
+#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) {
+ if (detection_mode != AUTO_DETECTION_WIRED || !wireless_is_aware(s, *interfaces)) {
+ 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);
+ log_message("NETWORK: choosing interface %s (link beat detected)", *ptr);
+ return *ptr;
+ }
+ }
+ ptr++;
+ }
+
+ log_message("NETWORK: no interface has a link beat");
+
+ if (detection_mode == AUTO_DETECTION_WIRED) {
+ ptr = interfaces;
+ while (ptr && *ptr) {
+ if (!wireless_is_aware(s, *interfaces)) {
+ close(s);
+ log_message("NETWORK: choosing interface %s (wired interface)", *ptr);
+ return *ptr;
+ }
+ ptr++;
+ }
+ log_message("NETWORK: no interface is wired");
+ }
+
+ close(s);
+
+ return NULL;
+}
+
+
static char * interface_select(void)
{
char ** interfaces, ** ptr;
@@ -607,8 +691,7 @@ static char * interface_select(void)
}
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.");
+ stg1_error_message("No NET device found.");
i = ask_insmod(NETWORK_DEVICES);
if (i == RETURN_BACK)
return NULL;
@@ -618,6 +701,20 @@ static char * interface_select(void)
if (count == 1)
return *interfaces;
+ /* this can't be done in ask_from_list_comments_auto because "auto" and "wired" are not in the interfaces list */
+ if (IS_AUTOMATIC) {
+ enum auto_detection_type auto_detect = AUTO_DETECTION_NONE;
+ if (streq(get_auto_value("interface"), "auto"))
+ auto_detect = AUTO_DETECTION_ALL;
+ else if (streq(get_auto_value("interface"), "wired"))
+ auto_detect = AUTO_DETECTION_WIRED;
+ if (auto_detect != AUTO_DETECTION_NONE) {
+ choice = auto_select_up_intf(auto_detect);
+ if (choice)
+ return choice;
+ }
+ }
+
i = 0;
while (interfaces[i]) {
descriptions[i] = get_net_intf_description(interfaces[i]);
@@ -633,7 +730,6 @@ static char * interface_select(void)
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 };
@@ -646,183 +742,153 @@ static enum return_type get_http_proxy(char **http_proxy_host, char **http_proxy
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 } */
+static int url_split(const char *url, const char *protocol, char **host, char **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;
+ char *protocol_sep, *host_sep;
- protocol_sep = strstr(entry, "://");
- if (!protocol_sep || protocol_sep == entry) {
- log_message("NETWORK: no protocol in \"%s\"", entry);
+ protocol_sep = strstr(url, "://");
+ if (!protocol_sep) {
+ log_message("NETWORK: no protocol in \"%s\"", url);
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);
+ if (strncmp(protocol, url, protocol_sep - url))
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);
+ url = protocol_sep + 3;
+ host_sep = strchr(url, '/');
+ if (!host_sep || host_sep == url) {
+ log_message("NETWORK: no hostname in \"%s\"", url);
return -1;
}
- mirror[3] = strndup(entry, path_sep - entry);
+ *host = strndup(url, host_sep - url);
+ *path = strdup(host_sep);
return 0;
}
+#define MIRRORLIST_MAX_ITEMS 500
+typedef char *mirrorlist_t[2][MIRRORLIST_MAX_ITEMS+1];
-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;
+static enum return_type get_mirrorlist(mirrorlist_t mirrorlist, int start, char *version, const char *protocol, char *http_proxy_host, char *http_proxy_port) {
int fd, size, line_pos = 0;
- char line[500];
+ char path[1024];
+ char line[1024];
+ char type[100] = DISTRIB_TYPE;
+ int mirror_idx = start;
+
int use_http_proxy = http_proxy_host && http_proxy_port && !streq(http_proxy_host, "") && !streq(http_proxy_port, "");
+ lowercase(type);
+ snprintf(path, sizeof(path), "%s/%s.%s.%s.list", MIRRORLIST_PATH, type, version, ARCH);
- fd = http_download_file(MIRRORLIST_HOST, MIRRORLIST_PATH, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
+ fd = http_download_file(MIRRORLIST_HOST, path, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
if (fd < 0) {
- log_message("HTTP: unable to get mirrors list");
+ log_message("HTTP: unable to get mirrors list from %s (%s)", MIRRORLIST_HOST, path);
return RETURN_ERROR;
}
while (read(fd, line + line_pos, 1) > 0) {
if (line[line_pos] == '\n') {
+ char *url;
line[line_pos] = '\0';
line_pos = 0;
- /* skip medium if it looks like an updates one */
- if (strstr(line, "updates"))
+ /* skip medium if it does not look like a distrib path */
+ if (!strstr(line, ",type=distrib,"))
continue;
- if (mirrorlist_entry_split(line, mirrorlist[mirrorlist_number]) < 0)
+ url = strstr(line, ",url=");
+ if (!url)
continue;
+ url += 5;
- /* 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++;
- }
+ if (url_split(url, protocol, &mirrorlist[0][mirror_idx], &mirrorlist[1][mirror_idx]) < 0)
+ continue;
- mirrorlist_number++;
+ mirror_idx++;
} else {
line_pos++;
}
- if (mirrorlist_number >= MIRRORLIST_MAX_ITEMS || media_number >= MIRRORLIST_MAX_MEDIA)
+ if (mirror_idx >= MIRRORLIST_MAX_ITEMS)
break;
}
close(fd);
- mirrorlist[mirrorlist_number][0] = NULL;
- medialist[media_number] = NULL;
+ mirrorlist[0][mirror_idx] = NULL;
+ mirrorlist[1][mirror_idx] = NULL;
+
+ return RETURN_OK;
+}
+
+static int choose_mirror_from_host_list(mirrorlist_t mirrorlist, char **selected_host, char **filepath)
+{
+ enum return_type results;
+ int mirror_idx = 0;
+
+ do {
+ results = ask_from_list_index("Please select a mirror from the list below.",
+ mirrorlist[0], NULL, &mirror_idx);
+
+ if (results == RETURN_BACK) {
+ return RETURN_ERROR;
+ } else if (results == RETURN_OK) {
+ if (mirror_idx == 0) {
+ /* enter the mirror manually */
+ return RETURN_OK;
+ }
+ *selected_host = strdup(mirrorlist[0][mirror_idx]);
+ *filepath = strdup(mirrorlist[1][mirror_idx]);
+ return RETURN_OK;
+ }
+ } 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 *versions[] = { "Specify the mirror manually", DISTRIB_NAME " " DISTRIB_VERSION, NULL };
+ char *version = DISTRIB_NAME " " DISTRIB_VERSION;
do {
- results = ask_from_list("Please select a medium from the list below.",
- medialist, &selected_medium);
+ results = ask_from_list("Please select a medium from the list below.", versions, &version);
if (results == RETURN_BACK) {
return RETURN_BACK;
} else if (results == RETURN_OK) {
- if (!strcmp(selected_medium, medialist[0])) {
+ if (!strcmp(version, versions[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);
+ mirrorlist_t mirrorlist;
+ mirrorlist[0][0] = "Specify the mirror manually";
+ mirrorlist[1][0] = NULL;
+
+ results = get_mirrorlist(mirrorlist, 1, DISTRIB_VERSION, protocol, http_proxy_host, http_proxy_port);
+ if (results == RETURN_ERROR)
+ return RETURN_ERROR;
+
+ results = choose_mirror_from_host_list(mirrorlist, selected_host, filepath);
}
}
} while (results == RETURN_ERROR);
return results;
}
-#endif
/* -=-=-- */
@@ -866,7 +932,6 @@ 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);
@@ -887,15 +952,16 @@ enum return_type nfs_prepare(void)
strcat(nfsmount_location, ":");
strcat(nfsmount_location, answers[1]);
- if (my_mount(nfsmount_location, nfs_own_mount, "nfs", 0) == -1) {
+ if (my_mount(nfsmount_location, MEDIA_LOCATION, "nfs", 0) == -1) {
stg1_error_message("I can't mount the directory from the NFS server.");
results = RETURN_BACK;
continue;
}
+ free(nfsmount_location); nfsmount_location = NULL;
- results = try_with_directory(nfs_own_mount, "nfs", "nfs-iso");
+ results = try_with_directory(MEDIA_LOCATION, "nfs", "nfs-iso");
if (results != RETURN_OK)
- umount(nfs_own_mount);
+ umount(MEDIA_LOCATION);
if (results == RETURN_ERROR)
return RETURN_ERROR;
}
@@ -905,7 +971,6 @@ enum return_type nfs_prepare(void)
}
-#ifndef MANDRAKE_MOVE
enum return_type ftp_prepare(void)
{
char * questions[] = { "FTP server", DISTRIB_NAME " directory", "Login", "Password", NULL };
@@ -936,11 +1001,12 @@ enum return_type ftp_prepare(void)
char location_full[500];
int ftp_serv_response = -1;
int fd, size;
+ int need_arch = 0;
char ftp_hostname[500];
if (!IS_AUTOMATIC) {
if (answers == NULL)
- answers = (char **) malloc(sizeof(questions));
+ answers = (char **) calloc(1, sizeof(questions));
results = choose_mirror_from_list(http_proxy_host, http_proxy_port, "ftp", &answers[0], &answers[1]);
@@ -972,8 +1038,6 @@ enum return_type ftp_prepare(void)
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) {
@@ -987,32 +1051,9 @@ enum return_type ftp_prepare(void)
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("/"));
+ strcat(location_full, COMPRESSED_FILE_REL("/"));
log_message("FTP: trying to retrieve %s", location_full);
@@ -1031,6 +1072,21 @@ enum return_type ftp_prepare(void)
fd = ftp_start_download(ftp_serv_response, location_full, &size);
}
+ /* Try arched directory */
+ if (fd < 0) {
+ log_message("%s failed.", location_full);
+ char *with_arch = asprintf_("%s%s/%s/%s", answers[1][0] == '/' ? "" : "/", answers[1], ARCH, COMPRESSED_FILE_REL("/"));
+ log_message("trying %s...", with_arch);
+ if (use_http_proxy)
+ fd = http_download_file(answers[0], with_arch, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
+ else
+ fd = ftp_start_download(ftp_serv_response, with_arch, &size);
+ if (0 < fd) {
+ strcpy(location_full, with_arch);
+ need_arch = 1;
+ }
+ }
+
if (fd < 0) {
char *msg = str_ftp_error(fd);
log_message("FTP: error get %d for remote file %s", fd, location_full);
@@ -1041,7 +1097,7 @@ enum return_type ftp_prepare(void)
log_message("FTP: size of download %d bytes", size);
- results = load_clp_fd(fd, size);
+ results = load_compressed_fd(fd, size);
if (results == RETURN_OK) {
if (!use_http_proxy)
ftp_end_data_command(ftp_serv_response);
@@ -1052,13 +1108,17 @@ enum return_type ftp_prepare(void)
if (use_http_proxy) {
add_to_env("METHOD", "http");
- sprintf(location_full, "ftp://%s%s", ftp_hostname, answers[1]);
+ snprintf(location_full, sizeof(location_full), "ftp://%s%s", ftp_hostname, answers[1]);
+ if (need_arch)
+ strcat(location_full, "/" ARCH);
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]);
+ if (need_arch)
+ strcat(answers[1], "/" ARCH);
add_to_env("PREFIX", answers[1]);
if (!streq(answers[2], "")) {
add_to_env("LOGIN", answers[2]);
@@ -1094,9 +1154,19 @@ enum return_type http_prepare(void)
do {
char location_full[500];
- int fd, size;
+ int fd, size, need_arch = 0;
int use_http_proxy;
+ if (!IS_AUTOMATIC) {
+ if (answers == NULL)
+ answers = (char **) calloc(1, sizeof(questions));
+
+ results = choose_mirror_from_list(http_proxy_host, http_proxy_port, "http", &answers[0], &answers[1]);
+
+ if (results == RETURN_BACK)
+ return http_prepare();
+ }
+
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);
@@ -1107,13 +1177,26 @@ enum return_type http_prepare(void)
strcpy(location_full, answers[1][0] == '/' ? "" : "/");
strcat(location_full, answers[1]);
- strcat(location_full, CLP_FILE_REL("/"));
+ strcat(location_full, COMPRESSED_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);
+
+ /* Try arched directory */
+ if (fd < 0) {
+ log_message("%s failed.", location_full);
+ char *with_arch = asprintf_("%s%s/%s/%s", answers[1][0] == '/' ? "" : "/", answers[1], ARCH, COMPRESSED_FILE_REL("/"));
+ log_message("trying %s...", with_arch);
+ fd = http_download_file(answers[0], with_arch, &size, use_http_proxy ? "http" : NULL, http_proxy_host, http_proxy_port);
+ if (0 < fd) {
+ strcpy(location_full, with_arch);
+ need_arch = 1;
+ }
+ }
+
if (fd < 0) {
log_message("HTTP: error %d", fd);
if (fd == FTPERR_FAILED_CONNECT)
@@ -1126,13 +1209,15 @@ enum return_type http_prepare(void)
log_message("HTTP: size of download %d bytes", size);
- if (load_clp_fd(fd, size) != RETURN_OK) {
+ if (load_compressed_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]);
+ if (need_arch)
+ strcat(location_full, "/" ARCH);
add_to_env("URLPREFIX", location_full);
if (!streq(http_proxy_host, ""))
add_to_env("PROXY", http_proxy_host);
@@ -1144,4 +1229,23 @@ enum return_type http_prepare(void)
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