dnl For ArchLinux handler.
AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no])
+dnl Support for gzipped kernel modules.
+AC_CHECK_LIB([z],[gzopen])
+
dnl Required programs, libraries.
AC_PATH_PROG([MKE2FS],[mke2fs],[no],
[$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR])
* ext2 filesystem on it.
*/
static const char *kmods[] = {
- "ext2.ko",
- "ext4.ko", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */
- "virtio*.ko",
- "ide*.ko",
- "libata*.ko",
- "piix*.ko",
- "scsi_transport_spi.ko",
- "scsi_mod.ko",
- "sd_mod.ko",
- "sym53c8xx.ko",
- "ata_piix.ko",
- "sr_mod.ko",
- "mbcache.ko",
- "crc*.ko",
- "libcrc*.ko",
+ "ext2.ko*",
+ "ext4.ko*", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */
+ "virtio*.ko*",
+ "ide*.ko*",
+ "libata*.ko*",
+ "piix*.ko*",
+ "scsi_transport_spi.ko*",
+ "scsi_mod.ko*",
+ "sd_mod.ko*",
+ "sym53c8xx.ko*",
+ "ata_piix.ko*",
+ "sr_mod.ko*",
+ "mbcache.ko*",
+ "crc*.ko*",
+ "libcrc*.ko*",
NULL
};
#include <asm/unistd.h>
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
extern long init_module (void *, unsigned long, const char *);
/* translation taken from module-init-tools/insmod.c */
static void
insmod (const char *filename)
{
+ size_t size;
+
if (verbose)
fprintf (stderr, "febootstrap: internal insmod %s\n", filename);
+#ifdef HAVE_LIBZ
+ gzFile gzfp = gzopen (filename, "rb");
+ int capacity = 64*1024;
+ char *buf = (char *) malloc (capacity);
+ int tmpsize = 8 * 1024;
+ char tmp[tmpsize];
+ int num;
+
+ size = 0;
+
+ if (gzfp == NULL) {
+ fprintf (stderr, "insmod: gzopen failed: %s", filename);
+ exit (EXIT_FAILURE);
+ }
+ while ((num = gzread (gzfp, tmp, tmpsize)) > 0) {
+ if (num > capacity) {
+ buf = (char*) realloc (buf, size*2);
+ capacity = size;
+ }
+ memcpy (buf+size, tmp, num);
+ capacity -= num;
+ size += num;
+ }
+ if (num == -1) {
+ perror ("insmod: gzread");
+ exit (EXIT_FAILURE);
+ }
+ gzclose (gzfp);
+#else
int fd = open (filename, O_RDONLY);
if (fd == -1) {
fprintf (stderr, "insmod: open: %s: %m\n", filename);
perror ("insmod: fstat");
exit (EXIT_FAILURE);
}
- char buf[st.st_size];
- long offset = 0;
+ size = st.st_size;
+ char buf[size];
+ size_t offset = 0;
do {
- long rc = read (fd, buf + offset, st.st_size - offset);
+ ssize_t rc = read (fd, buf + offset, size - offset);
if (rc == -1) {
perror ("insmod: read");
exit (EXIT_FAILURE);
}
offset += rc;
- } while (offset < st.st_size);
+ } while (offset < size);
close (fd);
+#endif
- if (init_module (buf, st.st_size, "") != 0) {
+ if (init_module (buf, size, "") != 0) {
fprintf (stderr, "insmod: init_module: %s: %s\n", filename, moderror (errno));
/* However ignore the error because this can just happen because
* of a missing device.
*/
}
+
+#ifdef HAVE_LIBZ
+ free (buf);
+#endif
}
/* Mount /proc unless it's mounted already. */