diff options
| author | Andrea Adami <andrea.adami@gmail.com> | 2009-08-06 01:47:32 +0200 |
|---|---|---|
| committer | Andrea Adami <andrea.adami@gmail.com> | 2009-08-06 01:52:47 +0200 |
| commit | 6211c548044fd843092c306382110a201d9f2a58 (patch) | |
| tree | 5a8922c9a1719d1813d0c93bb0caced06757cae5 | |
| parent | 77d48ff9a933018457176e97b289980e50246d59 (diff) | |
klibc, klibc-utils-static: bump to Testing/1.5.15
| -rw-r--r-- | conf/checksums.ini | 4 | ||||
| -rw-r--r-- | recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch | 18 | ||||
| -rw-r--r-- | recipes/klibc/files/modprobe.patch | 10 | ||||
| -rw-r--r-- | recipes/klibc/files/staging.patch | 14 | ||||
| -rw-r--r-- | recipes/klibc/files/wc.patch | 2 | ||||
| -rw-r--r-- | recipes/klibc/klibc-1.5/fstype-sane-vfat-and-jffs2-for-1.5.patch | 63 | ||||
| -rw-r--r-- | recipes/klibc/klibc-1.5/modprobe.patch | 1985 | ||||
| -rw-r--r-- | recipes/klibc/klibc-1.5/staging.patch | 144 | ||||
| -rw-r--r-- | recipes/klibc/klibc-1.5/wc.patch | 236 | ||||
| -rw-r--r-- | recipes/klibc/klibc-common_1.5.15.inc | 42 | ||||
| -rw-r--r-- | recipes/klibc/klibc-utils-static_1.5.15.bb | 98 | ||||
| -rw-r--r-- | recipes/klibc/klibc_1.5.15.bb | 2 | ||||
| -rw-r--r-- | recipes/klibc/klibc_1.5.15.inc | 146 |
13 files changed, 2742 insertions, 22 deletions
diff --git a/conf/checksums.ini b/conf/checksums.ini index 7ee6d7d730..a69b6b03b6 100644 --- a/conf/checksums.ini +++ b/conf/checksums.ini @@ -11982,6 +11982,10 @@ sha256=6a2efdfc757c518a8185f457799506086084b59498f53db37cfb6728008127e0 md5=481dfdef7273f2cc776c2637f481f017 sha256=27000ba4bc73a5977502b27d7036df24dd6ab94a1c33b8f5d6d54ba62772f0c7 +[http://kernel.org/pub/linux/libs/klibc/Testing/klibc-1.5.15.tar.bz2] +md5=db2152a8a03bd81e21a5f451f537ae3d +sha256=8b5334ef88b075f374b031695181b4302c3e5621bf2737a39fdf28262b0f80f4 + [http://downloads.sourceforge.net/klimt/klimt-src-0.6.1.zip] md5=d12f56384b4ccde11cd756db2b14065c sha256=48ae508d72e453e2a1f5748870362259786b475548c545feaec1aea71d2f8fdb diff --git a/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch b/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch index b52b3e309b..6eb604e45c 100644 --- a/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch +++ b/recipes/klibc/files/fstype-sane-vfat-and-jffs2-for-1.5.patch @@ -3,17 +3,17 @@ Index: klibc-1.5/usr/kinit/fstype/fstype.c --- klibc-1.5.orig/usr/kinit/fstype/fstype.c 2008-02-28 00:48:35.319254938 +0100 +++ klibc-1.5/usr/kinit/fstype/fstype.c 2008-02-28 00:52:20.583257793 +0100 @@ -20,7 +20,7 @@ - #include <endian.h> #include <netinet/in.h> + #include <sys/utsname.h> #include <sys/vfs.h> - +#include <linux/types.h> #define cpu_to_be32(x) __cpu_to_be32(x) /* Needed by romfs_fs.h */ #include "romfs_fs.h" -@@ -33,6 +33,12 @@ - #include "lvm2_sb.h" - #include "iso9660_sb.h" +@@ -37,6 +37,12 @@ + #include "ocfs2_fs.h" + #include "nilfs_fs.h" +#if __BYTE_ORDER == __BIG_ENDIAN +#include <linux/byteorder/big_endian.h> @@ -24,7 +24,7 @@ Index: klibc-1.5/usr/kinit/fstype/fstype.c /* * Slightly cleaned up version of jfs_superblock to * avoid pulling in other kernel header files. -@@ -54,6 +60,27 @@ +@@ -59,6 +65,27 @@ /* Swap needs the definition of block size */ #include "swap_fs.h" @@ -50,14 +50,14 @@ Index: klibc-1.5/usr/kinit/fstype/fstype.c +} + static int gzip_image(const void *buf, unsigned long long *bytes) - { + {277 304 const unsigned char *p = buf; -@@ -277,6 +304,8 @@ +@@ -490,6 +517,8 @@ {1, "ext3", ext3_image}, {1, "ext2", ext2_image}, {1, "minix", minix_image}, + {0, "jffs2", jffs2_image}, + {0, "vfat", vfat_image}, + {1, "nilfs2", nilfs2_image}, + {2, "ocfs2", ocfs2_image}, {8, "reiserfs", reiserfs_image}, - {64, "reiserfs", reiserfs_image}, - {32, "jfs", jfs_image}, diff --git a/recipes/klibc/files/modprobe.patch b/recipes/klibc/files/modprobe.patch index 074b0b6311..61ee340ff9 100644 --- a/recipes/klibc/files/modprobe.patch +++ b/recipes/klibc/files/modprobe.patch @@ -7,16 +7,16 @@ Index: klibc-1.5/usr/utils/Kbuild progs := chroot dd mkdir mkfifo mknod mount pivot_root umount -progs += true false sleep ln nuke minips cat --progs += insmod uname halt kill readlink cpio +-progs += uname halt kill readlink cpio sync dmesg +progs += true false sleep ln nuke minips cat losetup -+progs += insmod uname halt kill readlink cpio modprobe ++progs += uname halt kill readlink cpio sync dmesg modprobe static-y := $(addprefix static/, $(progs)) shared-y := $(addprefix shared/, $(progs)) -@@ -52,7 +52,10 @@ - shared/readlink-y := readlink.o - static/cpio-y := cpio.o +@@ -54,7 +54,10 @@ shared/cpio-y := cpio.o + static/sync-y := sync.o + shared/sync-y := sync.o - +static/modprobe-y := modprobe.o +shared/modprobe-y := modprobe.o diff --git a/recipes/klibc/files/staging.patch b/recipes/klibc/files/staging.patch index 215daad456..390c214f94 100644 --- a/recipes/klibc/files/staging.patch +++ b/recipes/klibc/files/staging.patch @@ -26,13 +26,13 @@ Index: klibc-1.5/scripts/Kbuild.install $(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include $(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)lib - $(Q)mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)bin - $(Q)set -e ; for d in linux scsi asm-$(KLIBCARCH) asm-generic $(ASMKLIBCARCH); do \ - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KLIBCCROSS)include/$$d ; \ + $(Q)set -e ; for d in linux asm asm-$(KLIBCARCH) asm-generic $(ASMKLIBCARCH); do \ for r in $(KLIBCKERNELSRC)/include $(KLIBCKERNELOBJ)/include \ $(KLIBCKERNELOBJ)/include2 ; do \ - [ ! -d $$r/$$d ] || \ -- cp -rfL $$r/$$d/. \ -+ cp -rfd $$r/$$d/. \ + [ ! -d $$r/$$d ] && continue; \ + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KLIBCCROSS)include/$$d ; \ +- cp -rfL $$r/$$d/. \ ++ cp -rfd $$r/$$d/. \ $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/$$d/. ; \ done ; \ done @@ -116,7 +116,7 @@ Index: klibc-1.5/usr/kinit/run-init/Kbuild =================================================================== --- klibc-1.5.orig/usr/kinit/run-init/Kbuild 2007-03-04 02:52:10.000000000 +0100 +++ klibc-1.5/usr/kinit/run-init/Kbuild 2008-02-24 15:13:50.221824559 +0100 -@@ -21,5 +21,3 @@ +@@ -25,5 +25,3 @@ # Cleaning clean-dirs := static shared @@ -136,7 +136,7 @@ Index: klibc-1.5/usr/utils/Kbuild =================================================================== --- klibc-1.5.orig/usr/utils/Kbuild 2007-03-04 02:52:10.000000000 +0100 +++ klibc-1.5/usr/utils/Kbuild 2008-02-24 15:13:50.229824358 +0100 -@@ -64,5 +64,3 @@ +@@ -66,5 +66,3 @@ # Clean deletes the static and shared dir clean-dirs := static shared diff --git a/recipes/klibc/files/wc.patch b/recipes/klibc/files/wc.patch index 296a4f9d92..f54c49d3ab 100644 --- a/recipes/klibc/files/wc.patch +++ b/recipes/klibc/files/wc.patch @@ -8,7 +8,7 @@ Index: klibc-1.5/usr/utils/Kbuild progs := chroot dd mkdir mkfifo mknod mount pivot_root umount -progs += true false sleep ln nuke minips cat losetup +progs += true false sleep ln nuke minips cat losetup wc - progs += insmod uname halt kill readlink cpio modprobe + progs += uname halt kill readlink cpio sync dmesg modprobe static-y := $(addprefix static/, $(progs)) @@ -56,6 +56,9 @@ diff --git a/recipes/klibc/klibc-1.5/fstype-sane-vfat-and-jffs2-for-1.5.patch b/recipes/klibc/klibc-1.5/fstype-sane-vfat-and-jffs2-for-1.5.patch new file mode 100644 index 0000000000..2ba6d98172 --- /dev/null +++ b/recipes/klibc/klibc-1.5/fstype-sane-vfat-and-jffs2-for-1.5.patch @@ -0,0 +1,63 @@ +Index: klibc-1.5/usr/kinit/fstype/fstype.c +=================================================================== +--- klibc-1.5.orig/usr/kinit/fstype/fstype.c 2008-02-28 00:48:35.319254938 +0100 ++++ klibc-1.5/usr/kinit/fstype/fstype.c 2008-02-28 00:52:20.583257793 +0100 +@@ -20,7 +20,7 @@ + #include <endian.h> + #include <netinet/in.h> + #include <sys/vfs.h> +- ++#include <linux/types.h> + #define cpu_to_be32(x) __cpu_to_be32(x) /* Needed by romfs_fs.h */ + + #include "romfs_fs.h" +@@ -33,6 +33,12 @@ + #include "lvm2_sb.h" + #include "iso9660_sb.h" + ++#if __BYTE_ORDER == __BIG_ENDIAN ++#include <linux/byteorder/big_endian.h> ++#else ++#include <linux/byteorder/little_endian.h> ++#endif ++ + /* + * Slightly cleaned up version of jfs_superblock to + * avoid pulling in other kernel header files. +@@ -54,6 +60,27 @@ + /* Swap needs the definition of block size */ + #include "swap_fs.h" + ++static int jffs2_image(const unsigned char *buf, unsigned long *blocks) ++{ ++ // Very sloppy! ;-E ++ if (*buf == 0x85 && buf[1] == 0x19) ++ return 1; ++ ++ return 0; ++} ++ ++static int vfat_image(const unsigned char *buf, unsigned long *blocks) ++{ ++ const struct romfs_super_block *sb = ++ (const struct romfs_super_block *)buf; ++ if (!strncmp(buf + 54, "FAT12 ", 8) ++ || !strncmp(buf + 54, "FAT16 ", 8) ++ || !strncmp(buf + 82, "FAT32 ", 8)) ++ return 1; ++ ++ return 0; ++} ++ + static int gzip_image(const void *buf, unsigned long long *bytes) + { + const unsigned char *p = buf; +@@ -277,6 +304,8 @@ + {1, "ext3", ext3_image}, + {1, "ext2", ext2_image}, + {1, "minix", minix_image}, ++ {0, "jffs2", jffs2_image}, ++ {0, "vfat", vfat_image}, + {8, "reiserfs", reiserfs_image}, + {64, "reiserfs", reiserfs_image}, + {32, "jfs", jfs_image}, diff --git a/recipes/klibc/klibc-1.5/modprobe.patch b/recipes/klibc/klibc-1.5/modprobe.patch new file mode 100644 index 0000000000..dceaf6103f --- /dev/null +++ b/recipes/klibc/klibc-1.5/modprobe.patch @@ -0,0 +1,1985 @@ +Index: klibc-1.5/usr/utils/Kbuild +=================================================================== +--- klibc-1.5.orig/usr/utils/Kbuild 2008-03-07 22:01:45.223695348 +0100 ++++ klibc-1.5/usr/utils/Kbuild 2008-03-07 22:48:44.660783243 +0100 +@@ -3,8 +3,8 @@ + # + + progs := chroot dd mkdir mkfifo mknod mount pivot_root umount +-progs += true false sleep ln nuke minips cat +-progs += insmod uname halt kill readlink cpio ++progs += true false sleep ln nuke minips cat losetup ++progs += insmod uname halt kill readlink cpio modprobe + + static-y := $(addprefix static/, $(progs)) + shared-y := $(addprefix shared/, $(progs)) +@@ -52,7 +52,10 @@ + shared/readlink-y := readlink.o + static/cpio-y := cpio.o + shared/cpio-y := cpio.o +- ++static/modprobe-y := modprobe.o ++shared/modprobe-y := modprobe.o ++static/losetup-y := losetup.o ++shared/losetup-y := losetup.o + # Additionally linked targets + always := static/reboot static/poweroff shared/reboot shared/poweroff + +Index: klibc-1.5/usr/utils/list.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ klibc-1.5/usr/utils/list.h 2008-03-07 22:33:22.287688586 +0100 +@@ -0,0 +1,238 @@ ++/* Stolen from Linux Kernel Source's list.h -- GPL. */ ++#ifndef _MODINITTOOLS_LIST_H ++#define _MODINITTOOLS_LIST_H ++ ++#undef offsetof ++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) ++ ++/** ++ * container_of - cast a member of a structure out to the containing structure ++ * ++ * @ptr: the pointer to the member. ++ * @type: the type of the container struct this is embedded in. ++ * @member: the name of the member within the struct. ++ * ++ */ ++#define container_of(ptr, type, member) ({ \ ++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ ++ (type *)( (char *)__mptr - offsetof(type,member) );}) ++ ++/* ++ * Simple doubly linked list implementation. ++ * ++ * Some of the internal functions ("__xxx") are useful when ++ * manipulating whole lists rather than single entries, as ++ * sometimes we already know the next/prev entries and we can ++ * generate better code by using them directly rather than ++ * using the generic single-entry routines. ++ */ ++ ++struct list_head { ++ struct list_head *next, *prev; ++}; ++ ++#define LIST_HEAD_INIT(name) { &(name), &(name) } ++ ++#define LIST_HEAD(name) \ ++ struct list_head name = LIST_HEAD_INIT(name) ++ ++#define INIT_LIST_HEAD(ptr) do { \ ++ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ ++} while (0) ++ ++/* ++ * Insert a new entry between two known consecutive entries. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_add(struct list_head *new, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ next->prev = new; ++ new->next = next; ++ new->prev = prev; ++ prev->next = new; ++} ++ ++/** ++ * list_add - add a new entry ++ * @new: new entry to be added ++ * @head: list head to add it after ++ * ++ * Insert a new entry after the specified head. ++ * This is good for implementing stacks. ++ */ ++static inline void list_add(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head, head->next); ++} ++ ++/** ++ * list_add_tail - add a new entry ++ * @new: new entry to be added ++ * @head: list head to add it before ++ * ++ * Insert a new entry before the specified head. ++ * This is useful for implementing queues. ++ */ ++static inline void list_add_tail(struct list_head *new, struct list_head *head) ++{ ++ __list_add(new, head->prev, head); ++} ++ ++/* ++ * Delete a list entry by making the prev/next entries ++ * point to each other. ++ * ++ * This is only for internal list manipulation where we know ++ * the prev/next entries already! ++ */ ++static inline void __list_del(struct list_head * prev, struct list_head * next) ++{ ++ next->prev = prev; ++ prev->next = next; ++} ++ ++/** ++ * list_del - deletes entry from list. ++ * @entry: the element to delete from the list. ++ * Note: list_empty on entry does not return true after this, the entry is ++ * in an undefined state. ++ */ ++static inline void list_del(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++} ++ ++/** ++ * list_del_init - deletes entry from list and reinitialize it. ++ * @entry: the element to delete from the list. ++ */ ++static inline void list_del_init(struct list_head *entry) ++{ ++ __list_del(entry->prev, entry->next); ++ INIT_LIST_HEAD(entry); ++} ++ ++/** ++ * list_move - delete from one list and add as another's head ++ * @list: the entry to move ++ * @head: the head that will precede our entry ++ */ ++static inline void list_move(struct list_head *list, struct list_head *head) ++{ ++ __list_del(list->prev, list->next); ++ list_add(list, head); ++} ++ ++/** ++ * list_move_tail - delete from one list and add as another's tail ++ * @list: the entry to move ++ * @head: the head that will follow our entry ++ */ ++static inline void list_move_tail(struct list_head *list, ++ struct list_head *head) ++{ ++ __list_del(list->prev, list->next); ++ list_add_tail(list, head); ++} ++ ++/** ++ * list_empty - tests whether a list is empty ++ * @head: the list to test. ++ */ ++static inline int list_empty(struct list_head *head) ++{ ++ return head->next == head; ++} ++ ++static inline void __list_splice(struct list_head *list, ++ struct list_head *head) ++{ ++ struct list_head *first = list->next; ++ struct list_head *last = list->prev; ++ struct list_head *at = head->next; ++ ++ first->prev = head; ++ head->next = first; ++ ++ last->next = at; ++ at->prev = last; ++} ++ ++/** ++ * list_splice - join two lists ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ */ ++static inline void list_splice(struct list_head *list, struct list_head *head) ++{ ++ if (!list_empty(list)) ++ __list_splice(list, head); ++} ++ ++/** ++ * list_splice_init - join two lists and reinitialise the emptied list. ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ * ++ * The list at @list is reinitialised ++ */ ++static inline void list_splice_init(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) { ++ __list_splice(list, head); ++ INIT_LIST_HEAD(list); ++ } ++} ++ ++/** ++ * list_entry - get the struct for this entry ++ * @ptr: the &struct list_head pointer. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_entry(ptr, type, member) \ ++ container_of(ptr, type, member) ++ ++/** ++ * list_for_each - iterate over a list ++ * @pos: the &struct list_head to use as a loop counter. ++ * @head: the head for your list. ++ */ ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++ ++/** ++ * list_for_each_prev - iterate over a list backwards ++ * @pos: the &struct list_head to use as a loop counter. ++ * @head: the head for your list. ++ */ ++#define list_for_each_prev(pos, head) \ ++ for (pos = (head)->prev; pos != (head); pos = pos->prev) ++ ++/** ++ * list_for_each_safe - iterate over a list safe against removal of list entry ++ * @pos: the &struct list_head to use as a loop counter. ++ * @n: another &struct list_head to use as temporary storage ++ * @head: the head for your list. ++ */ ++#define list_for_each_safe(pos, n, head) \ ++ for (pos = (head)->next, n = pos->next; pos != (head); \ ++ pos = n, n = pos->next) ++ ++/** ++ * list_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop counter. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ */ ++#define list_for_each_entry(pos, head, member) \ ++ for (pos = list_entry((head)->next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = list_entry(pos->member.next, typeof(*pos), member)) ++ ++#endif +Index: klibc-1.5/usr/utils/modprobe.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ klibc-1.5/usr/utils/modprobe.c 2008-03-08 03:05:51.847688952 +0100 +@@ -0,0 +1,1710 @@ ++/* modprobe.c: insert a module into the kernel, intelligently. ++ Copyright (C) 2001 Rusty Russell. ++ Copyright (C) 2002, 2003 Rusty Russell, IBM Corporation. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++*/ ++#define _GNU_SOURCE /* asprintf */ ++ ++#include <sys/utsname.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/mman.h> ++#include <fcntl.h> ++#include <stdarg.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <ctype.h> ++#include <string.h> ++#include <errno.h> ++#include <unistd.h> ++#include <dirent.h> ++#include <limits.h> ++#include <elf.h> ++#include <getopt.h> ++#include <fnmatch.h> ++#include <asm/unistd.h> ++#include <sys/wait.h> ++#include <syslog.h> ++#include <zlib.h> ++ ++#define streq(a,b) (strcmp((a),(b)) == 0) ++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++ ++#include "list.h" ++static inline void try_old_version(const char *progname, char *argv[]) ++{ ++} ++extern long init_module(void *, unsigned long, const char *); ++extern long delete_module(const char *, unsigned int); ++ ++struct module { ++ struct list_head list; ++ char *modname; ++ char filename[0]; ++}; ++ ++#ifndef MODULE_DIR ++#define MODULE_DIR "/lib/modules" ++#endif ++ ++typedef void (*errfn_t)(const char *fmt, ...); ++ ++/* Do we use syslog or stderr for messages? */ ++static int log; ++ ++static void message(const char *prefix, const char *fmt, va_list *arglist) ++{ ++ char *buf, *buf2; ++ ++ vasprintf(&buf, fmt, *arglist); ++ asprintf(&buf2, "%s%s", prefix, buf); ++ ++ if (log) ++ syslog(LOG_NOTICE, "%s", buf2); ++ else ++ fprintf(stderr, "%s", buf2); ++ free(buf2); ++ free(buf); ++} ++void *grab_contents(gzFile *gzfd, unsigned long *size) ++{ ++ unsigned int max = 16384; ++ void *buffer = malloc(max); ++ int ret; ++ ++ if (!buffer) ++ return NULL; ++ ++ *size = 0; ++ while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) { ++ *size += ret; ++ if (*size == max) { ++ buffer = realloc(buffer, max *= 2); ++ if (!buffer) ++ return NULL; ++ } ++ } ++ if (ret < 0) { ++ free(buffer); ++ buffer = NULL; ++ } ++ return buffer; ++} ++ ++void *grab_fd(int fd, unsigned long *size) ++{ ++ gzFile gzfd; ++ ++ gzfd = gzdopen(fd, "rb"); ++ if (!gzfd) ++ return NULL; ++ ++ /* gzclose(gzfd) would close fd, which would drop locks. ++ Don't blame zlib: POSIX locking semantics are so horribly ++ broken that they should be ripped out. */ ++ return grab_contents(gzfd, size); ++} ++void release_file(void *data, unsigned long size) ++{ ++ free(data); ++} ++ ++ ++static int warned = 0; ++static void warn(const char *fmt, ...) ++{ ++ va_list arglist; ++ warned++; ++ va_start(arglist, fmt); ++ message("WARNING: ", fmt, &arglist); ++ va_end(arglist); ++} ++ ++static void fatal(const char *fmt, ...) ++{ ++ va_list arglist; ++ va_start(arglist, fmt); ++ message("FATAL: ", fmt, &arglist); ++ va_end(arglist); ++ exit(1); ++} ++ ++ ++static void grammar(const char *cmd, const char *filename, unsigned int line) ++{ ++ warn("%s line %u: ignoring bad line starting with '%s'\n", ++ filename, line, cmd); ++} ++ ++static void *do_nofail(void *ptr, const char *file, int line, const char *expr) ++{ ++ if (!ptr) { ++ fatal("Memory allocation failure %s line %d: %s.\n", ++ file, line, expr); ++ } ++ return ptr; ++} ++ ++#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr) ++ ++static void print_usage(const char *progname) ++{ ++ fprintf(stderr, ++ "Usage: %s [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] [-o <modname>] <modname> [parameters...]\n" ++ "%s -r [-n] [-i] [-v] <modulename> ...\n" ++ "%s -l -t <dirname> [ -a <modulename> ...]\n", ++ progname, progname, progname); ++ exit(1); ++} ++ ++static int fgetc_wrapped(FILE *file, unsigned int *linenum) ++{ ++ for (;;) { ++ int ch = fgetc(file); ++ if (ch != '\\') ++ return ch; ++ ch = fgetc(file); ++ if (ch != '\n') ++ return ch; ++ if (linenum) ++ (*linenum)++; ++ } ++} ++ ++static char *getline_wrapped(FILE *file, unsigned int *linenum) ++{ ++ int size = 1024; ++ int i = 0; ++ char *buf = NOFAIL(malloc(size)); ++ for(;;) { ++ int ch = fgetc_wrapped(file, linenum); ++ if (i == size) { ++ size *= 2; ++ buf = NOFAIL(realloc(buf, size)); ++ } ++ if (ch < 0 && i == 0) { ++ free(buf); ++ return NULL; ++ } ++ if (ch < 0 || ch == '\n') { ++ if (linenum) ++ (*linenum)++; ++ buf[i] = '\0'; ++ return NOFAIL(realloc(buf, i+1)); ++ } ++ buf[i++] = ch; ++ } ++} ++ ++static struct module *find_module(const char *filename, struct list_head *list) ++{ ++ struct module *i; ++ ++ list_for_each_entry(i, list, list) { ++ if (strcmp(i->filename, filename) == 0) ++ return i; ++ } ++ return NULL; ++} ++ ++/* Convert filename to the module name. Works if filename == modname, too. */ ++static void filename2modname(char *modname, const char *filename) ++{ ++ const char *afterslash; ++ unsigned int i; ++ ++ afterslash = strrchr(filename, '/'); ++ if (!afterslash) ++ afterslash = filename; ++ else ++ afterslash++; ++ ++ /* Convert to underscores, stop at first . */ ++ for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) { ++ if (afterslash[i] == '-') ++ modname[i] = '_'; ++ else ++ modname[i] = afterslash[i]; ++ } ++ modname[i] = '\0'; ++} ++ ++static int lock_file(const char *filename) ++{ ++ int fd = open(filename, O_RDWR, 0); ++ ++ if (fd >= 0) { ++ struct flock lock; ++ lock.l_type = F_WRLCK; ++ lock.l_whence = SEEK_SET; ++ lock.l_start = 0; ++ lock.l_len = 1; ++ fcntl(fd, F_SETLKW, &lock); ++ } else ++ /* Read-only filesystem? There goes locking... */ ++ fd = open(filename, O_RDONLY, 0); ++ return fd; ++} ++ ++static void unlock_file(int fd) ++{ ++ /* Valgrind is picky... */ ++ close(fd); ++} ++ ++static void add_module(char *filename, int namelen, struct list_head *list) ++{ ++ struct module *mod; ++ ++ /* If it's a duplicate: move it to the end, so it gets ++ inserted where it is *first* required. */ ++ mod = find_module(filename, list); ++ if (mod) ++ list_del(&mod->list); ++ else { ++ /* No match. Create a new module. */ ++ mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1)); ++ memcpy(mod->filename, filename, namelen); ++ mod->filename[namelen] = '\0'; ++ mod->modname = NOFAIL(malloc(namelen + 1)); ++ filename2modname(mod->modname, mod->filename); ++ } ++ ++ list_add_tail(&mod->list, list); ++} ++ ++/* Compare len chars of a to b, with _ and - equivalent. */ ++static int modname_equal(const char *a, const char *b, unsigned int len) ++{ ++ unsigned int i; ++ ++ if (strlen(b) != len) ++ return 0; ++ ++ for (i = 0; i < len; i++) { ++ if ((a[i] == '_' || a[i] == '-') ++ && (b[i] == '_' || b[i] == '-')) ++ continue; ++ if (a[i] != b[i]) ++ return 0; ++ } ++ return 1; ++} ++ ++/* Fills in list of modules if this is the line we want. */ ++static int add_modules_dep_line(char *line, ++ const char *name, ++ struct list_head *list) ++{ ++ char *ptr; ++ int len; ++ char *modname; ++ ++ /* Ignore lines without : or which start with a # */ ++ ptr = strchr(line, ':'); ++ if (ptr == NULL || line[strspn(line, "\t ")] == '#') ++ return 0; ++ ++ /* Is this the module we are looking for? */ ++ *ptr = '\0'; ++ if (strrchr(line, '/')) ++ modname = strrchr(line, '/') + 1; ++ else ++ modname = line; ++ ++ len = strlen(modname); ++ if (strchr(modname, '.')) ++ len = strchr(modname, '.') - modname; ++ if (!modname_equal(modname, name, len)) ++ return 0; ++ ++ /* Create the list. */ ++ add_module(line, ptr - line, list); ++ ++ ptr++; ++ for(;;) { ++ char *dep_start; ++ ptr += strspn(ptr, " \t"); ++ if (*ptr == '\0') ++ break; ++ dep_start = ptr; ++ ptr += strcspn(ptr, " \t"); ++ add_module(dep_start, ptr - dep_start, list); ++ } ++ return 1; ++} ++ ++static void read_depends(const char *dirname, ++ const char *start_name, ++ struct list_head *list) ++{ ++ char *modules_dep_name; ++ char *line; ++ FILE *modules_dep; ++ int done = 0; ++ ++ asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep"); ++ modules_dep = fopen(modules_dep_name, "r"); ++ if (!modules_dep) ++ fatal("Could not load %s: %s\n", ++ modules_dep_name, strerror(errno)); ++ ++ /* Stop at first line, as we can have duplicates (eg. symlinks ++ from boot/ */ ++ while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) { ++ done = add_modules_dep_line(line, start_name, list); ++ free(line); ++ } ++ fclose(modules_dep); ++ free(modules_dep_name); ++} ++ ++/* We use error numbers in a loose translation... */ ++static const char *insert_moderror(int err) ++{ ++ switch (err) { ++ case ENOEXEC: ++ return "Invalid module format"; ++ case ENOENT: ++ return "Unknown symbol in module, or unknown parameter (see dmesg)"; ++ case ENOSYS: ++ return "Kernel does not have module support"; ++ default: ++ return strerror(err); ++ } ++} ++ ++static const char *remove_moderror(int err) ++{ ++ switch (err) { ++ case ENOENT: ++ return "No such module"; ++ case ENOSYS: ++ return "Kernel does not have module unloading support"; ++ default: ++ return strerror(err); ++ } ++} ++ ++/* Is module in /proc/modules? If so, fill in usecount if not NULL. ++ 0 means no, 1 means yes, -1 means unknown. ++ */ ++static int module_in_kernel(const char *modname, unsigned int *usecount) ++{ ++ FILE *proc_modules; ++ char *line; ++ ++again: ++ /* Might not be mounted yet. Don't fail. */ ++ proc_modules = fopen("/proc/modules", "r"); ++ if (!proc_modules) ++ return -1; ++ ++ while ((line = getline_wrapped(proc_modules, NULL)) != NULL) { ++ char *entry = strtok(line, " \n"); ++ ++ if (entry && streq(entry, modname)) { ++ /* If it exists, usecount is the third entry. */ ++ if (!strtok(NULL, " \n")) ++ goto out; ++ ++ if (!(entry = strtok(NULL, " \n"))) /* usecount */ ++ goto out; ++ else ++ if (usecount) ++ *usecount = atoi(entry); ++ ++ /* Followed by - then status. */ ++ if (strtok(NULL, " \n") ++ && (entry = strtok(NULL, " \n")) != NULL) { ++ /* Locking will fail on ro fs, we might hit ++ * cases where module is in flux. Spin. */ ++ if (streq(entry, "Loading") ++ || streq(entry, "Unloading")) { ++ usleep(100000); ++ free(line); ++ fclose(proc_modules); ++ goto again; ++ } ++ } ++ ++ out: ++ free(line); ++ fclose(proc_modules); ++ return 1; ++ } ++ free(line); ++ } ++ fclose(proc_modules); ++ return 0; ++} ++ ++static void replace_modname(struct module *module, ++ void *mem, unsigned long len, ++ const char *oldname, const char *newname) ++{ ++ char *p; ++ ++ /* 64 - sizeof(unsigned long) - 1 */ ++ if (strlen(newname) > 55) ++ fatal("New name %s is too long\n", newname); ++ ++ /* Find where it is in the module structure. Don't assume layout! */ ++ for (p = mem; p < (char *)mem + len - strlen(oldname); p++) { ++ if (memcmp(p, oldname, strlen(oldname)) == 0) { ++ strcpy(p, newname); ++ return; ++ } ++ } ++ ++ warn("Could not find old name in %s to replace!\n", module->filename); ++} ++ ++static void *get_section32(void *file, ++ unsigned long size, ++ const char *name, ++ unsigned long *secsize) ++{ ++ Elf32_Ehdr *hdr = file; ++ Elf32_Shdr *sechdrs = file + hdr->e_shoff; ++ const char *secnames; ++ unsigned int i; ++ ++ /* Too short? */ ++ if (size < sizeof(*hdr)) ++ return NULL; ++ if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0])) ++ return NULL; ++ if (size < sechdrs[hdr->e_shstrndx].sh_offset) ++ return NULL; ++ ++ secnames = file + sechdrs[hdr->e_shstrndx].sh_offset; ++ for (i = 1; i < hdr->e_shnum; i++) ++ if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) { ++ *secsize = sechdrs[i].sh_size; ++ return file + sechdrs[i].sh_offset; ++ } ++ return NULL; ++} ++ ++static void *get_section64(void *file, ++ unsigned long size, ++ const char *name, ++ unsigned long *secsize) ++{ ++ Elf64_Ehdr *hdr = file; ++ Elf64_Shdr *sechdrs = file + hdr->e_shoff; ++ const char *secnames; ++ unsigned int i; ++ ++ /* Too short? */ ++ if (size < sizeof(*hdr)) ++ return NULL; ++ if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0])) ++ return NULL; ++ if (size < sechdrs[hdr->e_shstrndx].sh_offset) ++ return NULL; ++ ++ secnames = file + sechdrs[hdr->e_shstrndx].sh_offset; |
