TARGET = $(DIR_INFO)/$(THISAPP)
SLOGAN = An Open Source Firewall Solution
+DOWNLOAD_URL = http://downloads.ipfire.org/releases/ipfire-2.x/$(VERSION)-core$(CORE)/$(SNAME)-$(VERSION).$(MACHINE)-full-core$(CORE).iso
###############################################################################
# Top-level Rules
--with-distro-name="$(NAME)" \
--with-distro-sname="$(SNAME)" \
--with-distro-slogan="$(SLOGAN)" \
- --with-config-root="$(CONFIG_ROOT)"
+ --with-config-root="$(CONFIG_ROOT)" \
+ --with-download-url="$(DOWNLOAD_URL)"
+
cd $(DIR_APP) && make $(MAKETUNING)
cd $(DIR_APP) && make install
- #Patch ISO Name for download ...
- #sed -i -e "s|ipfire.iso|download.ipfire.org/releases/ipfire-2.x/$(VERSION)-core$(CORE)/$(SNAME)-$(VERSION).$(MACHINE)-full-core$(CORE).iso|g" \
- # /usr/bin/downloadsource.sh
@rm -rf $(DIR_APP)
@$(POSTBUILD)
AC_DEFINE_UNQUOTED([CONFIG_ROOT], "$withval", [The config-root]),
AC_MSG_ERROR([*** you need to set CONFIG_ROOT with --with-config-root=]))
+AC_ARG_WITH([download-url],
+ AS_HELP_STRING([--with-download-url] [The default download URL]),
+ AC_DEFINE_UNQUOTED([DOWNLOAD_URL], "$withval", [The default download URL]),
+ AC_MSG_ERROR([*** you need to set DOWNLOAD_URL with --with-download-url=]))
+
AC_CONFIG_FILES([
Makefile
po/Makefile.in
# #
###############################################################################
-#lfs change the url while build!
-IPFireISO=ipfire.iso
-#
-
-#Get user defined download from boot cmdline
-grep "netinstall=" /proc/cmdline > /dev/null && CMDLINE=1
-if ( [ "$CMDLINE" == "1" ]); then
- read CMDLINE < /proc/cmdline
- POS=${CMDLINE%%netinstall*}
- POS=${#POS}
- IPFireISO=`echo ${CMDLINE:POS} | cut -d"=" -f2 | cut -d" " -f1`
+function download() {
+ wget -U "IPFire-NetInstall/2.x" "$@"
+}
+
+if [ $# -lt 2 ]; then
+ echo "$0: Insufficient number of arguments" >&2
+ exit 2
+fi
+
+OUTPUT="${1}"
+URL="${2}"
+
+echo "Downloading ${URL}..."
+if ! download -O "${OUTPUT}" "${URL}"; then
+ echo "Download failed" >&2
+
+ rm -f "${OUTPUT}"
+ exit 1
fi
-echo "Download with wget..."
-wget $IPFireISO -O /tmp/download.iso -t3 -U IPFire_NetInstall/2.x
-wget $IPFireISO.md5 -O /tmp/download.iso.md5 -t3 -U IPFire_NetInstall/2.x
-echo
-echo "Checking download..."
-md5_file=`md5sum /tmp/download.iso | cut -d" " -f1`
-md5_down=`cat /tmp/download.iso.md5 | cut -d" " -f1`
-if [ "$md5_file" == "$md5_down" ]; then
- echo -n "/tmp/download.iso" > /tmp/source_device
- exit 0
+# Download went well. Checking for MD5 sum
+if download -O "${OUTPUT}.md5" "${URL}.md5" &>/dev/null; then
+ # Read downloaded checksum
+ read -r md5sum rest < "${OUTPUT}.md5"
+ rm -f "${OUTPUT}.md5"
+
+ # Compute checkum of downloaded image file
+ read -r md5sum_image rest <<< "$(md5sum "${OUTPUT}")"
+
+ if [ "${md5sum}" != "${md5sum_image}" ]; then
+ echo "MD5 sum mismatch: ${md5sum} != ${md5sum_image}" >&2
+ exit 2
+ fi
fi
-echo "Error - SKIP"
-exit 10
+
+exit 0
#
########################################################################
-dhcpcd_up()
-{
- set | grep "^new_" | sed "s|^new_||g" | \
- sed "s|'||g" | \
- sort > /var/ipfire/dhcpc/dhcpcd-$interface.info
+LEASE_FILE="/var/ipfire/dhcpc/dhcpcd-${interface}.info"
- DNS=`grep "domain_name_servers" /var/ipfire/dhcpc/dhcpcd-$interface.info | cut -d"=" -f2`
- DNS1=`echo $DNS | cut -d" " -f1`
- DNS2=`echo $DNS | cut -d" " -f2`
+export_lease() {
+ set | grep "^new_" | sed "s|^new_||g" | \
+ sed "s|'||g" | sort > ${LEASE_FILE}
+}
- echo "nameserver $DNS1" > /etc/resolv.conf
- echo "nameserver $DNS2" >> /etc/resolv.conf
+make_resolvconf() {
+ local DNS="$(grep 'domain_name_servers' ${LEASE_FILE} | cut -d'=' -f2)"
+ local DNS1="$(echo ${DNS} | cut -d' ' -f1)"
+ local DNS2="$(echo ${DNS} | cut -d' ' -f2)"
+ (
+ echo "nameserver ${DNS1}"
+ echo "nameserver ${DNS2}"
+ ) > /etc/resolv.conf
}
-case "$reason" in
-BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC) dhcpcd_up;;
+case "${reason}" in
+ PREINIT)
+ # Configure MTU
+ if [ -n "${new_interface_mtu}" ] && [ ${new_interface_mtu} -gt 576 ]; then
+ echo "Setting MTU to ${new_interface_mtu}"
+ ip link set "${interface}" mtu "${new_interface_mtu}"
+ fi
+ ;;
+
+ BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)
+ # Export all information about the newly received lease
+ # to file
+ export_lease
+
+ # Create system configuration files
+ make_resolvconf
+ ;;
+
+ EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP)
+ rm -f "${LEASE_FILE}"
+ ;;
esac
+
+exit 0
inst_multiple tar gzip lzma xz
# Networking
- inst_multiple dhcpcd ethtool hostname ip ping wget
+ inst_multiple dhcpcd ethtool hostname ip ping sort wget
inst /usr/bin/start-networking.sh
- inst /var/ipfire/dhcpc/dhcpcd-run-hooks
inst /var/ipfire/dhcpc/dhcpcd.conf
- for file in /var/ipfire/dhcpc/dhcpcd-hooks/*; do
- inst "${file}"
- done
+ inst /var/ipfire/dhcpc/dhcpcd-run-hooks
inst "$moddir/70-dhcpcd.exe" "/var/ipfire/dhcpc/dhcpcd-hooks/70-dhcpcd.exe"
+ inst /etc/host.conf /etc/hosts /etc/protocols
+ inst /etc/nsswitch.conf /etc/resolv.conf
+ inst_libdir_file "libnss_dns.so.*"
+
# Misc. tools
- inst_multiple cut grep eject killall md5sum touch
+ inst_multiple cut grep eject id killall md5sum touch
inst_multiple -o fdisk cfdisk df ps top
# Hardware IDs
#include <blkid/blkid.h>
#include <fcntl.h>
#include <libudev.h>
+#include <linux/loop.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
+#include <sys/stat.h>
#include <sys/swap.h>
#include <sys/sysinfo.h>
#include <unistd.h>
return (strncmp(a, b, strlen(b)) == 0);
}
+static char loop_device[STRING_SIZE];
+
+static int setup_loop_device(const char* source, const char* device) {
+ int file_fd = open(source, O_RDWR);
+ if (file_fd < 0)
+ goto ERROR;
+
+ int device_fd = -1;
+ if ((device_fd = open(device, O_RDWR)) < 0)
+ goto ERROR;
+
+ if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0)
+ goto ERROR;
+
+ close(file_fd);
+ close(device_fd);
+
+ return 0;
+
+ERROR:
+ if (file_fd >= 0)
+ close(file_fd);
+
+ if (device_fd >= 0) {
+ ioctl(device_fd, LOOP_CLR_FD, 0);
+ close(device_fd);
+ }
+
+ return -1;
+}
+
int hw_mount(const char* source, const char* target, const char* fs, int flags) {
+ const char* loop_device = "/dev/loop0";
+
// Create target if it does not exist
if (access(target, X_OK) != 0)
mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO);
+ struct stat st;
+ stat(source, &st);
+
+ if (S_ISREG(st.st_mode)) {
+ int r = setup_loop_device(source, loop_device);
+ if (r == 0) {
+ source = loop_device;
+ } else {
+ return -1;
+ }
+ }
+
return mount(source, target, fs, flags, NULL);
}
int unattended;
int serial_console;
int require_networking;
+ int perform_download;
+ char download_url[STRING_SIZE];
} config = {
.unattended = 0,
.serial_console = 0,
.require_networking = 0,
+ .perform_download = 0,
+ .download_url = DOWNLOAD_URL,
};
static void parse_command_line(struct config* c) {
+ char buffer[STRING_SIZE];
char cmdline[STRING_SIZE];
FILE* f = fopen("/proc/cmdline", "r");
int r = fread(&cmdline, 1, sizeof(cmdline) - 1, f);
if (r > 0) {
- char* token = strtok(&cmdline, " ");
+ char* token = strtok(cmdline, " ");
while (token) {
+ strncpy(buffer, token, sizeof(buffer));
+ char* val = &buffer;
+ char* key = strsep(&val, "=");
+
// serial console
if (strcmp(token, "console=ttyS0") == 0)
c->serial_console = 1;
else if (strcmp(token, "installer.unattended") == 0)
c->unattended = 1;
+ // download url
+ else if (strcmp(key, "installer.download-url") == 0) {
+ strncpy(&c->download_url, val, sizeof(c->download_url));
+ c->perform_download = 1;
+
+ // Require networking for the download
+ c->require_networking = 1;
+ }
+
token = strtok(NULL, " ");
}
}
/* Search for a source drive that holds the right
* version of the image we are going to install. */
- sourcedrive = hw_find_source_medium(hw);
- fprintf(flog, "Source drive: %s\n", sourcedrive);
+ if (!config.perform_download) {
+ sourcedrive = hw_find_source_medium(hw);
+ fprintf(flog, "Source drive: %s\n", sourcedrive);
+ }
/* If we could not find a source drive, we will try
* downloading the install image */
- if (!sourcedrive) {
+ if (!sourcedrive)
+ config.perform_download = 1;
+
+ if (config.perform_download) {
if (!config.unattended) {
// Show the right message to the user
char reason[STRING_SIZE];
- if (config.require_networking) {
+ if (config.perform_download) {
snprintf(reason, sizeof(reason),
_("The installer will now try downloading the installation image."));
} else {
goto EXIT;
}
+ // Make sure that we enable networking before download
config.require_networking = 1;
}
}
// Download the image if required
- while (!sourcedrive) {
- snprintf(commandstring, sizeof(commandstring), "/usr/bin/downloadsource.sh %s", SOURCE_TEMPFILE);
- runcommandwithstatus(commandstring, title, _("Downloading installation image..."), logfile);
-
- FILE* f = fopen(SOURCE_TEMPFILE, "r");
- if (f) {
- sourcedrive = SOURCE_TEMPFILE;
- fclose(f);
- } else {
- rc = newtWinOkCancel(title, _("The installation image could not be downloaded."),
- 60, 8, _("Retry"), _("Cancel"));
+ if (config.perform_download) {
+ fprintf(flog, "Download URL: %s\n", config.download_url);
+ snprintf(commandstring, sizeof(commandstring), "/usr/bin/downloadsource.sh %s %s",
+ SOURCE_TEMPFILE, config.download_url);
+
+ while (!sourcedrive) {
+ rc = runcommandwithstatus(commandstring, title, _("Downloading installation image..."), logfile);
+
+ FILE* f = fopen(SOURCE_TEMPFILE, "r");
+ if (f) {
+ sourcedrive = SOURCE_TEMPFILE;
+ fclose(f);
+ } else {
+ char reason[STRING_SIZE] = "-";
+ if (rc == 2)
+ snprintf(reason, sizeof(STRING_SIZE), _("MD5 checksum mismatch"));
- if (rc)
- goto EXIT;
+ snprintf(message, sizeof(message),
+ _("The installation image could not be downloaded.\n Reason: %s\n\n%s"),
+ reason, config.download_url);
+
+ rc = newtWinOkCancel(title, message, 75, 12, _("Retry"), _("Cancel"));
+ if (rc)
+ goto EXIT;
+ }
}
}
}
int r = hw_mount(sourcedrive, SOURCE_MOUNT_PATH, "iso9660", MS_RDONLY);
if (r) {
- fprintf(flog, "Could not mount %s to %s\n", sourcedrive, SOURCE_MOUNT_PATH);
- fprintf(flog, strerror(errno));
- exit(1);
+ snprintf(message, sizeof(message), _("Could not mount %s to %s:\n %s\n"),
+ sourcedrive, SOURCE_MOUNT_PATH, strerror(errno));
+ errorbox(message);
+ goto EXIT;
}
if (!config.unattended) {
fi
echo "Successfully started on ${interface}"
+
+ # Wait until everything is settled
+ sleep 15
+
return 0
done