diff options
Diffstat (limited to 'mdk-stage1/insmod-busybox')
| -rw-r--r-- | mdk-stage1/insmod-busybox/.cvsignore | 2 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/Config.h | 132 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/Makefile | 65 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/README | 8 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/busybox.h | 467 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/insmod-frontend.c | 24 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/insmod.c | 2951 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/loop.h | 5 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/messages.c | 90 | ||||
| -rw-r--r-- | mdk-stage1/insmod-busybox/utility.c | 1759 | 
10 files changed, 0 insertions, 5503 deletions
| diff --git a/mdk-stage1/insmod-busybox/.cvsignore b/mdk-stage1/insmod-busybox/.cvsignore deleted file mode 100644 index 26a2c08c9..000000000 --- a/mdk-stage1/insmod-busybox/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -insmod -insmod-DIET diff --git a/mdk-stage1/insmod-busybox/Config.h b/mdk-stage1/insmod-busybox/Config.h deleted file mode 100644 index 8388416b7..000000000 --- a/mdk-stage1/insmod-busybox/Config.h +++ /dev/null @@ -1,132 +0,0 @@ -/* vi: set sw=4 ts=4: */ -// This file defines the feature set to be compiled into busybox. -// When you turn things off here, they won't be compiled in at all. -// -//// This file is parsed by sed. You MUST use single line comments. -//   i.e.  //#define BB_BLAH -// -// -// BusyBox Applications -#define BB_INSMOD -// End of Applications List -// -// -// -// --------------------------------------------------------- -// This is where feature definitions go.  Generally speaking, -// turning this stuff off makes things a bit smaller (and less  -// pretty/useful). -// -// -// -// Turn this on to use Erik's very cool devps, and devmtab kernel drivers, -// thereby eliminating the need for the /proc filesystem and thereby saving -// lots and lots memory for more important things.  You can not use this and -// USE_PROCFS at the same time...  NOTE:  If you enable this feature, you -// _must_ have patched the kernel to include the devps patch that is included -// in the busybox/kernel-patches directory.  You will also need to create some -// device special files in /dev on your embedded system: -//        mknod /dev/mtab c 10 22 -//        mknod /dev/ps c 10 21 -// I emailed Linus and this patch will not be going into the stock kernel. -//#define BB_FEATURE_USE_DEVPS_PATCH -// -// enable features that use the /proc filesystem (apps that  -// break without this will tell you on compile)... -// You can't use this and BB_FEATURE_USE_DEVPS_PATCH  -// at the same time... -#define BB_FEATURE_USE_PROCFS - -// -// Enable tab completion in the shell (not yet  -// working very well -- so don't turn this on) -//#define BB_FEATURE_SH_TAB_COMPLETION -// -//Turn on extra fbset options -//#define BB_FEATURE_FBSET_FANCY -// -//Turn on fbset readmode support -//#define BB_FEATURE_FBSET_READMODE -// -// You must enable one or both of these features -// Support installing modules from pre 2.1 kernels -//#define BB_FEATURE_INSMOD_OLD_KERNEL -// Support installing modules from kernel versions after 2.1.18 -#define BB_FEATURE_INSMOD_NEW_KERNEL -// -// Support module version checking -//#define BB_FEATURE_INSMOD_VERSION_CHECKING -// -// Support for Minix filesystem, version 2 -//#define BB_FEATURE_MINIX2 -// -// -// Enable busybox --install [-s] -// to create links (or symlinks) for all the commands that are  -// compiled into the binary.  (needs /proc filesystem) -// #define BB_FEATURE_INSTALLER -// -// Clean up all memory before exiting -- usually not needed -// as the OS can clean up...  Don't enable this unless you -// have a really good reason for cleaning things up manually. -//#define BB_FEATURE_CLEAN_UP -// -// End of Features List -// -// -// -// -// -// -//--------------------------------------------------- -// Nothing beyond this point should ever be touched by  -// mere mortals so leave this stuff alone. -// -#ifdef BB_FEATURE_MOUNT_MTAB_SUPPORT -#define BB_MTAB -#endif -// -#if defined BB_FEATURE_SH_COMMAND_EDITING && defined BB_SH -#define BB_CMDEDIT -#endif -// -#ifdef BB_KILLALL -#ifndef BB_KILL -#define BB_KILL -#endif -#endif -// -#ifdef BB_FEATURE_LINUXRC -#ifndef BB_INIT -#define BB_INIT -#endif -#define BB_LINUXRC -#endif -// -#ifdef BB_GZIP -#ifndef BB_GUNZIP -#define BB_GUNZIP -#endif -#endif -// -#if defined BB_MOUNT && defined BB_FEATURE_NFSMOUNT -#define BB_NFSMOUNT -#endif -// -#if defined BB_FEATURE_SH_COMMAND_EDITING -#ifndef BB_FEATURE_USE_TERMIOS -#define BB_FEATURE_USE_TERMIOS -#endif -#endif -// -#if defined BB_FEATURE_AUTOWIDTH -#ifndef BB_FEATURE_USE_TERMIOS -#define BB_FEATURE_USE_TERMIOS -#endif -#endif -// -#if defined BB_INSMOD -#ifndef BB_FEATURE_INSMOD_OLD_KERNEL -#define BB_FEATURE_INSMOD_NEW_KERNEL -#endif -#endif diff --git a/mdk-stage1/insmod-busybox/Makefile b/mdk-stage1/insmod-busybox/Makefile deleted file mode 100644 index c8649ae0d..000000000 --- a/mdk-stage1/insmod-busybox/Makefile +++ /dev/null @@ -1,65 +0,0 @@ - #****************************************************************************** - # - #    insmod from busybox (i386 only) - # - # $Id$ - # - # Copyright (C) 1999,2000 by Lineo, inc. - # - #***************************************************************************** - -top_dir = .. - -include $(top_dir)/Makefile.common - - -all: insmod insmod-DIET libinsmod.a libinsmod-DIET.a - -clean: -	rm -f *.o insmod insmod-DIET libinsmod.a libinsmod-DIET.a - - -FLAGS = -c -Wall -Os -fomit-frame-pointer -D_GNU_SOURCE -DBB_VER='"0.47"' -DBB_BT='"2000.12.06-14:02+0000"' - - -insmod: insmod-frontend.o insmod.o utility-standalone.o -	gcc -o $@ $^ -	$(STRIPCMD) $@ - -insmod-DIET: insmod-frontend-DIET.o insmod-DIET.o utility-standalone-DIET.o -	gcc $(DIETLIBC_LDFLAGS_STAGE1) -o $@ $^ $(DIETLIBC_LIBC) -	$(STRIPCMD) $@ - - -libinsmod.a: insmod.o utility.o -	ar cru $@ $^ -	ranlib $@ - -libinsmod-DIET.a: insmod-DIET.o utility-DIET.o -	ar cru $@ $^ -	ranlib $@ - -insmod-frontend.o: insmod-frontend.c busybox.h -	gcc $(FLAGS) $(GLIBC_INCLUDES) insmod-frontend.c - -insmod-frontend-DIET.o: insmod-frontend.c busybox.h -	gcc $(FLAGS) $(DIETLIBC_INCLUDES) -o $@ insmod-frontend.c - -utility.o: utility.c busybox.h -	gcc $(FLAGS) $(GLIBC_INCLUDES) utility.c - -utility-DIET.o: utility.c busybox.h -	gcc $(FLAGS) $(DIETLIBC_INCLUDES) -o $@ utility.c - -utility-standalone.o: utility.c busybox.h -	gcc $(FLAGS) $(GLIBC_INCLUDES) -o $@ -D_STANDALONE_ utility.c - -utility-standalone-DIET.o: utility.c busybox.h -	gcc $(FLAGS) $(DIETLIBC_INCLUDES) -o $@ -D_STANDALONE_ utility.c - -insmod.o: insmod.c busybox.h -	gcc $(FLAGS) $(GLIBC_INCLUDES) insmod.c - -insmod-DIET.o: insmod.c busybox.h -	gcc $(FLAGS) $(DIETLIBC_INCLUDES) -o $@ insmod.c - diff --git a/mdk-stage1/insmod-busybox/README b/mdk-stage1/insmod-busybox/README deleted file mode 100644 index 06695074a..000000000 --- a/mdk-stage1/insmod-busybox/README +++ /dev/null @@ -1,8 +0,0 @@ -This insmod code comes from busybox-0.47 - -ftp://ftp.lineo.com/pub/busybox - -It is cool but works only for ix86 architecture. - - -gc diff --git a/mdk-stage1/insmod-busybox/busybox.h b/mdk-stage1/insmod-busybox/busybox.h deleted file mode 100644 index a2d620c8b..000000000 --- a/mdk-stage1/insmod-busybox/busybox.h +++ /dev/null @@ -1,467 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Busybox main internal header file - * - * - * 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 - * - * Based in part on code from sash, Copyright (c) 1999 by David I. Bell  - * Permission has been granted to redistribute this code under the GPL. - * - */ -#ifndef	_BB_INTERNAL_H_ -#define	_BB_INTERNAL_H_    1 - -#include "Config.h" - -#ifdef DMALLOC -#include "dmalloc.h" -#endif - -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/param.h> -/* for the _syscall() macros */ -#include <sys/syscall.h> -#include <linux/unistd.h> -#include <linux/kernel.h> - -/* Some useful definitions */ -#define FALSE   ((int) 1) -#define TRUE    ((int) 0) - -/* for mtab.c */ -#define MTAB_GETMOUNTPT '1' -#define MTAB_GETDEVICE  '2' - -#define BUF_SIZE        8192 -#define EXPAND_ALLOC    1024 - - -#define isBlank(ch)     (((ch) == ' ') || ((ch) == '\t')) -#define isDecimal(ch)   (((ch) >= '0') && ((ch) <= '9')) -#define isOctal(ch)     (((ch) >= '0') && ((ch) <= '7')) -#define isWildCard(ch)  (((ch) == '*') || ((ch) == '?') || ((ch) == '[')) - -/* Macros for min/max.  */ -#ifndef MIN -#define	MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifndef MAX -#define	MAX(a,b) (((a)>(b))?(a):(b)) -#endif - - -/* I don't like nested includes, but the string and io functions are used - * too often - */ -#include <stdio.h> -#if !defined(NO_STRING_H) || defined(STDC_HEADERS) -#  include <string.h> -#  if !defined(STDC_HEADERS) && !defined(NO_MEMORY_H) && !defined(__GNUC__) -#    include <memory.h> -#  endif -#  define memzero(s, n)     memset ((void *)(s), 0, (n)) -#else -#  include <strings.h> -#  define strchr            index -#  define strrchr           rindex -#  define memcpy(d, s, n)   bcopy((s), (d), (n)) -#  define memcmp(s1, s2, n) bcmp((s1), (s2), (n)) -#  define memzero(s, n)     bzero((s), (n)) -#endif - - -enum Location { -	_BB_DIR_ROOT = 0, -	_BB_DIR_BIN, -	_BB_DIR_SBIN, -	_BB_DIR_USR_BIN, -	_BB_DIR_USR_SBIN -}; - -struct BB_applet { -	const	char*	name; -	int	(*main)(int argc, char** argv); -	enum	Location	location; -	const	char*	usage; -}; -/* From busybox.c */ -extern const struct BB_applet applets[]; - -extern int ar_main(int argc, char **argv); -extern int basename_main(int argc, char **argv); -extern int bogomips_main(int argc, char **argv); -extern int busybox_main(int argc, char** argv); -extern int cat_main(int argc, char** argv); -extern int chmod_chown_chgrp_main(int argc, char** argv); -extern int chroot_main(int argc, char** argv); -extern int chvt_main(int argc, char** argv); -extern int clear_main(int argc, char** argv); -extern int cp_mv_main(int argc, char** argv); -extern int cut_main(int argc, char** argv); -extern int date_main(int argc, char** argv); -extern int dc_main(int argc, char** argv); -extern int dd_main(int argc, char** argv); -extern int dirname_main(int argc, char** argv); -extern int deallocvt_main(int argc, char** argv); -extern int df_main(int argc, char** argv); -extern int dmesg_main(int argc, char** argv); -extern int dos2unix_main(int argc, char** argv); -extern int du_main(int argc, char** argv); -extern int dumpkmap_main(int argc, char** argv); -extern int dutmp_main(int argc, char** argv); -extern int echo_main(int argc, char** argv); -extern int expr_main(int argc, char** argv); -extern int false_main(int argc, char** argv); -extern int fbset_main(int argc, char** argv); -extern int fdisk_main(int argc, char** argv); -extern int fdflush_main(int argc, char **argv); -extern int fsck_minix_main(int argc, char **argv); -extern int find_main(int argc, char** argv); -extern int free_main(int argc, char** argv); -extern int freeramdisk_main(int argc, char** argv); -extern int getopt_main(int argc, char** argv); -extern int grep_main(int argc, char** argv); -extern int gunzip_main (int argc, char** argv); -extern int gzip_main(int argc, char** argv); -extern int halt_main(int argc, char** argv); -extern int head_main(int argc, char** argv); -extern int hostid_main(int argc, char** argv); -extern int hostname_main(int argc, char** argv); -extern int id_main(int argc, char** argv); -extern int init_main(int argc, char** argv); -extern int insmod_main(int argc, char** argv); -extern int kill_main(int argc, char** argv); -extern int length_main(int argc, char** argv); -extern int ln_main(int argc, char** argv); -extern int loadacm_main(int argc, char** argv); -extern int loadfont_main(int argc, char** argv); -extern int loadkmap_main(int argc, char** argv); -extern int losetup_main(int argc, char** argv); -extern int logger_main(int argc, char **argv); -extern int logname_main(int argc, char **argv); -extern int ls_main(int argc, char** argv); -extern int lsmod_main(int argc, char** argv); -extern int makedevs_main(int argc, char** argv); -extern int md5sum_main(int argc, char** argv); -extern int mkdir_main(int argc, char** argv); -extern int mkfifo_main(int argc, char **argv); -extern int mkfs_minix_main(int argc, char **argv); -extern int mknod_main(int argc, char** argv); -extern int mkswap_main(int argc, char** argv); -extern int mktemp_main(int argc, char **argv); -extern int nc_main(int argc, char** argv); -extern int more_main(int argc, char** argv); -extern int mount_main(int argc, char** argv); -extern int mt_main(int argc, char** argv); -extern int nslookup_main(int argc, char **argv); -extern int ping_main(int argc, char **argv); -extern int poweroff_main(int argc, char **argv); -extern int printf_main(int argc, char** argv); -extern int ps_main(int argc, char** argv); -extern int pwd_main(int argc, char** argv); -extern int rdate_main(int argc, char** argv); -extern int reboot_main(int argc, char** argv); -extern int renice_main(int argc, char** argv); -extern int reset_main(int argc, char** argv); -extern int rm_main(int argc, char** argv); -extern int rmdir_main(int argc, char **argv); -extern int rmmod_main(int argc, char** argv); -extern int sed_main(int argc, char** argv); -extern int sfdisk_main(int argc, char** argv); -extern int setkeycodes_main(int argc, char** argv); -extern int shell_main(int argc, char** argv); -extern int sleep_main(int argc, char** argv); -extern int sort_main(int argc, char** argv); -extern int swap_on_off_main(int argc, char** argv); -extern int sync_main(int argc, char** argv); -extern int syslogd_main(int argc, char **argv); -extern int tail_main(int argc, char** argv); -extern int tar_main(int argc, char** argv); -extern int tee_main(int argc, char** argv); -extern int test_main(int argc, char** argv); -extern int telnet_main(int argc, char** argv); -extern int touch_main(int argc, char** argv); -extern int tr_main(int argc, char** argv); -extern int true_main(int argc, char** argv); -extern int tput_main(int argc, char** argv); -extern int tryopen_main(int argc, char** argv); -extern int tty_main(int argc, char** argv); -extern int umount_main(int argc, char** argv); -extern int uname_main(int argc, char** argv); -extern int uniq_main(int argc, char** argv); -extern int unix2dos_main(int argc, char** argv); -extern int unrpm_main(int argc, char** argv); -extern int update_main(int argc, char** argv); -extern int uptime_main(int argc, char** argv); -extern int usleep_main(int argc, char** argv); -extern int uuencode_main(int argc, char** argv); -extern int uudecode_main(int argc, char** argv); -extern int wc_main(int argc, char** argv); -extern int wget_main(int argc, char** argv); -extern int which_main(int argc, char** argv); -extern int whoami_main(int argc, char** argv); -extern int xargs_main(int argc, char** argv); -extern int yes_main(int argc, char** argv); - -extern const char ar_usage[]; -extern const char basename_usage[]; -extern const char cat_usage[]; -extern const char chgrp_usage[]; -extern const char chmod_usage[]; -extern const char chown_usage[]; -extern const char chroot_usage[]; -extern const char chvt_usage[]; -extern const char clear_usage[]; -extern const char cp_usage[]; -extern const char cut_usage[]; -extern const char date_usage[]; -extern const char dc_usage[]; -extern const char dd_usage[]; -extern const char deallocvt_usage[]; -extern const char df_usage[]; -extern const char dirname_usage[]; -extern const char dmesg_usage[]; -extern const char dos2unix_usage[]; -extern const char du_usage[]; -extern const char dumpkmap_usage[]; -extern const char dutmp_usage[]; -extern const char echo_usage[]; -extern const char expr_usage[]; -extern const char false_usage[]; -extern const char fdflush_usage[]; -extern const char find_usage[]; -extern const char free_usage[]; -extern const char freeramdisk_usage[]; -extern const char fsck_minix_usage[]; -extern const char grep_usage[]; -extern const char gunzip_usage[]; -extern const char gzip_usage[]; -extern const char halt_usage[]; -extern const char head_usage[]; -extern const char hostid_usage[]; -extern const char hostname_usage[]; -extern const char id_usage[]; -extern const char insmod_usage[]; -extern const char kill_usage[]; -extern const char killall_usage[]; -extern const char length_usage[]; -extern const char ln_usage[]; -extern const char loadacm_usage[]; -extern const char loadfont_usage[]; -extern const char loadkmap_usage[]; -extern const char logger_usage[]; -extern const char logname_usage[]; -extern const char ls_usage[]; -extern const char lsmod_usage[]; -extern const char makedevs_usage[]; -extern const char md5sum_usage[]; -extern const char mkdir_usage[]; -extern const char mkfifo_usage[]; -extern const char mkfs_minix_usage[]; -extern const char mknod_usage[]; -extern const char mkswap_usage[]; -extern const char mktemp_usage[]; -extern const char more_usage[]; -extern const char mount_usage[];  -extern const char mt_usage[]; -extern const char mv_usage[]; -extern const char nc_usage[]; -extern const char nslookup_usage[]; -extern const char ping_usage[]; -extern const char poweroff_usage[]; -extern const char printf_usage[]; -extern const char ps_usage[]; -extern const char pwd_usage[]; -extern const char rdate_usage[]; -extern const char reboot_usage[]; -extern const char renice_usage[]; -extern const char reset_usage[]; -extern const char rm_usage[]; -extern const char rmdir_usage[]; -extern const char rmmod_usage[]; -extern const char sed_usage[]; -extern const char setkeycodes_usage[]; -extern const char shell_usage[]; -extern const char sleep_usage[]; -extern const char sort_usage[]; -extern const char swapoff_usage[]; -extern const char swapon_usage[]; -extern const char sync_usage[]; -extern const char syslogd_usage[]; -extern const char tail_usage[]; -extern const char tar_usage[]; -extern const char tee_usage[]; -extern const char telnet_usage[]; -extern const char test_usage[]; -extern const char touch_usage[]; -extern const char tr_usage[]; -extern const char true_usage[]; -extern const char tty_usage[]; -extern const char umount_usage[]; -extern const char uname_usage[]; -extern const char uniq_usage[]; -extern const char unix2dos_usage[]; -extern const char unrpm_usage[]; -extern const char update_usage[]; -extern const char uptime_usage[]; -extern const char usleep_usage[]; -extern const char uudecode_usage[]; -extern const char uuencode_usage[]; -extern const char wc_usage[]; -extern const char wget_usage[]; -extern const char which_usage[]; -extern const char whoami_usage[]; -extern const char xargs_usage[]; -extern const char yes_usage[]; - -extern const char *applet_name; - -extern void usage(const char *usage) __attribute__ ((noreturn)); -extern void errorMsg(const char *s, ...) __attribute__ ((format (printf, 1, 2))); -extern void logperror(char *s); -extern void fatalError(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))); - -const char *modeString(int mode); -const char *timeString(time_t timeVal); -int isDirectory(const char *name, const int followLinks, struct stat *statBuf); -int isDevice(const char *name); - -typedef struct ino_dev_hash_bucket_struct { -  struct ino_dev_hash_bucket_struct *next; -  ino_t ino; -  dev_t dev; -  char name[1]; -} ino_dev_hashtable_bucket_t; -int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name); -void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); -void reset_ino_dev_hashtable(void); - -int copyFile(const char *srcName, const char *destName, -		 int setModes, int followLinks, int forceFlag); -int copySubFile(int srcFd, int dstFd, size_t remaining); -char *buildName(const char *dirName, const char *fileName); -int makeString(int argc, const char **argv, char *buf, int bufLen); -char *getChunk(int size); -char *chunkstrdup(const char *str); -void freeChunks(void); -int fullWrite(int fd, const char *buf, int len); -int fullRead(int fd, char *buf, int len); -int recursiveAction(const char *fileName, int recurse, int followLinks, int depthFirst, -	  int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData), -	  int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData), -	  void* userData); - -extern int createPath (const char *name, int mode); -extern int parse_mode( const char* s, mode_t* theMode); - -extern int get_kernel_revision(void); - -extern int get_console_fd(char* tty_name); -extern struct mntent *findMountPoint(const char *name, const char *table); -extern void write_mtab(char* blockDevice, char* directory,  -	char* filesystemType, long flags, char* string_flags); -extern void erase_mtab(const char * name); -extern void mtab_read(void); -extern char *mtab_first(void **iter); -extern char *mtab_next(void **iter); -extern char *mtab_getinfo(const char *match, const char which); -extern int check_wildcard_match(const char* text, const char* pattern); -extern long getNum (const char *cp); -extern pid_t* findPidByName( char* pidName); -extern int find_real_root_device_name(char* name); -extern char *get_line_from_file(FILE *file); -extern void print_file(FILE *file); -extern int print_file_by_name(char *filename); -extern char process_escape_sequence(char **ptr); -extern char *get_last_path_component(char *path); -// extern void xregcomp(regex_t *preg, const char *regex, int cflags); - -#ifndef DMALLOC  -extern void *xmalloc (size_t size); -extern void *xrealloc(void *old, size_t size); -extern void *xcalloc(size_t nmemb, size_t size); -extern char *xstrdup (const char *s); -#endif -extern char *xstrndup (const char *s, int n); - - -/* These parse entries in /etc/passwd and /etc/group.  This is desirable - * for BusyBox since we want to avoid using the glibc NSS stuff, which - * increases target size and is often not needed embedded systems.  */ -extern long my_getpwnam(char *name); -extern long my_getgrnam(char *name); -extern void my_getpwuid(char *name, long uid); -extern void my_getgrgid(char *group, long gid); -extern long my_getpwnamegid(char *name); - -extern int device_open(char *device, int mode); - -#if defined BB_FEATURE_MOUNT_LOOP -extern int del_loop(const char *device); -extern int set_loop(const char *device, const char *file, int offset, int *loopro); -extern char *find_unused_loop_device (void); -#endif - - -#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT) -extern int vdprintf(int d, const char *format, va_list ap); -#endif - -#if defined BB_NFSMOUNT -int nfsmount(const char *spec, const char *node, int *flags, -	     char **extra_opts, char **mount_opts, int running_bg); -#endif - -#ifndef RB_POWER_OFF -/* Stop system and switch power off if possible.  */ -#define RB_POWER_OFF   0x4321fedc -#endif - -/* Include our own copy of struct sysinfo to avoid binary compatability - * problems with Linux 2.4, which changed things.  Grumble, grumble. */ -//struct sysinfo { -//	  long uptime;			/* Seconds since boot */ -//	  unsigned long loads[3];		/* 1, 5, and 15 minute load averages */ -//	  unsigned long totalram;		/* Total usable main memory size */ -//	  unsigned long freeram;		/* Available memory size */ -//	  unsigned long sharedram;	/* Amount of shared memory */ -//	  unsigned long bufferram;	/* Memory used by buffers */ -//	  unsigned long totalswap;	/* Total swap space size */ -//	  unsigned long freeswap;		/* swap space still available */ -//	  unsigned short procs;		/* Number of current processes */ -//	  unsigned long totalhigh;	/* Total high memory size */ -//	  unsigned long freehigh;		/* Available high memory size */ -//	  unsigned int mem_unit;		/* Memory unit size in bytes */ -//	  char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */ -//}; -extern int sysinfo (struct sysinfo* info); - -/* Bit map related macros -- libc5 doens't provide these... sigh.  */ -#ifndef setbit -#define NBBY            CHAR_BIT -#define setbit(a,i)     ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a,i)     ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a,i)      ((a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a,i)      (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif - -#endif /* _BB_INTERNAL_H_ */ diff --git a/mdk-stage1/insmod-busybox/insmod-frontend.c b/mdk-stage1/insmod-busybox/insmod-frontend.c deleted file mode 100644 index 3e5d6b3d7..000000000 --- a/mdk-stage1/insmod-busybox/insmod-frontend.c +++ /dev/null @@ -1,24 +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. - * - */ - -#include <stdio.h> - - -int insmod_main( int argc, char **argv); - -int main( int argc, char **argv) -{ -	printf("Using insmod provided by busybox.\n"); -	return insmod_main(argc, argv); -} diff --git a/mdk-stage1/insmod-busybox/insmod.c b/mdk-stage1/insmod-busybox/insmod.c deleted file mode 100644 index bdf7ba5f7..000000000 --- a/mdk-stage1/insmod-busybox/insmod.c +++ /dev/null @@ -1,2951 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Mini insmod implementation for busybox - * - * Copyright (C) 1999,2000 by Lineo, inc. - * Written by Erik Andersen <andersen@lineo.com> - * and Ron Alder <alder@lineo.com> - * - * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4 - * and (theoretically) SH3. Note that there is still no true - * multiple architecture support. You just get SH3|SH4|i386, despite - * the mention of ARM and m68k--which may or may not work (but - * almost certainly do not, due to at least MATCH_MACHINE). I have - * only tested SH4 in little endian mode. - * - * Based almost entirely on the Linux modutils-2.3.11 implementation. - *   Copyright 1996, 1997 Linux International. - *   New implementation contributed by Richard Henderson <rth@tamu.edu> - *   Based on original work by Bjorn Ekwall <bj0rn@blox.se> - *   Restructured (and partly rewritten) by: - *   Björn Ekwall <bj0rn@blox.se> February 1999 - * - * 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 - * - */ - -#include "../insmod.h" -#include "busybox.h" -#include <stdlib.h> -#include <stdio.h> -#include <stddef.h> -#include <errno.h> -#include <unistd.h> -#include <dirent.h> -#include <ctype.h> -#include <assert.h> -#include <sys/utsname.h> - -//---------------------------------------------------------------------------- -//--------modutils module.h, lines 45-242 -//---------------------------------------------------------------------------- - -/* Definitions for the Linux module syscall interface. -   Copyright 1996, 1997 Linux International. - -   Contributed by Richard Henderson <rth@tamu.edu> - -   This file is part of the Linux modutils. - -   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.  */ - - -#ifndef MODUTILS_MODULE_H -#define MODUTILS_MODULE_H 1 - -#ident "$Id$" - -/* This file contains the structures used by the 2.0 and 2.1 kernels. -   We do not use the kernel headers directly because we do not wish -   to be dependant on a particular kernel version to compile insmod.  */ - - -/*======================================================================*/ -/* The structures used by Linux 2.0.  */ - -/* The symbol format used by get_kernel_syms(2).  */ -struct old_kernel_sym -{ -  unsigned long value; -  char name[60]; -}; - -struct old_module_ref -{ -  unsigned long module;		/* kernel addresses */ -  unsigned long next; -}; - -struct old_module_symbol -{ -  unsigned long addr; -  unsigned long name; -}; - -struct old_symbol_table -{ -  int size;			/* total, including string table!!! */ -  int n_symbols; -  int n_refs; -  struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */ -  struct old_module_ref ref[0];	/* actual size defined by n_refs */ -}; - -struct old_mod_routines -{ -  unsigned long init; -  unsigned long cleanup; -}; - -struct old_module -{ -  unsigned long next; -  unsigned long ref;		/* the list of modules that refer to me */ -  unsigned long symtab; -  unsigned long name; -  int size;			/* size of module in pages */ -  unsigned long addr;		/* address of module */ -  int state; -  unsigned long cleanup;	/* cleanup routine */ -}; - -/* Sent to init_module(2) or'ed into the code size parameter.  */ -#define OLD_MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */ - -int get_kernel_syms(struct old_kernel_sym *); -int old_sys_init_module(const char *name, char *code, unsigned codesize, -			struct old_mod_routines *, struct old_symbol_table *); - -/*======================================================================*/ -/* For sizeof() which are related to the module platform and not to the -   environment isnmod is running in, use sizeof_xx instead of sizeof(xx).  */ - -#define tgt_sizeof_char		sizeof(char) -#define tgt_sizeof_short	sizeof(short) -#define tgt_sizeof_int		sizeof(int) -#define tgt_sizeof_long		sizeof(long) -#define tgt_sizeof_char_p	sizeof(char *) -#define tgt_sizeof_void_p	sizeof(void *) -#define tgt_long		long - -#if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64) -#undef tgt_sizeof_long -#undef tgt_sizeof_char_p -#undef tgt_sizeof_void_p -#undef tgt_long -#define tgt_sizeof_long		8 -#define tgt_sizeof_char_p	8 -#define tgt_sizeof_void_p	8 -#define tgt_long		long long -#endif - -/*======================================================================*/ -/* The structures used in Linux 2.1.  */ - -/* Note: new_module_symbol does not use tgt_long intentionally */ -struct new_module_symbol -{ -  unsigned long value; -  unsigned long name; -}; - -struct new_module_persist; - -struct new_module_ref -{ -  unsigned tgt_long dep;		/* kernel addresses */ -  unsigned tgt_long ref; -  unsigned tgt_long next_ref; -}; - -struct new_module -{ -  unsigned tgt_long size_of_struct;	/* == sizeof(module) */ -  unsigned tgt_long next; -  unsigned tgt_long name; -  unsigned tgt_long size; - -  tgt_long usecount; -  unsigned tgt_long flags;		/* AUTOCLEAN et al */ - -  unsigned nsyms; -  unsigned ndeps; - -  unsigned tgt_long syms; -  unsigned tgt_long deps; -  unsigned tgt_long refs; -  unsigned tgt_long init; -  unsigned tgt_long cleanup; -  unsigned tgt_long ex_table_start; -  unsigned tgt_long ex_table_end; -#ifdef __alpha__ -  unsigned tgt_long gp; -#endif -  /* Everything after here is extension.  */ -  unsigned tgt_long persist_start; -  unsigned tgt_long persist_end; -  unsigned tgt_long can_unload; -  unsigned tgt_long runsize; -}; - -struct new_module_info -{ -  unsigned long addr; -  unsigned long size; -  unsigned long flags; -	   long usecount; -}; - -/* Bits of module.flags.  */ -#define NEW_MOD_RUNNING		1 -#define NEW_MOD_DELETED		2 -#define NEW_MOD_AUTOCLEAN	4 -#define NEW_MOD_VISITED		8 -#define NEW_MOD_USED_ONCE	16 - -int new_sys_init_module(const char *name, const struct new_module *); -int query_module(const char *name, int which, void *buf, size_t bufsize, -		 size_t *ret); - -/* Values for query_module's which.  */ - -#define QM_MODULES	1 -#define QM_DEPS		2 -#define QM_REFS		3 -#define QM_SYMBOLS	4 -#define QM_INFO		5 - -/*======================================================================*/ -/* The system calls unchanged between 2.0 and 2.1.  */ - -unsigned long create_module(const char *, size_t); -int delete_module(const char *); - - -#endif /* module.h */ - -//---------------------------------------------------------------------------- -//--------end of modutils module.h -//---------------------------------------------------------------------------- - - - -//---------------------------------------------------------------------------- -//--------modutils obj.h, lines 253-462 -//---------------------------------------------------------------------------- - -/* Elf object file loading and relocation routines. -   Copyright 1996, 1997 Linux International. - -   Contributed by Richard Henderson <rth@tamu.edu> - -   This file is part of the Linux modutils. - -   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.  */ - - -#ifndef MODUTILS_OBJ_H -#define MODUTILS_OBJ_H 1 - -#ident "$Id$" - -/* The relocatable object is manipulated using elfin types.  */ - -#include <stdio.h> -#include <elf.h> - - -/* Machine-specific elf macros for i386 et al.  */ - -/* the SH changes have only been tested on the SH4 in =little endian= mode */ -/* I'm not sure about big endian, so let's warn: */ - -#if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__) -#error insmod.c may require changes for use on big endian SH4/SH3 -#endif - -/* it may or may not work on the SH1/SH2... So let's error on those -   also */ -#if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__)))) -#error insmod.c may require changes for non-SH3/SH4 use -#endif - -#define ELFCLASSM	ELFCLASS32 -#define ELFDATAM	ELFDATA2LSB - - - -#if defined(__sh__) - -#define MATCH_MACHINE(x) (x == EM_SH) -#define SHT_RELM	SHT_RELA -#define Elf32_RelM	Elf32_Rela - -#else - -/* presumably we can use these for anything but the SH */ -/* this is the previous behavior, but it does result in -   insmod.c being broken on anything except i386 */ - -#define MATCH_MACHINE(x)  (x == EM_386) -#define SHT_RELM	SHT_REL -#define Elf32_RelM	Elf32_Rel - -#endif - -#ifndef ElfW -# if ELFCLASSM == ELFCLASS32 -#  define ElfW(x)  Elf32_ ## x -#  define ELFW(x)  ELF32_ ## x -# else -#  define ElfW(x)  Elf64_ ## x -#  define ELFW(x)  ELF64_ ## x -# endif -#endif - -/* For some reason this is missing from libc5.  */ -#ifndef ELF32_ST_INFO -# define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf)) -#endif - -#ifndef ELF64_ST_INFO -# define ELF64_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf)) -#endif - -struct obj_string_patch; -struct obj_symbol_patch; - -struct obj_section -{ -  ElfW(Shdr) header; -  const char *name; -  char *contents; -  struct obj_section *load_next; -  int idx; -}; - -struct obj_symbol -{ -  struct obj_symbol *next;	/* hash table link */ -  const char *name; -  unsigned long value; -  unsigned long size; -  int secidx;			/* the defining section index/module */ -  int info; -  int ksymidx;			/* for export to the kernel symtab */ -  int referenced;		/* actually used in the link */ -}; - -/* Hardcode the hash table size.  We shouldn't be needing so many -   symbols that we begin to degrade performance, and we get a big win -   by giving the compiler a constant divisor.  */ - -#define HASH_BUCKETS  521 - -struct obj_file -{ -  ElfW(Ehdr) header; -  ElfW(Addr) baseaddr; -  struct obj_section **sections; -  struct obj_section *load_order; -  struct obj_section **load_order_search_start; -  struct obj_string_patch *string_patches; -  struct obj_symbol_patch *symbol_patches; -  int (*symbol_cmp)(const char *, const char *); -  unsigned long (*symbol_hash)(const char *); -  unsigned long local_symtab_size; -  struct obj_symbol **local_symtab; -  struct obj_symbol *symtab[HASH_BUCKETS]; -}; - -enum obj_reloc -{ -  obj_reloc_ok, -  obj_reloc_overflow, -  obj_reloc_dangerous, -  obj_reloc_unhandled -}; - -struct obj_string_patch -{ -  struct obj_string_patch *next; -  int reloc_secidx; -  ElfW(Addr) reloc_offset; -  ElfW(Addr) string_offset; -}; - -struct obj_symbol_patch -{ -  struct obj_symbol_patch *next; -  int reloc_secidx; -  ElfW(Addr) reloc_offset; -  struct obj_symbol *sym; -}; - - -/* Generic object manipulation routines.  */ - -unsigned long obj_elf_hash(const char *); - -unsigned long obj_elf_hash_n(const char *, unsigned long len); - -struct obj_symbol *obj_add_symbol (struct obj_file *f, const char *name, -				   unsigned long symidx, int info, int secidx, -				   ElfW(Addr) value, unsigned long size); - -struct obj_symbol *obj_find_symbol (struct obj_file *f, -					 const char *name); - -ElfW(Addr) obj_symbol_final_value(struct obj_file *f, -				  struct obj_symbol *sym); - -void obj_set_symbol_compare(struct obj_file *f, -			    int (*cmp)(const char *, const char *), -			    unsigned long (*hash)(const char *)); - -struct obj_section *obj_find_section (struct obj_file *f, -					   const char *name); - -void obj_insert_section_load_order (struct obj_file *f, -				    struct obj_section *sec); - -struct obj_section *obj_create_alloced_section (struct obj_file *f, -						const char *name, -						unsigned long align, -						unsigned long size); - -struct obj_section *obj_create_alloced_section_first (struct obj_file *f, -						      const char *name, -						      unsigned long align, -						      unsigned long size); - -void *obj_extend_section (struct obj_section *sec, unsigned long more); - -int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, -		     const char *string); - -int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, -		     struct obj_symbol *sym); - -int obj_check_undefineds(struct obj_file *f); - -void obj_allocate_commons(struct obj_file *f); - -unsigned long obj_load_size (struct obj_file *f); - -int obj_relocate (struct obj_file *f, ElfW(Addr) base); - -struct obj_file *obj_load(FILE *f); - -int obj_create_image (struct obj_file *f, char *image); - -/* Architecture specific manipulation routines.  */ - -struct obj_file *arch_new_file (void); - -struct obj_section *arch_new_section (void); - -struct obj_symbol *arch_new_symbol (void); - -enum obj_reloc arch_apply_relocation (struct obj_file *f, -				      struct obj_section *targsec, -				      struct obj_section *symsec, -				      struct obj_symbol *sym, -				      ElfW(RelM) *rel, ElfW(Addr) value); - -int arch_create_got (struct obj_file *f); - -struct new_module; -int arch_init_module (struct obj_file *f, struct new_module *); - -#endif /* obj.h */ -//---------------------------------------------------------------------------- -//--------end of modutils obj.h -//---------------------------------------------------------------------------- - - - - - -#define _PATH_MODULES	"/lib/modules" -#define STRVERSIONLEN	32 - -#if !defined(BB_FEATURE_INSMOD_NEW_KERNEL) && !defined(BB_FEATURE_INSMOD_OLD_KERNEL) -#error "Must have ether BB_FEATURE_INSMOD_NEW_KERNEL or BB_FEATURE_INSMOD_OLD_KERNEL defined" -#endif - -/*======================================================================*/ - -int flag_force_load = 1; -int flag_autoclean = 0; -int flag_export = 1; - - -/*======================================================================*/ - -/* previously, these were named i386_* but since we could be -   compiling for the sh, I've renamed them to the more general -   arch_* These structures are the same between the x86 and SH,  -   and we can't support anything else right now anyway. In the -   future maybe they should be #if defined'd */ - -struct arch_got_entry { -	int offset; -	unsigned offset_done:1; -	unsigned reloc_done:1; -}; - -struct arch_file { -	struct obj_file root; -	struct obj_section *got; -}; - -struct arch_symbol { -	struct obj_symbol root; -	struct arch_got_entry gotent; -}; - - -struct external_module { -	const char *name; -	ElfW(Addr) addr; -	int used; -	size_t nsyms; -	struct new_module_symbol *syms; -}; - -struct new_module_symbol *ksyms; -size_t nksyms; - -struct external_module *ext_modules; -int n_ext_modules; -int n_ext_modules_used; - - - -/* Some firendly syscalls to cheer everyone's day...  */ -#define __NR_new_sys_init_module  __NR_init_module -_syscall2(int, new_sys_init_module, const char *, name, -		  const struct new_module *, info) -#define __NR_old_sys_init_module  __NR_init_module -_syscall5(int, old_sys_init_module, const char *, name, char *, code, -		  unsigned, codesize, struct old_mod_routines *, routines, -		  struct old_symbol_table *, symtab) -#ifndef BB_RMMOD -_syscall1(int, delete_module, const char *, name) -#else -extern int delete_module(const char *); -#endif - -/* This is kind of troublesome. See, we don't actually support -   the m68k or the arm the same way we support i386 and (now) -   sh. In doing my SH patch, I just assumed that whatever works -   for i386 also works for m68k and arm since currently insmod.c -   does nothing special for them. If this isn't true, the below -   line is rather misleading IMHO, and someone should either -   change it or add more proper architecture-dependent support -   for these boys. - -   -- Bryan Rittmeyer <bryan@ixiacom.com>                    */ - -#if defined(__i386__) || defined(__m68k__) || defined(__arm__) -/* Jump through hoops to fixup error return codes */ -#define __NR__create_module  __NR_create_module -static inline _syscall2(long, _create_module, const char *, name, size_t, -						size) -unsigned long create_module(const char *name, size_t size) -{ -	long ret = _create_module(name, size); - -	if (ret == -1 && errno > 125) { -		ret = -errno; -		errno = 0; -	} -	return ret; -} -#else -_syscall2(unsigned long, create_module, const char *, name, size_t, size) -#endif -static char m_filename[BUFSIZ + 1] = "\0"; -static char m_fullName[BUFSIZ + 1] = "\0"; - -/*======================================================================*/ - - -/*======================================================================*/ - -struct obj_file *arch_new_file(void) -{ -	struct arch_file *f; -	f = xmalloc(sizeof(*f)); -	f->got = NULL; -	return &f->root; -} - -struct obj_section *arch_new_section(void) -{ -	return xmalloc(sizeof(struct obj_section)); -} - -struct obj_symbol *arch_new_symbol(void) -{ -	struct arch_symbol *sym; -	sym = xmalloc(sizeof(*sym)); -	memset(&sym->gotent, 0, sizeof(sym->gotent)); -	return &sym->root; -} - -enum obj_reloc -arch_apply_relocation(struct obj_file *f, -					  struct obj_section *targsec, -					  struct obj_section *symsec, -					  struct obj_symbol *sym, -#if defined(__sh__) -		                          Elf32_Rela * rel, Elf32_Addr v) -#else -					  Elf32_Rel * rel, Elf32_Addr v) -#endif -{ -	struct arch_file *ifile = (struct arch_file *) f; -	struct arch_symbol *isym = (struct arch_symbol *) sym; - -	Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset); -	Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; -	Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0; - -	enum obj_reloc ret = obj_reloc_ok; - -	switch (ELF32_R_TYPE(rel->r_info)) { - -/* even though these constants seem to be the same for -   the i386 and the sh, we "#if define" them for clarity -   and in case that ever changes */ -#if defined(__sh__) -	case R_SH_NONE: -#else -	case R_386_NONE: -#endif -		break; - -#if defined(__sh__) -	case R_SH_DIR32: -#else -	case R_386_32: -#endif -		*loc += v; -		break; - -#if defined(__sh__) -        case R_SH_REL32: -#else -	case R_386_PLT32: -	case R_386_PC32: -#endif -		*loc += v - dot; -		break; - -#if defined(__sh__) -        case R_SH_PLT32: -                *loc = v - dot; -                break; -#endif - - -#if defined(__sh__) -        case R_SH_GLOB_DAT: -        case R_SH_JMP_SLOT: -               	*loc = v; -                break; -#else -	case R_386_GLOB_DAT: -	case R_386_JMP_SLOT: -		*loc = v; -		break; -#endif - -#if defined(__sh__) -        case R_SH_RELATIVE: -	        *loc += f->baseaddr + rel->r_addend; -                break; -#else -        case R_386_RELATIVE: -		*loc += f->baseaddr; -		break; -#endif - -#if defined(__sh__) -        case R_SH_GOTPC: -		assert(got != 0); -		*loc += got - dot + rel->r_addend;; -		break; -#else -	case R_386_GOTPC: -		assert(got != 0); -		*loc += got - dot; -		break; -#endif - -#if defined(__sh__) -	case R_SH_GOT32: - 		assert(isym != NULL); - 		if (!isym->gotent.reloc_done) { - 			isym->gotent.reloc_done = 1; - 			*(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) = - 				v; - 		} -		*loc += isym->gotent.offset + rel->r_addend; - 		break; -#else -	case R_386_GOT32: -		assert(isym != NULL); -		if (!isym->gotent.reloc_done) { -			isym->gotent.reloc_done = 1; -			*(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) = -				v; -		} -		*loc += isym->gotent.offset; -		break; -#endif - -#if defined(__sh__) -	case R_SH_GOTOFF: -#else -	case R_386_GOTOFF: -#endif -		assert(got != 0); -		*loc += v - got; -		break; - -	default: -		ret = obj_reloc_unhandled; -		break; -	} - -	return ret; -} - -int arch_create_got(struct obj_file *f) -{ -	struct arch_file *ifile = (struct arch_file *) f; -	int i, n, offset = 0, gotneeded = 0; - -	n = ifile->root.header.e_shnum; -	for (i = 0; i < n; ++i) { -		struct obj_section *relsec, *symsec, *strsec; -#if defined(__sh__) -		Elf32_Rela *rel, *relend; -#else -		Elf32_Rel *rel, *relend; -#endif -		Elf32_Sym *symtab; -		const char *strtab; - -		relsec = ifile->root.sections[i]; -		if (relsec->header.sh_type != SHT_REL) -			continue; - -		symsec = ifile->root.sections[relsec->header.sh_link]; -		strsec = ifile->root.sections[symsec->header.sh_link]; - - -#if defined(__sh__) -		rel = (Elf32_Rela *) relsec->contents; -		relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela)); -#else -		rel = (Elf32_Rel *) relsec->contents; -		relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); -#endif -		symtab = (Elf32_Sym *) symsec->contents; -		strtab = (const char *) strsec->contents; - -		for (; rel < relend; ++rel) { -			Elf32_Sym *extsym; -			struct arch_symbol *intsym; -			const char *name; - -			switch (ELF32_R_TYPE(rel->r_info)) { -#if defined(__sh__) -			case R_SH_GOTPC: -			case R_SH_GOTOFF: -#else -			case R_386_GOTPC: -			case R_386_GOTOFF: -#endif -				gotneeded = 1; -			default: -				continue; - -#if defined(__sh__) -			case R_SH_GOT32: -#else -			case R_386_GOT32: -#endif -				break; -			} - -			extsym = &symtab[ELF32_R_SYM(rel->r_info)]; -			if (extsym->st_name) -				name = strtab + extsym->st_name; -			else -				name = f->sections[extsym->st_shndx]->name; -			intsym = -				(struct arch_symbol *) obj_find_symbol(&ifile->root, name); - -			if (!intsym->gotent.offset_done) { -				intsym->gotent.offset_done = 1; -				intsym->gotent.offset = offset; -				offset += 4; -			} -		} -	} - -	if (offset > 0 || gotneeded) -		ifile->got = -			obj_create_alloced_section(&ifile->root, ".got", 4, offset); - -	return 1; -} - -int arch_init_module(struct obj_file *f, struct new_module *mod) -{ -	return 1; -} - - -/*======================================================================*/ - -/* Standard ELF hash function.  */ -inline unsigned long obj_elf_hash_n(const char *name, unsigned long n) -{ -	unsigned long h = 0; -	unsigned long g; -	unsigned char ch; - -	while (n > 0) { -		ch = *name++; -		h = (h << 4) + ch; -		if ((g = (h & 0xf0000000)) != 0) { -			h ^= g >> 24; -			h &= ~g; -		} -		n--; -	} -	return h; -} - -unsigned long obj_elf_hash(const char *name) -{ -	return obj_elf_hash_n(name, strlen(name)); -} - -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -/* Get the kernel version in the canonical integer form.  */ - -static int get_kernel_version(char str[STRVERSIONLEN]) -{ -	struct utsname uts_info; -	char *p, *q; -	int a, b, c; - -	if (uname(&uts_info) < 0) -		return -1; -	strncpy(str, uts_info.release, STRVERSIONLEN); -	p = uts_info.release; - -	a = strtoul(p, &p, 10); -	if (*p != '.') -		return -1; -	b = strtoul(p + 1, &p, 10); -	if (*p != '.') -		return -1; -	c = strtoul(p + 1, &q, 10); -	if (p + 1 == q) -		return -1; - -	return a << 16 | b << 8 | c; -} - -/* String comparison for non-co-versioned kernel and module.  */ - -static int ncv_strcmp(const char *a, const char *b) -{ -	size_t alen = strlen(a), blen = strlen(b); - -	if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R') -		return strncmp(a, b, alen); -	else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R') -		return strncmp(a, b, blen); -	else -		return strcmp(a, b); -} - -/* String hashing for non-co-versioned kernel and module.  Here -   we are simply forced to drop the crc from the hash.  */ - -static unsigned long ncv_symbol_hash(const char *str) -{ -	size_t len = strlen(str); -	if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R') -		len -= 10; -	return obj_elf_hash_n(str, len); -} - -void -obj_set_symbol_compare(struct obj_file *f, -					   int (*cmp) (const char *, const char *), -					   unsigned long (*hash) (const char *)) -{ -	if (cmp) -		f->symbol_cmp = cmp; -	if (hash) { -		struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next; -		int i; - -		f->symbol_hash = hash; - -		memcpy(tmptab, f->symtab, sizeof(tmptab)); -		memset(f->symtab, 0, sizeof(f->symtab)); - -		for (i = 0; i < HASH_BUCKETS; ++i) -			for (sym = tmptab[i]; sym; sym = next) { -				unsigned long h = hash(sym->name) % HASH_BUCKETS; -				next = sym->next; -				sym->next = f->symtab[h]; -				f->symtab[h] = sym; -			} -	} -} - -#endif							/* BB_FEATURE_INSMOD_VERSION_CHECKING */ - - -struct obj_symbol *obj_add_symbol(struct obj_file *f, const char *name, -								  unsigned long symidx, int info, -								  int secidx, ElfW(Addr) value, -								  unsigned long size) -{ -	struct obj_symbol *sym; -	unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; -	int n_type = ELFW(ST_TYPE) (info); -	int n_binding = ELFW(ST_BIND) (info); - -	for (sym = f->symtab[hash]; sym; sym = sym->next) -		if (f->symbol_cmp(sym->name, name) == 0) { -			int o_secidx = sym->secidx; -			int o_info = sym->info; -			int o_type = ELFW(ST_TYPE) (o_info); -			int o_binding = ELFW(ST_BIND) (o_info); - -			/* A redefinition!  Is it legal?  */ - -			if (secidx == SHN_UNDEF) -				return sym; -			else if (o_secidx == SHN_UNDEF) -				goto found; -			else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) { -				/* Cope with local and global symbols of the same name -				   in the same object file, as might have been created -				   by ld -r.  The only reason locals are now seen at this -				   level at all is so that we can do semi-sensible things -				   with parameters.  */ - -				struct obj_symbol *nsym, **p; - -				nsym = arch_new_symbol(); -				nsym->next = sym->next; -				nsym->ksymidx = -1; - -				/* Excise the old (local) symbol from the hash chain.  */ -				for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next) -					continue; -				*p = sym = nsym; -				goto found; -			} else if (n_binding == STB_LOCAL) { -				/* Another symbol of the same name has already been defined. -				   Just add this to the local table.  */ -				sym = arch_new_symbol(); -				sym->next = NULL; -				sym->ksymidx = -1; -				f->local_symtab[symidx] = sym; -				goto found; -			} else if (n_binding == STB_WEAK) -				return sym; -			else if (o_binding == STB_WEAK) -				goto found; -			/* Don't unify COMMON symbols with object types the programmer -			   doesn't expect.  */ -			else if (secidx == SHN_COMMON -					 && (o_type == STT_NOTYPE || o_type == STT_OBJECT)) -				return sym; -			else if (o_secidx == SHN_COMMON -					 && (n_type == STT_NOTYPE || n_type == STT_OBJECT)) -				goto found; -			else { -				/* Don't report an error if the symbol is coming from -				   the kernel or some external module.  */ -				if (secidx <= SHN_HIRESERVE) -					errorMsg("%s multiply defined", name); -				return sym; -			} -		} - -	/* Completely new symbol.  */ -	sym = arch_new_symbol(); -	sym->next = f->symtab[hash]; -	f->symtab[hash] = sym; -	sym->ksymidx = -1; - -	if (ELFW(ST_BIND) (info) == STB_LOCAL) -		f->local_symtab[symidx] = sym; - -  found: -	sym->name = name; -	sym->value = value; -	sym->size = size; -	sym->secidx = secidx; -	sym->info = info; - -	return sym; -} - -struct obj_symbol *obj_find_symbol(struct obj_file *f, const char *name) -{ -	struct obj_symbol *sym; -	unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; - -	for (sym = f->symtab[hash]; sym; sym = sym->next) -		if (f->symbol_cmp(sym->name, name) == 0) -			return sym; - -	return NULL; -} - -ElfW(Addr) -	obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym) -{ -	if (sym) { -		if (sym->secidx >= SHN_LORESERVE) -			return sym->value; - -		return sym->value + f->sections[sym->secidx]->header.sh_addr; -	} else { -		/* As a special case, a NULL sym has value zero.  */ -		return 0; -	} -} - -struct obj_section *obj_find_section(struct obj_file *f, const char *name) -{ -	int i, n = f->header.e_shnum; - -	for (i = 0; i < n; ++i) -		if (strcmp(f->sections[i]->name, name) == 0) -			return f->sections[i]; - -	return NULL; -} - -static int obj_load_order_prio(struct obj_section *a) -{ -	unsigned long af, ac; - -	af = a->header.sh_flags; - -	ac = 0; -	if (a->name[0] != '.' || strlen(a->name) != 10 || -		strcmp(a->name + 5, ".init")) -		ac |= 32; -	if (af & SHF_ALLOC) -		ac |= 16; -	if (!(af & SHF_WRITE)) -		ac |= 8; -	if (af & SHF_EXECINSTR) -		ac |= 4; -	if (a->header.sh_type != SHT_NOBITS) -		ac |= 2; - -	return ac; -} - -void -obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec) -{ -	struct obj_section **p; -	int prio = obj_load_order_prio(sec); -	for (p = f->load_order_search_start; *p; p = &(*p)->load_next) -		if (obj_load_order_prio(*p) < prio) -			break; -	sec->load_next = *p; -	*p = sec; -} - -struct obj_section *obj_create_alloced_section(struct obj_file *f, -											   const char *name, -											   unsigned long align, -											   unsigned long size) -{ -	int newidx = f->header.e_shnum++; -	struct obj_section *sec; - -	f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); -	f->sections[newidx] = sec = arch_new_section(); - -	memset(sec, 0, sizeof(*sec)); -	sec->header.sh_type = SHT_PROGBITS; -	sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; -	sec->header.sh_size = size; -	sec->header.sh_addralign = align; -	sec->name = name; -	sec->idx = newidx; -	if (size) -		sec->contents = xmalloc(size); - -	obj_insert_section_load_order(f, sec); - -	return sec; -} - -struct obj_section *obj_create_alloced_section_first(struct obj_file *f, -													 const char *name, -													 unsigned long align, -													 unsigned long size) -{ -	int newidx = f->header.e_shnum++; -	struct obj_section *sec; - -	f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); -	f->sections[newidx] = sec = arch_new_section(); - -	memset(sec, 0, sizeof(*sec)); -	sec->header.sh_type = SHT_PROGBITS; -	sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; -	sec->header.sh_size = size; -	sec->header.sh_addralign = align; -	sec->name = name; -	sec->idx = newidx; -	if (size) -		sec->contents = xmalloc(size); - -	sec->load_next = f->load_order; -	f->load_order = sec; -	if (f->load_order_search_start == &f->load_order) -		f->load_order_search_start = &sec->load_next; - -	return sec; -} - -void *obj_extend_section(struct obj_section *sec, unsigned long more) -{ -	unsigned long oldsize = sec->header.sh_size; -	sec->contents = xrealloc(sec->contents, sec->header.sh_size += more); -	return sec->contents + oldsize; -} - - - -/* Conditionally add the symbols from the given symbol set to the -   new module.  */ - -static int -add_symbols_from( -				 struct obj_file *f, -				 int idx, struct new_module_symbol *syms, size_t nsyms) -{ -	struct new_module_symbol *s; -	size_t i; -	int used = 0; - -	for (i = 0, s = syms; i < nsyms; ++i, ++s) { - -		/* Only add symbols that are already marked external.  If we -		   override locals we may cause problems for argument initialization. -		   We will also create a false dependency on the module.  */ -		struct obj_symbol *sym; - -		sym = obj_find_symbol(f, (char *) s->name); -		if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) { -			sym = obj_add_symbol(f, (char *) s->name, -1, -								 ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE), -								 idx, s->value, 0); -			/* Did our symbol just get installed?  If so, mark the -			   module as "used".  */ -			if (sym->secidx == idx) -				used = 1; -		} -	} - -	return used; -} - -static void add_kernel_symbols(struct obj_file *f) -{ -	struct external_module *m; -	int i, nused = 0; - -	/* Add module symbols first.  */ - -	for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) -		if (m->nsyms -			&& add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, -								m->nsyms)) m->used = 1, ++nused; - -	n_ext_modules_used = nused; - -	/* And finally the symbols from the kernel proper.  */ - -	if (nksyms) -		add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms); -} - -static char *get_modinfo_value(struct obj_file *f, const char *key) -{ -	struct obj_section *sec; -	char *p, *v, *n, *ep; -	size_t klen = strlen(key); - -	sec = obj_find_section(f, ".modinfo"); -	if (sec == NULL) -		return NULL; -	p = sec->contents; -	ep = p + sec->header.sh_size; -	while (p < ep) { -		v = strchr(p, '='); -		n = strchr(p, '\0'); -		if (v) { -			if (p + klen == v && strncmp(p, key, klen) == 0) -				return v + 1; -		} else { -			if (p + klen == n && strcmp(p, key) == 0) -				return n; -		} -		p = n + 1; -	} - -	return NULL; -} - - -/*======================================================================*/ -/* Functions relating to module loading in pre 2.1 kernels.  */ - -static int -old_process_module_arguments(struct obj_file *f, int argc, char **argv) -{ -	while (argc > 0) { -		char *p, *q; -		struct obj_symbol *sym; -		int *loc; - -		p = *argv; -		if ((q = strchr(p, '=')) == NULL) { -			argc--; -			continue; -                } -		*q++ = '\0'; - -		sym = obj_find_symbol(f, p); - -		/* Also check that the parameter was not resolved from the kernel.  */ -		if (sym == NULL || sym->secidx > SHN_HIRESERVE) { -			errorMsg("symbol for parameter %s not found", p); -			return 0; -		} - -		loc = (int *) (f->sections[sym->secidx]->contents + sym->value); - -		/* Do C quoting if we begin with a ".  */ -		if (*q == '"') { -			char *r, *str; - -			str = alloca(strlen(q)); -			for (r = str, q++; *q != '"'; ++q, ++r) { -				if (*q == '\0') { -					errorMsg("improperly terminated string argument for %s", p); -					return 0; -				} else if (*q == '\\') -					switch (*++q) { -					case 'a': -						*r = '\a'; -						break; -					case 'b': -						*r = '\b'; -						break; -					case 'e': -						*r = '\033'; -						break; -					case 'f': -						*r = '\f'; -						break; -					case 'n': -						*r = '\n'; -						break; -					case 'r': -						*r = '\r'; -						break; -					case 't': -						*r = '\t'; -						break; - -					case '0': -					case '1': -					case '2': -					case '3': -					case '4': -					case '5': -					case '6': -					case '7': -						{ -							int c = *q - '0'; -							if (q[1] >= '0' && q[1] <= '7') { -								c = (c * 8) + *++q - '0'; -								if (q[1] >= '0' && q[1] <= '7') -									c = (c * 8) + *++q - '0'; -							} -							*r = c; -						} -						break; - -					default: -						*r = *q; -						break; -				} else -					*r = *q; -			} -			*r = '\0'; -			obj_string_patch(f, sym->secidx, sym->value, str); -		} else if (*q >= '0' && *q <= '9') { -			do -				*loc++ = strtoul(q, &q, 0); -			while (*q++ == ','); -		} else { -			char *contents = f->sections[sym->secidx]->contents; -			char *loc = contents + sym->value; -			char *r;			/* To search for commas */ - -			/* Break the string with comas */ -			while ((r = strchr(q, ',')) != (char *) NULL) { -				*r++ = '\0'; -				obj_string_patch(f, sym->secidx, loc - contents, q); -				loc += sizeof(char *); -				q = r; -			} - -			/* last part */ -			obj_string_patch(f, sym->secidx, loc - contents, q); -		} - -		argc--, argv++; -	} - -	return 1; -} - -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -static int old_is_module_checksummed(struct obj_file *f) -{ -	return obj_find_symbol(f, "Using_Versions") != NULL; -} -/* Get the module's kernel version in the canonical integer form.  */ - -static int -old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) -{ -	struct obj_symbol *sym; -	char *p, *q; -	int a, b, c; - -	sym = obj_find_symbol(f, "kernel_version"); -	if (sym == NULL) -		return -1; - -	p = f->sections[sym->secidx]->contents + sym->value; -	strncpy(str, p, STRVERSIONLEN); - -	a = strtoul(p, &p, 10); -	if (*p != '.') -		return -1; -	b = strtoul(p + 1, &p, 10); -	if (*p != '.') -		return -1; -	c = strtoul(p + 1, &q, 10); -	if (p + 1 == q) -		return -1; - -	return a << 16 | b << 8 | c; -} - -#endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */ - -#ifdef BB_FEATURE_INSMOD_OLD_KERNEL - -/* Fetch all the symbols and divvy them up as appropriate for the modules.  */ - -static int old_get_kernel_symbols(const char *m_name) -{ -	struct old_kernel_sym *ks, *k; -	struct new_module_symbol *s; -	struct external_module *mod; -	int nks, nms, nmod, i; - -	nks = get_kernel_syms(NULL); -	if (nks < 0) { -		errorMsg("get_kernel_syms: %s: %s", m_name, strerror(errno)); -		return 0; -	} - -	ks = k = xmalloc(nks * sizeof(*ks)); - -	if (get_kernel_syms(ks) != nks) { -		logperror("inconsistency with get_kernel_syms -- is someone else " -			   "playing with modules?"); -		free(ks); -		return 0; -	} - -	/* Collect the module information.  */ - -	mod = NULL; -	nmod = -1; - -	while (k->name[0] == '#' && k->name[1]) { -		struct old_kernel_sym *k2; -		struct new_module_symbol *s; - -		/* Find out how many symbols this module has.  */ -		for (k2 = k + 1; k2->name[0] != '#'; ++k2) -			continue; -		nms = k2 - k - 1; - -		mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod)); -		mod[nmod].name = k->name + 1; -		mod[nmod].addr = k->value; -		mod[nmod].used = 0; -		mod[nmod].nsyms = nms; -		mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL); - -		for (i = 0, ++k; i < nms; ++i, ++s, ++k) { -			s->name = (unsigned long) k->name; -			s->value = k->value; -		} - -		k = k2; -	} - -	ext_modules = mod; -	n_ext_modules = nmod + 1; - -	/* Now collect the symbols for the kernel proper.  */ - -	if (k->name[0] == '#') -		++k; - -	nksyms = nms = nks - (k - ks); -	ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL); - -	for (i = 0; i < nms; ++i, ++s, ++k) { -		s->name = (unsigned long) k->name; -		s->value = k->value; -	} - -	return 1; -} - -/* Return the kernel symbol checksum version, or zero if not used.  */ - -static int old_is_kernel_checksummed(void) -{ -	/* Using_Versions is the first symbol.  */ -	if (nksyms > 0 -		&& strcmp((char *) ksyms[0].name, -				  "Using_Versions") == 0) return ksyms[0].value; -	else -		return 0; -} - - -static int old_create_mod_use_count(struct obj_file *f) -{ -	struct obj_section *sec; - -	sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long), -										   sizeof(long)); - -	obj_add_symbol(f, "mod_use_count_", -1, -				   ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, -				   sizeof(long)); - -	return 1; -} - -static int -old_init_module(const char *m_name, struct obj_file *f, -				unsigned long m_size) -{ -	char *image; -	struct old_mod_routines routines; -	struct old_symbol_table *symtab; -	int ret; - -	/* Create the symbol table */ -	{ -		int nsyms = 0, strsize = 0, total; - -		/* Size things first... */ -		if (flag_export) { -			int i; -			for (i = 0; i < HASH_BUCKETS; ++i) { -				struct obj_symbol *sym; -				for (sym = f->symtab[i]; sym; sym = sym->next) -					if (ELFW(ST_BIND) (sym->info) != STB_LOCAL -						&& sym->secidx <= SHN_HIRESERVE)  -					{ -						sym->ksymidx = nsyms++; -						strsize += strlen(sym->name) + 1; -					} -			} -		} - -		total = (sizeof(struct old_symbol_table) -				 + nsyms * sizeof(struct old_module_symbol) -				 + n_ext_modules_used * sizeof(struct old_module_ref) -				 + strsize); -		symtab = xmalloc(total); -		symtab->size = total; -		symtab->n_symbols = nsyms; -		symtab->n_refs = n_ext_modules_used; - -		if (flag_export && nsyms) { -			struct old_module_symbol *ksym; -			char *str; -			int i; - -			ksym = symtab->symbol; -			str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol) -				   + n_ext_modules_used * sizeof(struct old_module_ref)); - -			for (i = 0; i < HASH_BUCKETS; ++i) { -				struct obj_symbol *sym; -				for (sym = f->symtab[i]; sym; sym = sym->next) -					if (sym->ksymidx >= 0) { -						ksym->addr = obj_symbol_final_value(f, sym); -						ksym->name = -							(unsigned long) str - (unsigned long) symtab; - -						str = stpcpy(str, sym->name) + 1; -						ksym++; -					} -			} -		} - -		if (n_ext_modules_used) { -			struct old_module_ref *ref; -			int i; - -			ref = (struct old_module_ref *) -				((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol)); - -			for (i = 0; i < n_ext_modules; ++i) -				if (ext_modules[i].used) -					ref++->module = ext_modules[i].addr; -		} -	} - -	/* Fill in routines.  */ - -	routines.init = -		obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); -	routines.cleanup = -		obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module")); - -	/* Whew!  All of the initialization is complete.  Collect the final -	   module image and give it to the kernel.  */ - -	image = xmalloc(m_size); -	obj_create_image(f, image); - -	/* image holds the complete relocated module, accounting correctly for -	   mod_use_count.  However the old module kernel support assume that -	   it is receiving something which does not contain mod_use_count.  */ -	ret = old_sys_init_module(m_name, image + sizeof(long), -							  m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN -										: 0), &routines, symtab); -	if (ret) -		errorMsg("init_module: %s: %s", m_name, strerror(errno)); - -	free(image); -	free(symtab); - -	return ret == 0; -} - -#else - -#define old_create_mod_use_count(x) TRUE -#define old_init_module(x, y, z) TRUE - -#endif							/* BB_FEATURE_INSMOD_OLD_KERNEL */ - - - -/*======================================================================*/ -/* Functions relating to module loading after 2.1.18.  */ - -static int -new_process_module_arguments(struct obj_file *f, int argc, char **argv) -{ -	while (argc > 0) { -		char *p, *q, *key; -		struct obj_symbol *sym; -		char *contents, *loc; -		int min, max, n; - -		p = *argv; -		if ((q = strchr(p, '=')) == NULL) { -			argc--; -			continue; -                } - -		key = alloca(q - p + 6); -		memcpy(key, "parm_", 5); -		memcpy(key + 5, p, q - p); -		key[q - p + 5] = 0; - -		p = get_modinfo_value(f, key); -		key += 5; -		if (p == NULL) { -			errorMsg("invalid parameter %s", key); -			return 0; -		} - -		sym = obj_find_symbol(f, key); - -		/* Also check that the parameter was not resolved from the kernel.  */ -		if (sym == NULL || sym->secidx > SHN_HIRESERVE) { -			errorMsg("symbol for parameter %s not found", key); -			return 0; -		} - -		if (isdigit(*p)) { -			min = strtoul(p, &p, 10); -			if (*p == '-') -				max = strtoul(p + 1, &p, 10); -			else -				max = min; -		} else -			min = max = 1; - -		contents = f->sections[sym->secidx]->contents; -		loc = contents + sym->value; -		n = (*++q != '\0'); - -		while (1) { -			if ((*p == 's') || (*p == 'c')) { -				char *str; - -				/* Do C quoting if we begin with a ", else slurp the lot.  */ -				if (*q == '"') { -					char *r; - -					str = alloca(strlen(q)); -					for (r = str, q++; *q != '"'; ++q, ++r) { -						if (*q == '\0') { -							errorMsg("improperly terminated string argument for %s", -									key); -							return 0; -						} else if (*q == '\\') -							switch (*++q) { -							case 'a': -								*r = '\a'; -								break; -							case 'b': -								*r = '\b'; -								break; -							case 'e': -								*r = '\033'; -								break; -							case 'f': -								*r = '\f'; -								break; -							case 'n': -								*r = '\n'; -								break; -							case 'r': -								*r = '\r'; -								break; -							case 't': -								*r = '\t'; -								break; - -							case '0': -							case '1': -							case '2': -							case '3': -							case '4': -							case '5': -							case '6': -							case '7': -								{ -									int c = *q - '0'; -									if (q[1] >= '0' && q[1] <= '7') { -										c = (c * 8) + *++q - '0'; -										if (q[1] >= '0' && q[1] <= '7') -											c = (c * 8) + *++q - '0'; -									} -									*r = c; -								} -								break; - -							default: -								*r = *q; -								break; -						} else -							*r = *q; -					} -					*r = '\0'; -					++q; -				} else { -					char *r; - -					/* In this case, the string is not quoted. We will break -					   it using the coma (like for ints). If the user wants to -					   include comas in a string, he just has to quote it */ - -					/* Search the next coma */ -					r = strchr(q, ','); - -					/* Found ? */ -					if (r != (char *) NULL) { -						/* Recopy the current field */ -						str = alloca(r - q + 1); -						memcpy(str, q, r - q); - -						/* I don't know if it is usefull, as the previous case -						   doesn't null terminate the string ??? */ -						str[r - q] = '\0'; - -						/* Keep next fields */ -						q = r; -					} else { -						/* last string */ -						str = q; -						q = ""; -					} -				} - -				if (*p == 's') { -					/* Normal string */ -					obj_string_patch(f, sym->secidx, loc - contents, str); -					loc += tgt_sizeof_char_p; -				} else { -					/* Array of chars (in fact, matrix !) */ -					unsigned long charssize;	/* size of each member */ - -					/* Get the size of each member */ -					/* Probably we should do that outside the loop ? */ -					if (!isdigit(*(p + 1))) { -						errorMsg("parameter type 'c' for %s must be followed by" -								" the maximum size", key); -						return 0; -					} -					charssize = strtoul(p + 1, (char **) NULL, 10); - -					/* Check length */ -					if (strlen(str) >= charssize) { -						errorMsg("string too long for %s (max %ld)", key, -								charssize - 1); -						return 0; -					} - -					/* Copy to location */ -					strcpy((char *) loc, str); -					loc += charssize; -				} -			} else { -				long v = strtoul(q, &q, 0); -				switch (*p) { -				case 'b': -					*loc++ = v; -					break; -				case 'h': -					*(short *) loc = v; -					loc += tgt_sizeof_short; -					break; -				case 'i': -					*(int *) loc = v; -					loc += tgt_sizeof_int; -					break; -				case 'l': -					*(long *) loc = v; -					loc += tgt_sizeof_long; -					break; - -				default: -					errorMsg("unknown parameter type '%c' for %s", *p, key); -					return 0; -				} -			} - -		  retry_end_of_value: -			switch (*q) { -			case '\0': -				goto end_of_arg; - -			case ' ': -			case '\t': -			case '\n': -			case '\r': -				++q; -				goto retry_end_of_value; - -			case ',': -				if (++n > max) { -					errorMsg("too many values for %s (max %d)", key, max); -					return 0; -				} -				++q; -				break; - -			default: -				errorMsg("invalid argument syntax for %s", key); -				return 0; -			} -		} - -	  end_of_arg: -		if (n < min) { -			errorMsg("too few values for %s (min %d)", key, min); -			return 0; -		} - -		argc--, argv++; -	} - -	return 1; -} - -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -static int new_is_module_checksummed(struct obj_file *f) -{ -	const char *p = get_modinfo_value(f, "using_checksums"); -	if (p) -		return atoi(p); -	else -		return 0; -} - -/* Get the module's kernel version in the canonical integer form.  */ - -static int -new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) -{ -	char *p, *q; -	int a, b, c; - -	p = get_modinfo_value(f, "kernel_version"); -	if (p == NULL) -		return -1; -	strncpy(str, p, STRVERSIONLEN); - -	a = strtoul(p, &p, 10); -	if (*p != '.') -		return -1; -	b = strtoul(p + 1, &p, 10); -	if (*p != '.') -		return -1; -	c = strtoul(p + 1, &q, 10); -	if (p + 1 == q) -		return -1; - -	return a << 16 | b << 8 | c; -} - -#endif   /* BB_FEATURE_INSMOD_VERSION_CHECKING */ - - -#ifdef BB_FEATURE_INSMOD_NEW_KERNEL - -/* Fetch the loaded modules, and all currently exported symbols.  */ - -static int new_get_kernel_symbols(void) -{ -	char *module_names, *mn; -	struct external_module *modules, *m; -	struct new_module_symbol *syms, *s; -	size_t ret, bufsize, nmod, nsyms, i, j; - -	/* Collect the loaded modules.  */ - -	module_names = xmalloc(bufsize = 256); -  retry_modules_load: -	if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { -		if (errno == ENOSPC) { -			module_names = xrealloc(module_names, bufsize = ret); -			goto retry_modules_load; -		} -		errorMsg("QM_MODULES: %s", strerror(errno)); -		return 0; -	} - -	n_ext_modules = nmod = ret; -	ext_modules = modules = xmalloc(nmod * sizeof(*modules)); -	memset(modules, 0, nmod * sizeof(*modules)); - -	/* Collect the modules' symbols.  */ - -	for (i = 0, mn = module_names, m = modules; -		 i < nmod; ++i, ++m, mn += strlen(mn) + 1) { -		struct new_module_info info; - -		if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) { -			if (errno == ENOENT) { -				/* The module was removed out from underneath us.  */ -				continue; -			} -			errorMsg("query_module: QM_INFO: %s: %s", mn, strerror(errno)); -			return 0; -		} - -		syms = xmalloc(bufsize = 1024); -	  retry_mod_sym_load: -		if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { -			switch (errno) { -			case ENOSPC: -				syms = xrealloc(syms, bufsize = ret); -				goto retry_mod_sym_load; -			case ENOENT: -				/* The module was removed out from underneath us.  */ -				continue; -			default: -				errorMsg("query_module: QM_SYMBOLS: %s: %s", mn, strerror(errno)); -				return 0; -			} -		} -		nsyms = ret; - -		m->name = mn; -		m->addr = info.addr; -		m->nsyms = nsyms; -		m->syms = syms; - -		for (j = 0, s = syms; j < nsyms; ++j, ++s) { -			s->name += (unsigned long) syms; -		} -	} - -	/* Collect the kernel's symbols.  */ - -	syms = xmalloc(bufsize = 16 * 1024); -  retry_kern_sym_load: -	if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { -		if (errno == ENOSPC) { -			syms = xrealloc(syms, bufsize = ret); -			goto retry_kern_sym_load; -		} -		errorMsg("kernel: QM_SYMBOLS: %s", strerror(errno)); -		return 0; -	} -	nksyms = nsyms = ret; -	ksyms = syms; - -	for (j = 0, s = syms; j < nsyms; ++j, ++s) { -		s->name += (unsigned long) syms; -	} -	return 1; -} - - -/* Return the kernel symbol checksum version, or zero if not used.  */ - -static int new_is_kernel_checksummed(void) -{ -	struct new_module_symbol *s; -	size_t i; - -	/* Using_Versions is not the first symbol, but it should be in there.  */ - -	for (i = 0, s = ksyms; i < nksyms; ++i, ++s) -		if (strcmp((char *) s->name, "Using_Versions") == 0) -			return s->value; - -	return 0; -} - - -static int new_create_this_module(struct obj_file *f, const char *m_name) -{ -	struct obj_section *sec; - -	sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, -										   sizeof(struct new_module)); -	memset(sec->contents, 0, sizeof(struct new_module)); - -	obj_add_symbol(f, "__this_module", -1, -				   ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, -				   sizeof(struct new_module)); - -	obj_string_patch(f, sec->idx, offsetof(struct new_module, name), -					 m_name); - -	return 1; -} - - -static int new_create_module_ksymtab(struct obj_file *f) -{ -	struct obj_section *sec; -	int i; - -	/* We must always add the module references.  */ - -	if (n_ext_modules_used) { -		struct new_module_ref *dep; -		struct obj_symbol *tm; - -		sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p, -										 (sizeof(struct new_module_ref) -										  * n_ext_modules_used)); -		if (!sec) -			return 0; - -		tm = obj_find_symbol(f, "__this_module"); -		dep = (struct new_module_ref *) sec->contents; -		for (i = 0; i < n_ext_modules; ++i) -			if (ext_modules[i].used) { -				dep->dep = ext_modules[i].addr; -				obj_symbol_patch(f, sec->idx, -								 (char *) &dep->ref - sec->contents, tm); -				dep->next_ref = 0; -				++dep; -			} -	} - -	if (flag_export && !obj_find_section(f, "__ksymtab")) { -		size_t nsyms; -		int *loaded; - -		sec = -			obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, -									   0); - -		/* We don't want to export symbols residing in sections that -		   aren't loaded.  There are a number of these created so that -		   we make sure certain module options don't appear twice.  */ - -		loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); -		while (--i >= 0) -			loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; - -		for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { -			struct obj_symbol *sym; -			for (sym = f->symtab[i]; sym; sym = sym->next) -				if (ELFW(ST_BIND) (sym->info) != STB_LOCAL -					&& sym->secidx <= SHN_HIRESERVE -					&& (sym->secidx >= SHN_LORESERVE -						|| loaded[sym->secidx])) { -					ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; - -					obj_symbol_patch(f, sec->idx, ofs, sym); -					obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, -									 sym->name); - -					nsyms++; -				} -		} - -		obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); -	} - -	return 1; -} - - -static int -new_init_module(const char *m_name, struct obj_file *f, -				unsigned long m_size) -{ -	struct new_module *module; -	struct obj_section *sec; -	void *image; -	int ret; -	tgt_long m_addr; - -	sec = obj_find_section(f, ".this"); -	module = (struct new_module *) sec->contents; -	m_addr = sec->header.sh_addr; - -	module->size_of_struct = sizeof(*module); -	module->size = m_size; -	module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0; - -	sec = obj_find_section(f, "__ksymtab"); -	if (sec && sec->header.sh_size) { -		module->syms = sec->header.sh_addr; -		module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p); -	} - -	if (n_ext_modules_used) { -		sec = obj_find_section(f, ".kmodtab"); -		module->deps = sec->header.sh_addr; -		module->ndeps = n_ext_modules_used; -	} - -	module->init = -		obj_symbol_final_value(f, obj_find_symbol(f, "init_module")); -	module->cleanup = -		obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module")); - -	sec = obj_find_section(f, "__ex_table"); -	if (sec) { -		module->ex_table_start = sec->header.sh_addr; -		module->ex_table_end = sec->header.sh_addr + sec->header.sh_size; -	} - -	sec = obj_find_section(f, ".text.init"); -	if (sec) { -		module->runsize = sec->header.sh_addr - m_addr; -	} -	sec = obj_find_section(f, ".data.init"); -	if (sec) { -		if (!module->runsize || -			module->runsize > sec->header.sh_addr - m_addr) -				module->runsize = sec->header.sh_addr - m_addr; -	} - -	if (!arch_init_module(f, module)) -		return 0; - -	/* Whew!  All of the initialization is complete.  Collect the final -	   module image and give it to the kernel.  */ - -	image = xmalloc(m_size); -	obj_create_image(f, image); - -	ret = new_sys_init_module(m_name, (struct new_module *) image); -	if (ret) -		errorMsg("init_module: %s: %s", m_name, strerror(errno)); - -	free(image); - -	return ret == 0; -} - -#else - -#define new_init_module(x, y, z) TRUE -#define new_create_this_module(x, y) 0 -#define new_create_module_ksymtab(x) - -#endif							/* BB_FEATURE_INSMOD_OLD_KERNEL */ - - -/*======================================================================*/ - -int -obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, -				 const char *string) -{ -	struct obj_string_patch *p; -	struct obj_section *strsec; -	size_t len = strlen(string) + 1; -	char *loc; - -	p = xmalloc(sizeof(*p)); -	p->next = f->string_patches; -	p->reloc_secidx = secidx; -	p->reloc_offset = offset; -	f->string_patches = p; - -	strsec = obj_find_section(f, ".kstrtab"); -	if (strsec == NULL) { -		strsec = obj_create_alloced_section(f, ".kstrtab", 1, len); -		p->string_offset = 0; -		loc = strsec->contents; -	} else { -		p->string_offset = strsec->header.sh_size; -		loc = obj_extend_section(strsec, len); -	} -	memcpy(loc, string, len); - -	return 1; -} - -int -obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, -				 struct obj_symbol *sym) -{ -	struct obj_symbol_patch *p; - -	p = xmalloc(sizeof(*p)); -	p->next = f->symbol_patches; -	p->reloc_secidx = secidx; -	p->reloc_offset = offset; -	p->sym = sym; -	f->symbol_patches = p; - -	return 1; -} - -int obj_check_undefineds(struct obj_file *f) -{ -	unsigned long i; -	int ret = 1; - -	for (i = 0; i < HASH_BUCKETS; ++i) { -		struct obj_symbol *sym; -		for (sym = f->symtab[i]; sym; sym = sym->next) -			if (sym->secidx == SHN_UNDEF) { -				if (ELFW(ST_BIND) (sym->info) == STB_WEAK) { -					sym->secidx = SHN_ABS; -					sym->value = 0; -				} else { -					errorMsg("unresolved symbol %s", sym->name); -					ret = 0; -				} -			} -	} - -	return ret; -} - -void obj_allocate_commons(struct obj_file *f) -{ -	struct common_entry { -		struct common_entry *next; -		struct obj_symbol *sym; -	} *common_head = NULL; - -	unsigned long i; - -	for (i = 0; i < HASH_BUCKETS; ++i) { -		struct obj_symbol *sym; -		for (sym = f->symtab[i]; sym; sym = sym->next) -			if (sym->secidx == SHN_COMMON) { -				/* Collect all COMMON symbols and sort them by size so as to -				   minimize space wasted by alignment requirements.  */ -				{ -					struct common_entry **p, *n; -					for (p = &common_head; *p; p = &(*p)->next) -						if (sym->size <= (*p)->sym->size) -							break; - -					n = alloca(sizeof(*n)); -					n->next = *p; -					n->sym = sym; -					*p = n; -				} -			} -	} - -	for (i = 1; i < f->local_symtab_size; ++i) { -		struct obj_symbol *sym = f->local_symtab[i]; -		if (sym && sym->secidx == SHN_COMMON) { -			struct common_entry **p, *n; -			for (p = &common_head; *p; p = &(*p)->next) -				if (sym == (*p)->sym) -					break; -				else if (sym->size < (*p)->sym->size) { -					n = alloca(sizeof(*n)); -					n->next = *p; -					n->sym = sym; -					*p = n; -					break; -				} -		} -	} - -	if (common_head) { -		/* Find the bss section.  */ -		for (i = 0; i < f->header.e_shnum; ++i) -			if (f->sections[i]->header.sh_type == SHT_NOBITS) -				break; - -		/* If for some reason there hadn't been one, create one.  */ -		if (i == f->header.e_shnum) { -			struct obj_section *sec; - -			f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec)); -			f->sections[i] = sec = arch_new_section(); -			f->header.e_shnum = i + 1; - -			memset(sec, 0, sizeof(*sec)); -			sec->header.sh_type = SHT_PROGBITS; -			sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; -			sec->name = ".bss"; -			sec->idx = i; -		} - -		/* Allocate the COMMONS.  */ -		{ -			ElfW(Addr) bss_size = f->sections[i]->header.sh_size; -			ElfW(Addr) max_align = f->sections[i]->header.sh_addralign; -			struct common_entry *c; - -			for (c = common_head; c; c = c->next) { -				ElfW(Addr) align = c->sym->value; - -				if (align > max_align) -					max_align = align; -				if (bss_size & (align - 1)) -					bss_size = (bss_size | (align - 1)) + 1; - -				c->sym->secidx = i; -				c->sym->value = bss_size; - -				bss_size += c->sym->size; -			} - -			f->sections[i]->header.sh_size = bss_size; -			f->sections[i]->header.sh_addralign = max_align; -		} -	} - -	/* For the sake of patch relocation and parameter initialization, -	   allocate zeroed data for NOBITS sections now.  Note that after -	   this we cannot assume NOBITS are really empty.  */ -	for (i = 0; i < f->header.e_shnum; ++i) { -		struct obj_section *s = f->sections[i]; -		if (s->header.sh_type == SHT_NOBITS) { -			s->contents = memset(xmalloc(s->header.sh_size), -								 0, s->header.sh_size); -			s->header.sh_type = SHT_PROGBITS; -		} -	} -} - -unsigned long obj_load_size(struct obj_file *f) -{ -	unsigned long dot = 0; -	struct obj_section *sec; - -	/* Finalize the positions of the sections relative to one another.  */ - -	for (sec = f->load_order; sec; sec = sec->load_next) { -		ElfW(Addr) align; - -		align = sec->header.sh_addralign; -		if (align && (dot & (align - 1))) -			dot = (dot | (align - 1)) + 1; - -		sec->header.sh_addr = dot; -		dot += sec->header.sh_size; -	} - -	return dot; -} - -int obj_relocate(struct obj_file *f, ElfW(Addr) base) -{ -	int i, n = f->header.e_shnum; -	int ret = 1; - -	/* Finalize the addresses of the sections.  */ - -	f->baseaddr = base; -	for (i = 0; i < n; ++i) -		f->sections[i]->header.sh_addr += base; - -	/* And iterate over all of the relocations.  */ - -	for (i = 0; i < n; ++i) { -		struct obj_section *relsec, *symsec, *targsec, *strsec; -		ElfW(RelM) * rel, *relend; -		ElfW(Sym) * symtab; -		const char *strtab; - -		relsec = f->sections[i]; -		if (relsec->header.sh_type != SHT_RELM) -			continue; - -		symsec = f->sections[relsec->header.sh_link]; -		targsec = f->sections[relsec->header.sh_info]; -		strsec = f->sections[symsec->header.sh_link]; - -		rel = (ElfW(RelM) *) relsec->contents; -		relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM))); -		symtab = (ElfW(Sym) *) symsec->contents; -		strtab = (const char *) strsec->contents; - -		for (; rel < relend; ++rel) { -			ElfW(Addr) value = 0; -			struct obj_symbol *intsym = NULL; -			unsigned long symndx; -			ElfW(Sym) * extsym = 0; -			const char *errmsg; - -			/* Attempt to find a value to use for this relocation.  */ - -			symndx = ELFW(R_SYM) (rel->r_info); -			if (symndx) { -				/* Note we've already checked for undefined symbols.  */ - -				extsym = &symtab[symndx]; -				if (ELFW(ST_BIND) (extsym->st_info) == STB_LOCAL) { -					/* Local symbols we look up in the local table to be sure -					   we get the one that is really intended.  */ -					intsym = f->local_symtab[symndx]; -				} else { -					/* Others we look up in the hash table.  */ -					const char *name; -					if (extsym->st_name) -						name = strtab + extsym->st_name; -					else -						name = f->sections[extsym->st_shndx]->name; -					intsym = obj_find_symbol(f, name); -				} - -				value = obj_symbol_final_value(f, intsym); -				intsym->referenced = 1; -			} -#if SHT_RELM == SHT_RELA -#if defined(__alpha__) && defined(AXP_BROKEN_GAS) -			/* Work around a nasty GAS bug, that is fixed as of 2.7.0.9.  */ -			if (!extsym || !extsym->st_name || -				ELFW(ST_BIND) (extsym->st_info) != STB_LOCAL) -#endif -				value += rel->r_addend; -#endif - -			/* Do it! */ -			switch (arch_apply_relocation -					(f, targsec, symsec, intsym, rel, value)) { -			case obj_reloc_ok: -				break; - -			case obj_reloc_overflow: -				errmsg = "Relocation overflow"; -				goto bad_reloc; -			case obj_reloc_dangerous: -				errmsg = "Dangerous relocation"; -				goto bad_reloc; -			case obj_reloc_unhandled: -				errmsg = "Unhandled relocation"; -			  bad_reloc: -				if (extsym) { -					errorMsg("%s of type %ld for %s", errmsg, -							(long) ELFW(R_TYPE) (rel->r_info), -							strtab + extsym->st_name); -				} else { -					errorMsg("%s of type %ld", errmsg, -							(long) ELFW(R_TYPE) (rel->r_info)); -				} -				ret = 0; -				break; -			} -		} -	} - -	/* Finally, take care of the patches.  */ - -	if (f->string_patches) { -		struct obj_string_patch *p; -		struct obj_section *strsec; -		ElfW(Addr) strsec_base; -		strsec = obj_find_section(f, ".kstrtab"); -		strsec_base = strsec->header.sh_addr; - -		for (p = f->string_patches; p; p = p->next) { -			struct obj_section *targsec = f->sections[p->reloc_secidx]; -			*(ElfW(Addr) *) (targsec->contents + p->reloc_offset) -				= strsec_base + p->string_offset; -		} -	} - -	if (f->symbol_patches) { -		struct obj_symbol_patch *p; - -		for (p = f->symbol_patches; p; p = p->next) { -			struct obj_section *targsec = f->sections[p->reloc_secidx]; -			*(ElfW(Addr) *) (targsec->contents + p->reloc_offset) -				= obj_symbol_final_value(f, p->sym); -		} -	} - -	return ret; -} - -int obj_create_image(struct obj_file *f, char *image) -{ -	struct obj_section *sec; -	ElfW(Addr) base = f->baseaddr; - -	for (sec = f->load_order; sec; sec = sec->load_next) { -		char *secimg; - -		if (sec->header.sh_size == 0) -			continue; - -		secimg = image + (sec->header.sh_addr - base); - -		/* Note that we allocated data for NOBITS sections earlier.  */ -		memcpy(secimg, sec->contents, sec->header.sh_size); -	} - -	return 1; -} - -/*======================================================================*/ - -struct obj_file *obj_load(FILE * fp) -{ -	struct obj_file *f; -	ElfW(Shdr) * section_headers; -	int shnum, i; -	char *shstrtab; - -	/* Read the file header.  */ - -	f = arch_new_file(); -	memset(f, 0, sizeof(*f)); -	f->symbol_cmp = strcmp; -	f->symbol_hash = obj_elf_hash; -	f->load_order_search_start = &f->load_order; - -	fseek(fp, 0, SEEK_SET); -	if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { -		errorMsg("error reading ELF header: %s", strerror(errno)); -		return NULL; -	} - -	if (f->header.e_ident[EI_MAG0] != ELFMAG0 -		|| f->header.e_ident[EI_MAG1] != ELFMAG1 -		|| f->header.e_ident[EI_MAG2] != ELFMAG2 -		|| f->header.e_ident[EI_MAG3] != ELFMAG3) { -		errorMsg("not an ELF file"); -		return NULL; -	} -	if (f->header.e_ident[EI_CLASS] != ELFCLASSM -		|| f->header.e_ident[EI_DATA] != ELFDATAM -		|| f->header.e_ident[EI_VERSION] != EV_CURRENT -		|| !MATCH_MACHINE(f->header.e_machine)) { -		errorMsg("ELF file not for this architecture"); -		return NULL; -	} -	if (f->header.e_type != ET_REL) { -		errorMsg("ELF file not a relocatable object"); -		return NULL; -	} - -	/* Read the section headers.  */ - -	if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { -		errorMsg("section header size mismatch: %lu != %lu", -				(unsigned long) f->header.e_shentsize, -				(unsigned long) sizeof(ElfW(Shdr))); -		return NULL; -	} - -	shnum = f->header.e_shnum; -	f->sections = xmalloc(sizeof(struct obj_section *) * shnum); -	memset(f->sections, 0, sizeof(struct obj_section *) * shnum); - -	section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); -	fseek(fp, f->header.e_shoff, SEEK_SET); -	if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { -		errorMsg("error reading ELF section headers: %s", strerror(errno)); -		return NULL; -	} - -	/* Read the section data.  */ - -	for (i = 0; i < shnum; ++i) { -		struct obj_section *sec; - -		f->sections[i] = sec = arch_new_section(); -		memset(sec, 0, sizeof(*sec)); - -		sec->header = section_headers[i]; -		sec->idx = i; - -		switch (sec->header.sh_type) { -		case SHT_NULL: -		case SHT_NOTE: -		case SHT_NOBITS: -			/* ignore */ -			break; - -		case SHT_PROGBITS: -		case SHT_SYMTAB: -		case SHT_STRTAB: -		case SHT_RELM: -			if (sec->header.sh_size > 0) { -				sec->contents = xmalloc(sec->header.sh_size); -				fseek(fp, sec->header.sh_offset, SEEK_SET); -				if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { -					errorMsg("error reading ELF section data: %s", strerror(errno)); -					return NULL; -				} -			} else { -				sec->contents = NULL; -			} -			break; - -#if SHT_RELM == SHT_REL -		case SHT_RELA: -			errorMsg("RELA relocations not supported on this architecture"); -			return NULL; -#else -		case SHT_REL: -			errorMsg("REL relocations not supported on this architecture"); -			return NULL; -#endif - -		default: -			if (sec->header.sh_type >= SHT_LOPROC) { -				/* Assume processor specific section types are debug -				   info and can safely be ignored.  If this is ever not -				   the case (Hello MIPS?), don't put ifdefs here but -				   create an arch_load_proc_section().  */ -				break; -			} - -			errorMsg("can't handle sections of type %ld", -					(long) sec->header.sh_type); -			return NULL; -		} -	} - -	/* Do what sort of interpretation as needed by each section.  */ - -	shstrtab = f->sections[f->header.e_shstrndx]->contents; - -	for (i = 0; i < shnum; ++i) { -		struct obj_section *sec = f->sections[i]; -		sec->name = shstrtab + sec->header.sh_name; -	} - -	for (i = 0; i < shnum; ++i) { -		struct obj_section *sec = f->sections[i]; - -		if (sec->header.sh_flags & SHF_ALLOC) -			obj_insert_section_load_order(f, sec); - -		switch (sec->header.sh_type) { -		case SHT_SYMTAB: -			{ -				unsigned long nsym, j; -				char *strtab; -				ElfW(Sym) * sym; - -				if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { -					errorMsg("symbol size mismatch: %lu != %lu", -							(unsigned long) sec->header.sh_entsize, -							(unsigned long) sizeof(ElfW(Sym))); -					return NULL; -				} - -				nsym = sec->header.sh_size / sizeof(ElfW(Sym)); -				strtab = f->sections[sec->header.sh_link]->contents; -				sym = (ElfW(Sym) *) sec->contents; - -				/* Allocate space for a table of local symbols.  */ -				j = f->local_symtab_size = sec->header.sh_info; -				f->local_symtab = xmalloc(j *= -										  sizeof(struct obj_symbol *)); -				memset(f->local_symtab, 0, j); - -				/* Insert all symbols into the hash table.  */ -				for (j = 1, ++sym; j < nsym; ++j, ++sym) { -					const char *name; -					if (sym->st_name) -						name = strtab + sym->st_name; -		else -						name = f->sections[sym->st_shndx]->name; - -					obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, -								   sym->st_value, sym->st_size); -		} -	} -			break; - -		case SHT_RELM: -			if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { -				errorMsg("relocation entry size mismatch: %lu != %lu", -						(unsigned long) sec->header.sh_entsize, -						(unsigned long) sizeof(ElfW(RelM))); -				return NULL; -			} -			break; -		} -	} - -	return f; -} - -static void hide_special_symbols(struct obj_file *f) -{ -	static const char *const specials[] = { -		"cleanup_module", -		"init_module", -		"kernel_version", -		NULL -	}; - -	struct obj_symbol *sym; -	const char *const *p; - -	for (p = specials; *p; ++p) -		if ((sym = obj_find_symbol(f, *p)) != NULL) -			sym->info = -				ELFW(ST_INFO) (STB_LOCAL, ELFW(ST_TYPE) (sym->info)); -} - - -void my_usage(void) -{ -	printf("Usage."); -	exit(0); -} - -extern int insmod_main( int argc, char **argv) -{ -	int k_crcs; -	int k_new_syscalls; -	int len; -	char *tmp; -	unsigned long m_size; -	ElfW(Addr) m_addr; -	FILE *fp; -	struct obj_file *f; -	char m_name[BUFSIZ + 1] = "\0"; -	int exit_status = FALSE; -	int m_has_modinfo; -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -	int k_version; -	char k_strversion[STRVERSIONLEN]; -	char m_strversion[STRVERSIONLEN]; -	int m_version; -	int m_crcs; -#endif - - -	if (argc <= 1) -		my_usage(); - -	argv++; argc--; - -	/* Grab the module name */ -	if ((tmp = strrchr(*argv, '/')) != NULL) { -		tmp++; -	} else { -		tmp = *argv; -	} -	len = strlen(tmp); - -	if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') -		len -= 2; -	memcpy(m_name, tmp, len); -	strcpy(m_fullName, m_name); -	strcat(m_fullName, ".o"); - -	/* Get a filedesc for the module */ -	if ((fp = fopen(*argv, "r")) == NULL) { -		errorMsg("Module %s not found", *argv); -		return -1; -	} else -		memcpy(m_filename, *argv, strlen(*argv)); - - -	if ((f = obj_load(fp)) == NULL) { -		logperror("Could not load the module"); -		goto out; -	} - -	if (get_modinfo_value(f, "kernel_version") == NULL) -		m_has_modinfo = 0; -	else -		m_has_modinfo = 1; - -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -	/* Version correspondence?  */ - -	k_version = get_kernel_version(k_strversion); -	if (m_has_modinfo) { -		m_version = new_get_module_version(f, m_strversion); -	} else { -		m_version = old_get_module_version(f, m_strversion); -		if (m_version == -1) { -			errorMsg("couldn't find the kernel version the module was " -					"compiled for"); -			goto out; -		} -	} - -	if (strncmp(k_strversion, m_strversion, STRVERSIONLEN) != 0) { -		if (flag_force_load) { -			errorMsg("Warning: kernel-module version mismatch\n" -					"\t%s was compiled for kernel version %s\n" -					"\twhile this kernel is version %s", -					m_filename, m_strversion, k_strversion); -		} else { -			errorMsg("kernel-module version mismatch\n" -					"\t%s was compiled for kernel version %s\n" -					"\twhile this kernel is version %s.", -					m_filename, m_strversion, k_strversion); -			goto out; -		} -	} -	k_crcs = 0; -#endif							/* BB_FEATURE_INSMOD_VERSION_CHECKING */ - -	k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL); - -	if (k_new_syscalls) { -#ifdef BB_FEATURE_INSMOD_NEW_KERNEL -		if (!new_get_kernel_symbols()) -			goto out; -		k_crcs = new_is_kernel_checksummed(); -#else -		errorMsg("Not configured to support new kernels"); -		goto out; -#endif -	} else { -#ifdef BB_FEATURE_INSMOD_OLD_KERNEL -		if (!old_get_kernel_symbols(m_name)) -			goto out; -		k_crcs = old_is_kernel_checksummed(); -#else -		errorMsg("Not configured to support old kernels"); -		goto out; -#endif -	} - -#ifdef BB_FEATURE_INSMOD_VERSION_CHECKING -	if (m_has_modinfo) -		m_crcs = new_is_module_checksummed(f); -	else -		m_crcs = old_is_module_checksummed(f); - -	if (m_crcs != k_crcs) -		obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); -#endif							/* BB_FEATURE_INSMOD_VERSION_CHECKING */ - -	/* Let the module know about the kernel symbols.  */ -	add_kernel_symbols(f); - -	/* Allocate common symbols, symbol tables, and string tables.  */ - -	if (k_new_syscalls  -		? !new_create_this_module(f, m_name) -		: !old_create_mod_use_count(f))  -	{ -		goto out; -	} - -	if (!obj_check_undefineds(f)) { -		goto out; -	} -	obj_allocate_commons(f); - -	if (m_has_modinfo -	    ? !new_process_module_arguments(f, argc-1, argv+1) -	    : !old_process_module_arguments(f, argc-1, argv+1))  -	{ -		goto out; -	} - -	arch_create_got(f); -	hide_special_symbols(f); - -	if (k_new_syscalls) -		new_create_module_ksymtab(f); - -	/* Find current size of the module */ -	m_size = obj_load_size(f); - - -	errno = 0; -	m_addr = create_module(m_name, m_size); -	switch (errno) { -	case 0: -		break; -	case EEXIST: -		errorMsg("A module named %s already exists", m_name); -		/* Considered as a success in stage1 */ -		fclose(fp); -		return(TRUE); -	case ENOMEM: -		errorMsg("Can't allocate kernel memory for module; needed %lu bytes", -				m_size); -		goto out; -	default: -		errorMsg("create_module: %s: %s", m_name, strerror(errno)); -		goto out; -	} - -	if (!obj_relocate(f, m_addr)) { -		delete_module(m_name); -		goto out; -	} - -	if (k_new_syscalls  -		? !new_init_module(m_name, f, m_size) -		: !old_init_module(m_name, f, m_size))  -	{ -		delete_module(m_name); -		goto out; -	} - -	exit_status = TRUE; - -out: -	fclose(fp); -	return(exit_status); -} - - -int insmod_call(char * full_filename, char * params) -{ -	int argc = 2; -	char *argv[50]; -	char * ptr = params; -	argv[0] = "stage1"; -	argv[1] = full_filename; - -	while (ptr != NULL) { -		argv[argc] = ptr; -		argc++; -		ptr = strchr(ptr, ' '); -		if (ptr) { -			ptr[0] = '\0'; -			ptr++; -		} -	} - -	return insmod_main(argc, argv); -} diff --git a/mdk-stage1/insmod-busybox/loop.h b/mdk-stage1/insmod-busybox/loop.h deleted file mode 100644 index cba8c6b2b..000000000 --- a/mdk-stage1/insmod-busybox/loop.h +++ /dev/null @@ -1,5 +0,0 @@ -#include <linux/posix_types.h> -#undef dev_t -#define dev_t __kernel_dev_t -#include <linux/loop.h> -#undef dev_t diff --git a/mdk-stage1/insmod-busybox/messages.c b/mdk-stage1/insmod-busybox/messages.c deleted file mode 100644 index 81fd9c75c..000000000 --- a/mdk-stage1/insmod-busybox/messages.c +++ /dev/null @@ -1,90 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Copyright (C) 2000 by BitterSweet Enterprises, LLC. - * Written by Karl M. Hegbloom <karlheg@debian.org> - * - * 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 - * - */ - -/* - *  Let's put all of these messages in one place, and link this in as - *  a separate object module, so that there are not going to be - *  multiple non-unique but very similar strings in the binary. - *  Perhaps this will make it simpler to internationalize also, and - *  may make the binary slightly smaller. - */ - -// To use this header file, include something like this: -// -//#define BB_DECLARE_EXTERN -//#define bb_need_memory_exhausted -//#include "messages.c" -// -//Then just use the string memory_exhausted when it is needed. -// - -#include "busybox.h" -#ifndef _BB_MESSAGES_C -#define _BB_MESSAGES_C - -#ifdef BB_DECLARE_EXTERN -#  define BB_DEF_MESSAGE(symbol, string_const) extern const char *symbol; -#else -#  define BB_DEF_MESSAGE(symbol, string_const) const char *symbol = string_const; -#endif - - -#if defined bb_need_full_version || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(full_version, -	 "BusyBox v" BB_VER " (" BB_BT ") multi-call binary -- GPL2") -#endif -#if defined bb_need_name_too_long || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(name_too_long, "file name too long\n") -#endif -#if defined bb_need_omitting_directory || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(omitting_directory, "%s: omitting directory\n") -#endif -#if defined bb_need_not_a_directory || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(not_a_directory, "%s: not a directory\n") -#endif -#if defined bb_need_memory_exhausted || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(memory_exhausted, "memory exhausted\n") -#endif -#if defined bb_need_invalid_date || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(invalid_date, "invalid date `%s'\n") -#endif -#if defined bb_need_invalid_option || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(invalid_option, "invalid option -- %c\n") -#endif -#if defined bb_need_io_error || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(io_error, "%s: input/output error -- %s\n") -#endif -#if defined bb_need_help || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(dash_dash_help, "--help") -#endif -#if defined bb_need_write_error || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(write_error, "Write Error\n") -#endif -#if defined bb_need_too_few_args || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(too_few_args, "too few arguments\n") -#endif -#if defined bb_need_name_longer_then_foo || ! defined BB_DECLARE_EXTERN -	BB_DEF_MESSAGE(name_longer_then_foo, "Names longer then %d chars not supported.\n") -#endif - - -#endif /* _BB_MESSAGES_C */ - diff --git a/mdk-stage1/insmod-busybox/utility.c b/mdk-stage1/insmod-busybox/utility.c deleted file mode 100644 index ffd323347..000000000 --- a/mdk-stage1/insmod-busybox/utility.c +++ /dev/null @@ -1,1759 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Utility routines. - * - * Copyright (C) tons of folks.  Tracking down who wrote what - * isn't something I'm going to worry about...  If you wrote something - * here, please feel free to acknowledge your work. - * - * 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 - * - * Based in part on code from sash, Copyright (c) 1999 by David I. Bell  - * Permission has been granted to redistribute this code under the GPL. - * - */ - -#include "busybox.h" -#if defined (BB_CHMOD_CHOWN_CHGRP) \ - || defined (BB_CP_MV)		   \ - || defined (BB_FIND)		   \ - || defined (BB_INSMOD)		   \ - || defined (BB_LS)		   \ - || defined (BB_RM)		   \ - || defined (BB_TAR) -/* same conditions as recursiveAction */ -#define bb_need_name_too_long -#endif -#define bb_need_memory_exhausted -#define bb_need_full_version -#define BB_DECLARE_EXTERN -#include "messages.c" - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <dirent.h> -#include <time.h> -#include <utime.h> -#include <unistd.h> -#include <ctype.h> -#include <sys/ioctl.h> -#include <sys/utsname.h>		/* for uname(2) */ - -/* Busybox mount uses either /proc/filesystems or /dev/mtab to get the  - * list of available filesystems used for the -t auto option */  -#if defined BB_FEATURE_USE_PROCFS && defined BB_FEATURE_USE_DEVPS_PATCH -//#error Sorry, but busybox can't use both /proc and /dev/ps at the same time -- Pick one and try again. -#error "Sorry, but busybox can't use both /proc and /dev/ps at the same time -- Pick one and try again." -#endif - - -#if defined BB_MOUNT || defined BB_UMOUNT || defined BB_DF -#  if defined BB_MTAB -const char mtab_file[] = "/etc/mtab"; -#  else -#    if defined BB_FEATURE_USE_PROCFS -const char mtab_file[] = "/proc/mounts"; -#    else -#      if defined BB_FEATURE_USE_DEVPS_PATCH -const char mtab_file[] = "/dev/mtab"; -#    else -#        error With (BB_MOUNT||BB_UMOUNT||BB_DF) defined, you must define either BB_MTAB or ( BB_FEATURE_USE_PROCFS | BB_FEATURE_USE_DEVPS_PATCH) -#    endif -#  endif -#  endif -#endif - -#ifdef _STANDALONE_ -void errorMsg(const char *s, ...) -{ -	va_list p; - -	fflush(stdout); -	printf("busybox: "); -	va_start(p, s); -	vprintf(s, p); -	va_end(p); -	printf("\n"); -	fflush(stdout); -} - -extern void logperror(char *s) -{ -		perror(s); -} - -void fatalError(const char *s, ...) -{ -	va_list p; - -	fflush(stdout); -	fprintf(stdout, "busybox: "); -	va_start(p, s); -	vfprintf(stdout, s, p); -	va_end(p); -	fprintf(stdout, "\n"); -	fflush(stdout); -	exit(FALSE); -} -#else /* _STANDALONE_ */ -#include "../log.h" -extern void errorMsg(const char *s, ...) -{ -	va_list p; - -	va_start(p, s); -	vlog_message(s, p); -	va_end(p); -} - -extern void logperror(char *s) -{ -		log_perror(s); -} - -extern void fatalError(const char *s, ...) -{ -	va_list p; - -	va_start(p, s); -	vlog_message(s, p); -	va_end(p); -	while (1); -} -#endif /* _STANDALONE_ */ - - -#if defined BB_INIT -/* Returns kernel version encoded as major*65536 + minor*256 + patch, - * so, for example,  to check if the kernel is greater than 2.2.11: - *     if (get_kernel_revision() <= 2*65536+2*256+11) { <stuff> } - */ -extern int get_kernel_revision(void) -{ -	struct utsname name; -	int major = 0, minor = 0, patch = 0; - -	if (uname(&name) == -1) { -		perror("cannot get system information"); -		return (0); -	} -	sscanf(name.version, "%d.%d.%d", &major, &minor, &patch); -	return major * 65536 + minor * 256 + patch; -} -#endif                                                 /* BB_INIT */ - - - -#if defined BB_FREE || defined BB_INIT || defined BB_UNAME || defined BB_UPTIME -_syscall1(int, sysinfo, struct sysinfo *, info); -#endif                                                 /* BB_INIT */ - -#if defined BB_MOUNT || defined BB_UMOUNT - -#ifndef __NR_umount2 -#define __NR_umount2           52 -#endif - -/* Include our own version of <sys/mount.h>, since libc5 doesn't - * know about umount2 */ -extern _syscall1(int, umount, const char *, special_file); -extern _syscall2(int, umount2, const char *, special_file, int, flags); -extern _syscall5(int, mount, const char *, special_file, const char *, dir, -		const char *, fstype, unsigned long int, rwflag, const void *, data); -#endif - -#if defined BB_INSMOD || defined BB_LSMOD -#ifndef __NR_query_module -#define __NR_query_module     167 -#endif -_syscall5(int, query_module, const char *, name, int, which, -		void *, buf, size_t, bufsize, size_t*, ret); -#endif - - -#if defined (BB_CP_MV) || defined (BB_DU) - -#define HASH_SIZE	311		/* Should be prime */ -#define hash_inode(i)	((i) % HASH_SIZE) - -static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE]; - -/* - * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in - * `ino_dev_hashtable', else return 0 - * - * If NAME is a non-NULL pointer to a character pointer, and there is - * a match, then set *NAME to the value of the name slot in that - * bucket. - */ -int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name) -{ -	ino_dev_hashtable_bucket_t *bucket; - -	bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)]; -	while (bucket != NULL) { -	  if ((bucket->ino == statbuf->st_ino) && -		  (bucket->dev == statbuf->st_dev)) -	  { -		if (name) *name = bucket->name; -		return 1; -	  } -	  bucket = bucket->next; -	} -	return 0; -} - -/* Add statbuf to statbuf hash table */ -void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name) -{ -	int i; -	size_t s; -	ino_dev_hashtable_bucket_t *bucket; -     -	i = hash_inode(statbuf->st_ino); -	s = name ? strlen(name) : 0; -	bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s); -	bucket->ino = statbuf->st_ino; -	bucket->dev = statbuf->st_dev; -	if (name) -		strcpy(bucket->name, name); -	else -		bucket->name[0] = '\0'; -	bucket->next = ino_dev_hashtable[i]; -	ino_dev_hashtable[i] = bucket; -} - -/* Clear statbuf hash table */ -void reset_ino_dev_hashtable(void) -{ -	int i; -	ino_dev_hashtable_bucket_t *bucket; - -	for (i = 0; i < HASH_SIZE; i++) { -		while (ino_dev_hashtable[i] != NULL) { -			bucket = ino_dev_hashtable[i]->next; -			free(ino_dev_hashtable[i]); -			ino_dev_hashtable[i] = bucket; -		} -	} -} - -#endif /* BB_CP_MV || BB_DU */ - -#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN) || defined (BB_AR) -/* - * Return TRUE if a fileName is a directory. - * Nonexistant files return FALSE. - */ -int isDirectory(const char *fileName, const int followLinks, struct stat *statBuf) -{ -	int status; -	int didMalloc = 0; - -	if (statBuf == NULL) { -	    statBuf = (struct stat *)xmalloc(sizeof(struct stat)); -	    ++didMalloc; -	} - -	if (followLinks == TRUE) -		status = stat(fileName, statBuf); -	else -		status = lstat(fileName, statBuf); - -	if (status < 0 || !(S_ISDIR(statBuf->st_mode))) { -	    status = FALSE; -	} -	else status = TRUE; - -	if (didMalloc) { -	    free(statBuf); -	    statBuf = NULL; -	} -	return status; -} -#endif - -#if defined (BB_AR) || defined BB_CP_MV -/* - * Copy readSize bytes between two file descriptors - */ -int copySubFile(int srcFd, int dstFd, size_t remaining) -{ -        size_t size; -        char buffer[BUFSIZ]; - -        while (remaining > 0) { -                if (remaining > BUFSIZ) -                        size = BUFSIZ; -                else -                        size = remaining; -                if (fullWrite(dstFd, buffer, fullRead(srcFd, buffer, size)) < size) -                        return(FALSE); -                remaining -= size; -        } -        return (TRUE); -} -#endif - - -#if defined (BB_CP_MV) -/* - * Copy one file to another, while possibly preserving its modes, times, and - * modes.  Returns TRUE if successful, or FALSE on a failure with an error - * message output.  (Failure is not indicated if attributes cannot be set.) - * -Erik Andersen - */ -int -copyFile(const char *srcName, const char *destName, -		 int setModes, int followLinks, int forceFlag) -{ -	int rfd; -	int wfd; -	int status; -	struct stat srcStatBuf; -	struct stat dstStatBuf; -	struct utimbuf times; - -	if (followLinks == TRUE) -		status = stat(srcName, &srcStatBuf); -	else -		status = lstat(srcName, &srcStatBuf); - -	if (status < 0) { -		perror(srcName); -		return FALSE; -	} - -	if (followLinks == TRUE) -		status = stat(destName, &dstStatBuf); -	else -		status = lstat(destName, &dstStatBuf); - -	if (status < 0 || forceFlag==TRUE) { -		unlink(destName); -		dstStatBuf.st_ino = -1; -		dstStatBuf.st_dev = -1; -	} - -	if ((srcStatBuf.st_dev == dstStatBuf.st_dev) && -		(srcStatBuf.st_ino == dstStatBuf.st_ino)) { -		errorMsg("Copying file \"%s\" to itself\n", srcName); -		return FALSE; -	} - -	if (S_ISDIR(srcStatBuf.st_mode)) { -		//fprintf(stderr, "copying directory %s to %s\n", srcName, destName); -		/* Make sure the directory is writable */ -		status = mkdir(destName, 0777777 ^ umask(0)); -		if (status < 0 && errno != EEXIST) { -			perror(destName); -			return FALSE; -		} -	} else if (S_ISLNK(srcStatBuf.st_mode)) { -		char link_val[BUFSIZ + 1]; -		int link_size; - -		//fprintf(stderr, "copying link %s to %s\n", srcName, destName); -		/* Warning: This could possibly truncate silently, to BUFSIZ chars */ -		link_size = readlink(srcName, &link_val[0], BUFSIZ); -		if (link_size < 0) { -			perror(srcName); -			return FALSE; -		} -		link_val[link_size] = '\0'; -		status = symlink(link_val, destName); -		if (status < 0) { -			perror(destName); -			return FALSE; -		} -#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) -		if (setModes == TRUE) { -			/* Try to set owner, but fail silently like GNU cp */ -			lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid); -		} -#endif -		return TRUE; -	} else if (S_ISFIFO(srcStatBuf.st_mode)) { -		//fprintf(stderr, "copying fifo %s to %s\n", srcName, destName); -		if (mkfifo(destName, 0644) < 0) { -			perror(destName); -			return FALSE; -		} -	} else if (S_ISBLK(srcStatBuf.st_mode) || S_ISCHR(srcStatBuf.st_mode) -			   || S_ISSOCK(srcStatBuf.st_mode)) { -		//fprintf(stderr, "copying soc, blk, or chr %s to %s\n", srcName, destName); -		if (mknod(destName, srcStatBuf.st_mode, srcStatBuf.st_rdev) < 0) { -			perror(destName); -			return FALSE; -		} -	} else if (S_ISREG(srcStatBuf.st_mode)) { -		//fprintf(stderr, "copying regular file %s to %s\n", srcName, destName); -		rfd = open(srcName, O_RDONLY); -		if (rfd < 0) { -			perror(srcName); -			return FALSE; -		} - -	 	wfd = open(destName, O_WRONLY | O_CREAT | O_TRUNC, -				 srcStatBuf.st_mode); -		if (wfd < 0) { -			perror(destName); -			close(rfd); -			return FALSE; -		} - -		if (copySubFile(rfd, wfd, srcStatBuf.st_size)==FALSE) -			goto error_exit;	 -		 -		close(rfd); -		if (close(wfd) < 0) { -			return FALSE; -		} -	} - -	if (setModes == TRUE) { -		/* This is fine, since symlinks never get here */ -		if (chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid) < 0) { -			perror(destName); -			exit FALSE; -		} -		if (chmod(destName, srcStatBuf.st_mode) < 0) { -			perror(destName); -			exit FALSE; -		} -		times.actime = srcStatBuf.st_atime; -		times.modtime = srcStatBuf.st_mtime; -		if (utime(destName, ×) < 0) { -			perror(destName); -			exit FALSE; -		} -	} - -	return TRUE; - -  error_exit: -	perror(destName); -	close(rfd); -	close(wfd); - -	return FALSE; -} -#endif							/* BB_CP_MV */ - - - -#if defined BB_TAR || defined BB_LS ||defined BB_AR - -#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) -#define TYPECHAR(mode)  ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) - -/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ -static const mode_t SBIT[] = { -	0, 0, S_ISUID, -	0, 0, S_ISGID, -	0, 0, S_ISVTX -}; - -/* The 9 mode bits to test */ -static const mode_t MBIT[] = { -	S_IRUSR, S_IWUSR, S_IXUSR, -	S_IRGRP, S_IWGRP, S_IXGRP, -	S_IROTH, S_IWOTH, S_IXOTH -}; - -#define MODE1  "rwxrwxrwx" -#define MODE0  "---------" -#define SMODE1 "..s..s..t" -#define SMODE0 "..S..S..T" - -/* - * Return the standard ls-like mode string from a file mode. - * This is static and so is overwritten on each call. - */ -const char *modeString(int mode) -{ -	static char buf[12]; - -	int i; - -	buf[0] = TYPECHAR(mode); -	for (i = 0; i < 9; i++) { -		if (mode & SBIT[i]) -			buf[i + 1] = (mode & MBIT[i]) ? SMODE1[i] : SMODE0[i]; -		else -			buf[i + 1] = (mode & MBIT[i]) ? MODE1[i] : MODE0[i]; -	} -	return buf; -} -#endif							/* BB_TAR || BB_LS */ - - -#if defined BB_TAR || defined BB_AR -/* - * Return the standard ls-like time string from a time_t - * This is static and so is overwritten on each call. - */ -const char *timeString(time_t timeVal) -{ -	time_t now; -	char *str; -	static char buf[26]; - -	time(&now); - -	str = ctime(&timeVal); - -	strcpy(buf, &str[4]); -	buf[12] = '\0'; - -	if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) { -		strcpy(&buf[7], &str[20]); -		buf[11] = '\0'; -	} - -	return buf; -} -#endif /* BB_TAR || BB_AR */ - -#if defined BB_TAR || defined BB_CP_MV || defined BB_AR -/* - * Write all of the supplied buffer out to a file. - * This does multiple writes as necessary. - * Returns the amount written, or -1 on an error. - */ -int fullWrite(int fd, const char *buf, int len) -{ -	int cc; -	int total; - -	total = 0; - -	while (len > 0) { -		cc = write(fd, buf, len); - -		if (cc < 0) -			return -1; - -		buf += cc; -		total += cc; -		len -= cc; -	} - -	return total; -} -#endif /* BB_TAR || BB_CP_MV || BB_AR */ - - -#if defined BB_TAR || defined BB_TAIL || defined BB_AR || defined BB_SH || defined BB_CP_MV -/* - * Read all of the supplied buffer from a file. - * This does multiple reads as necessary. - * Returns the amount read, or -1 on an error. - * A short read is returned on an end of file. - */ -int fullRead(int fd, char *buf, int len) -{ -	int cc; -	int total; - -	total = 0; - -	while (len > 0) { -		cc = read(fd, buf, len); - -		if (cc < 0) -			return -1; - -		if (cc == 0) -			break; - -		buf += cc; -		total += cc; -		len -= cc; -	} - -	return total; -} -#endif /* BB_TAR || BB_TAIL || BB_AR || BB_SH */ - - -#if defined (BB_CHMOD_CHOWN_CHGRP) \ - || defined (BB_CP_MV)			\ - || defined (BB_FIND)			\ - || defined (BB_INSMOD)			\ - || defined (BB_LS)				\ - || defined (BB_RM)				\ - || defined (BB_TAR) - -/* - * Walk down all the directories under the specified  - * location, and do something (something specified - * by the fileAction and dirAction function pointers). - * - * Unfortunatly, while nftw(3) could replace this and reduce  - * code size a bit, nftw() wasn't supported before GNU libc 2.1,  - * and so isn't sufficiently portable to take over since glibc2.1 - * is so stinking huge. - */ -int recursiveAction(const char *fileName, -					int recurse, int followLinks, int depthFirst, -					int (*fileAction) (const char *fileName, -									   struct stat * statbuf, -									   void* userData), -					int (*dirAction) (const char *fileName, -									  struct stat * statbuf, -									  void* userData), -					void* userData) -{ -	int status; -	struct stat statbuf; -	struct dirent *next; - -	if (followLinks == TRUE) -		status = stat(fileName, &statbuf); -	else -		status = lstat(fileName, &statbuf); - -	if (status < 0) { -#ifdef BB_DEBUG_PRINT_SCAFFOLD -		fprintf(stderr, -				"status=%d followLinks=%d TRUE=%d\n", -				status, followLinks, TRUE); -#endif -		perror(fileName); -		return FALSE; -	} - -	if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode))) { -		if (fileAction == NULL) -			return TRUE; -		else -			return fileAction(fileName, &statbuf, userData); -	} - -	if (recurse == FALSE) { -		if (S_ISDIR(statbuf.st_mode)) { -			if (dirAction != NULL) -				return (dirAction(fileName, &statbuf, userData)); -			else -				return TRUE; -		} -	} - -	if (S_ISDIR(statbuf.st_mode)) { -		DIR *dir; - -		dir = opendir(fileName); -		if (!dir) { -			perror(fileName); -			return FALSE; -		} -		if (dirAction != NULL && depthFirst == FALSE) { -			status = dirAction(fileName, &statbuf, userData); -			if (status == FALSE) { -				perror(fileName); -				return FALSE; -			} -		} -		while ((next = readdir(dir)) != NULL) { -			char nextFile[BUFSIZ + 1]; - -			if ((strcmp(next->d_name, "..") == 0) -				|| (strcmp(next->d_name, ".") == 0)) { -				continue; -			} -			if (strlen(fileName) + strlen(next->d_name) + 1 > BUFSIZ) { -				errorMsg("name_too_long"); -				return FALSE; -			} -			memset(nextFile, 0, sizeof(nextFile)); -			sprintf(nextFile, "%s/%s", fileName, next->d_name); -			status = -				recursiveAction(nextFile, TRUE, followLinks, depthFirst, -								fileAction, dirAction, userData); -			if (status == FALSE) { -				closedir(dir); -				return FALSE; -			} -		} -		status = closedir(dir); -		if (status < 0) { -			perror(fileName); -			return FALSE; -		} -		if (dirAction != NULL && depthFirst == TRUE) { -			status = dirAction(fileName, &statbuf, userData); -			if (status == FALSE) { -				perror(fileName); -				return FALSE; -			} -		} -	} else { -		if (fileAction == NULL) -			return TRUE; -		else -			return fileAction(fileName, &statbuf, userData); -	} -	return TRUE; -} - -#endif							/* BB_CHMOD_CHOWN_CHGRP || BB_CP_MV || BB_FIND || BB_LS || BB_INSMOD */ - - - -#if defined (BB_TAR) || defined (BB_MKDIR) || defined (BB_AR) -/* - * Attempt to create the directories along the specified path, except for - * the final component.  The mode is given for the final directory only, - * while all previous ones get default protections.  Errors are not reported - * here, as failures to restore files can be reported later. - */ -extern int createPath(const char *name, int mode) -{ -	char *cp; -	char *cpOld; -	char buf[BUFSIZ + 1]; -	int retVal = 0; - -	strcpy(buf, name); -	for (cp = buf; *cp == '/'; cp++); -	cp = strchr(cp, '/'); -	while (cp) { -		cpOld = cp; -		cp = strchr(cp + 1, '/'); -		*cpOld = '\0'; -		retVal = mkdir(buf, cp ? 0777 : mode); -		if (retVal != 0 && errno != EEXIST) { -			perror(buf); -			return FALSE; -		} -		*cpOld = '/'; -	} -	return TRUE; -} -#endif							/* BB_TAR || BB_MKDIR */ - - - -#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_MKDIR) \ - || defined (BB_MKFIFO) || defined (BB_MKNOD) || defined (BB_AR) -/* [ugoa]{+|-|=}[rwxst] */ - - - -extern int parse_mode(const char *s, mode_t * theMode) -{ -	mode_t andMode = - -		S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; -	mode_t orMode = 0; -	mode_t mode = 0; -	mode_t groups = 0; -	char type; -	char c; - -	if (s==NULL) -		return (FALSE); - -	do { -		for (;;) { -			switch (c = *s++) { -			case '\0': -				return -1; -			case 'u': -				groups |= S_ISUID | S_IRWXU; -				continue; -			case 'g': -				groups |= S_ISGID | S_IRWXG; -				continue; -			case 'o': -				groups |= S_IRWXO; -				continue; -			case 'a': -				groups |= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; -				continue; -			case '+': -			case '=': -			case '-': -				type = c; -				if (groups == 0)	/* The default is "all" */ -					groups |= -						S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; -				break; -			default: -				if (isdigit(c) && c >= '0' && c <= '7' && -					mode == 0 && groups == 0) { -					*theMode = strtol(--s, NULL, 8); -					return (TRUE); -				} else -					return (FALSE); -			} -			break; -		} - -		while ((c = *s++) != '\0') { -			switch (c) { -			case ',': -				break; -			case 'r': -				mode |= S_IRUSR | S_IRGRP | S_IROTH; -				continue; -			case 'w': -				mode |= S_IWUSR | S_IWGRP | S_IWOTH; -				continue; -			case 'x': -				mode |= S_IXUSR | S_IXGRP | S_IXOTH; -				continue; -			case 's': -				mode |= S_IXGRP | S_ISUID | S_ISGID; -				continue; -			case 't': -				mode |= 0; -				continue; -			default: -				*theMode &= andMode; -				*theMode |= orMode; -				return (TRUE); -			} -			break; -		} -		switch (type) { -		case '=': -			andMode &= ~(groups); -			/* fall through */ -		case '+': -			orMode |= mode & groups; -			break; -		case '-': -			andMode &= ~(mode & groups); -			orMode &= andMode; -			break; -		} -	} while (c == ','); -	*theMode &= andMode; -	*theMode |= orMode; -	return (TRUE); -} - - -#endif -/* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR || BB_MKFIFO || BB_MKNOD */ - - - - - -#if defined BB_CHMOD_CHOWN_CHGRP || defined BB_PS || defined BB_LS \ - || defined BB_TAR || defined BB_ID || defined BB_LOGGER \ - || defined BB_LOGNAME || defined BB_WHOAMI - -/* This parses entries in /etc/passwd and /etc/group.  This is desirable - * for BusyBox, since we want to avoid using the glibc NSS stuff, which - * increases target size and is often not needed or wanted for embedded - * systems. - * - * /etc/passwd entries look like this:  - *		root:x:0:0:root:/root:/bin/bash - * and /etc/group entries look like this:  - *		root:x:0: - * - * This uses buf as storage to hold things. - *  - */ -unsigned long my_getid(const char *filename, char *name, long id, long *gid) -{ -	FILE *file; -	char *rname, *start, *end, buf[128]; -	long rid; -	long rgid = 0; - -	file = fopen(filename, "r"); -	if (file == NULL) { -		/* Do not complain.  It is ok for /etc/passwd and -		 * friends to be missing... */ -		return (-1); -	} - -	while (fgets(buf, 128, file) != NULL) { -		if (buf[0] == '#') -			continue; - -		/* username/group name */ -		start = buf; -		end = strchr(start, ':'); -		if (end == NULL) -			continue; -		*end = '\0'; -		rname = start; - -		/* password */ -		start = end + 1; -		end = strchr(start, ':'); -		if (end == NULL) -			continue; - -		/* uid in passwd, gid in group */ -		start = end + 1; -		rid = (unsigned long) strtol(start, &end, 10); -		if (end == start) -			continue; - -		/* gid in passwd */ -		start = end + 1; -		rgid = (unsigned long) strtol(start, &end, 10); -		 -		if (name) { -			if (0 == strcmp(rname, name)) { -			    if (gid) *gid = rgid; -				fclose(file); -				return (rid); -			} -		} -		if (id != -1 && id == rid) { -			strncpy(name, rname, 8); -			if (gid) *gid = rgid; -			fclose(file); -			return (TRUE); -		} -	} -	fclose(file); -	return (-1); -} - -/* returns a uid given a username */ -long my_getpwnam(char *name) -{ -	return my_getid("/etc/passwd", name, -1, NULL); -} - -/* returns a gid given a group name */ -long my_getgrnam(char *name) -{ -	return my_getid("/etc/group", name, -1, NULL); -} - -/* gets a username given a uid */ -void my_getpwuid(char *name, long uid) -{ -	my_getid("/etc/passwd", name, uid, NULL); -} - -/* gets a groupname given a gid */ -void my_getgrgid(char *group, long gid) -{ -	my_getid("/etc/group", group, gid, NULL); -} - -/* gets a gid given a user name */ -long my_getpwnamegid(char *name) -{ -	long gid; -	my_getid("/etc/passwd", name, -1, &gid); -	return gid; -} - -#endif - /* BB_CHMOD_CHOWN_CHGRP || BB_PS || BB_LS || BB_TAR \ - || BB_ID || BB_LOGGER || BB_LOGNAME || BB_WHOAMI */ - - -#if (defined BB_CHVT) || (defined BB_DEALLOCVT) || (defined BB_SETKEYCODES) - -/* From <linux/kd.h> */  -#define KDGKBTYPE       0x4B33  /* get keyboard type */ -#define         KB_84           0x01 -#define         KB_101          0x02    /* this is what we always answer */ - -int is_a_console(int fd) -{ -	char arg; - -	arg = 0; -	return (ioctl(fd, KDGKBTYPE, &arg) == 0 -			&& ((arg == KB_101) || (arg == KB_84))); -} - -static int open_a_console(char *fnam) -{ -	int fd; - -	/* try read-only */ -	fd = open(fnam, O_RDWR); - -	/* if failed, try read-only */ -	if (fd < 0 && errno == EACCES) -		fd = open(fnam, O_RDONLY); - -	/* if failed, try write-only */ -	if (fd < 0 && errno == EACCES) -		fd = open(fnam, O_WRONLY); - -	/* if failed, fail */ -	if (fd < 0) -		return -1; - -	/* if not a console, fail */ -	if (!is_a_console(fd)) { -		close(fd); -		return -1; -	} - -	/* success */ -	return fd; -} - -/* - * Get an fd for use with kbd/console ioctls. - * We try several things because opening /dev/console will fail - * if someone else used X (which does a chown on /dev/console). - * - * if tty_name is non-NULL, try this one instead. - */ - -int get_console_fd(char *tty_name) -{ -	int fd; - -	if (tty_name) { -		if (-1 == (fd = open_a_console(tty_name))) -			return -1; -		else -			return fd; -	} - -	fd = open_a_console("/dev/tty"); -	if (fd >= 0) -		return fd; - -	fd = open_a_console("/dev/tty0"); -	if (fd >= 0) -		return fd; - -	fd = open_a_console("/dev/console"); -	if (fd >= 0) -		return fd; - -	for (fd = 0; fd < 3; fd++) -		if (is_a_console(fd)) -			return fd; - -	errorMsg("Couldnt get a file descriptor referring to the console\n"); -	return -1;					/* total failure */ -} - - -#endif							/* BB_CHVT || BB_DEALLOCVT || BB_SETKEYCODES */ - - -#if defined BB_FIND || defined BB_INSMOD -/* - * Routine to see if a text string is matched by a wildcard pattern. - * Returns TRUE if the text is matched, or FALSE if it is not matched - * or if the pattern is invalid. - *  *		matches zero or more characters - *  ?		matches a single character - *  [abc]	matches 'a', 'b' or 'c' - *  \c		quotes character c - * Adapted from code written by Ingo Wilken, and - * then taken from sash, Copyright (c) 1999 by David I. Bell - * Permission is granted to use, distribute, or modify this source, - * provided that this copyright notice remains intact. - * Permission to distribute this code under the GPL has been granted. - */ -extern int check_wildcard_match(const char *text, const char *pattern) -{ -	const char *retryPat; -	const char *retryText; -	int ch; -	int found; -	int len; - -	retryPat = NULL; -	retryText = NULL; - -	while (*text || *pattern) { -		ch = *pattern++; - -		switch (ch) { -		case '*': -			retryPat = pattern; -			retryText = text; -			break; - -		case '[': -			found = FALSE; - -			while ((ch = *pattern++) != ']') { -				if (ch == '\\') -					ch = *pattern++; - -				if (ch == '\0') -					return FALSE; - -				if (*text == ch) -					found = TRUE; -			} -			len=strlen(text); -			if (found == FALSE && len!=0) { -				return FALSE; -			} -			if (found == TRUE) { -				if (strlen(pattern)==0 && len==1) { -					return TRUE; -				} -				if (len!=0) { -					text++; -					continue; -				} -			} - -			/* fall into next case */ - -		case '?': -			if (*text++ == '\0') -				return FALSE; - -			break; - -		case '\\': -			ch = *pattern++; - -			if (ch == '\0') -				return FALSE; - -			/* fall into next case */ - -		default: -			if (*text == ch) { -				if (*text) -					text++; -				break; -			} - -			if (*text) { -				pattern = retryPat; -				text = ++retryText; -				break; -			} - -			return FALSE; -		} - -		if (pattern == NULL) -			return FALSE; -	} - -	return TRUE; -} -#endif                            /* BB_FIND || BB_INSMOD */ - - - - -#if defined BB_DF || defined BB_MTAB -/* - * Given a block device, find the mount table entry if that block device - * is mounted. - * - * Given any other file (or directory), find the mount table entry for its - * filesystem. - */ -extern struct mntent *findMountPoint(const char *name, const char *table) -{ -	struct stat s; -	dev_t mountDevice; -	FILE *mountTable; -	struct mntent *mountEntry; - -	if (stat(name, &s) != 0) -		return 0; - -	if ((s.st_mode & S_IFMT) == S_IFBLK) -		mountDevice = s.st_rdev; -	else -		mountDevice = s.st_dev; - - -	if ((mountTable = setmntent(table, "r")) == 0) -		return 0; - -	while ((mountEntry = getmntent(mountTable)) != 0) { -		if (strcmp(name, mountEntry->mnt_dir) == 0 -			|| strcmp(name, mountEntry->mnt_fsname) == 0)	/* String match. */ -			break; -		if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice)	/* Match the device. */ -			break; -		if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice)	/* Match the directory's mount point. */ -			break; -	} -	endmntent(mountTable); -	return mountEntry; -} -#endif							/* BB_DF || BB_MTAB */ - - - -#if defined BB_DD || defined BB_TAIL -/* - * Read a number with a possible multiplier. - * Returns -1 if the number format is illegal. - */ -extern long getNum(const char *cp) -{ -	long value; - -	if (!isDecimal(*cp)) -		return -1; - -	value = 0; - -	while (isDecimal(*cp)) -		value = value * 10 + *cp++ - '0'; - -	switch (*cp++) { -	case 'M': -	case 'm':					/* `tail' uses it traditionally */ -		value *= 1048576; -		break; - -	case 'k': -		value *= 1024; -		break; - -	case 'b': -		value *= 512; -		break; - -	case 'w': -		value *= 2; -		break; - -	case '\0': -		return value; - -	default: -		return -1; -	} - -	if (*cp) -		return -1; - -	return value; -} -#endif							/* BB_DD || BB_TAIL */ - - -#if defined BB_INIT || defined BB_SYSLOGD  -/* try to open up the specified device */ -extern int device_open(char *device, int mode) -{ -	int m, f, fd = -1; - -	m = mode | O_NONBLOCK; - -	/* Retry up to 5 times */ -	for (f = 0; f < 5; f++) -		if ((fd = open(device, m, 0600)) >= 0) -			break; -	if (fd < 0) -		return fd; -	/* Reset original flags. */ -	if (m != mode) -		fcntl(fd, F_SETFL, mode); -	return fd; -} -#endif							/* BB_INIT BB_SYSLOGD */ - - -#if defined BB_KILLALL || ( defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF )) -#ifdef BB_FEATURE_USE_DEVPS_PATCH -#include <linux/devps.h> /* For Erik's nifty devps device driver */ -#endif - -#if defined BB_FEATURE_USE_DEVPS_PATCH -/* findPidByName() - *   - *  This finds the pid of the specified process, - *  by using the /dev/ps device driver. - * - *  Returns a list of all matching PIDs - */ -extern pid_t* findPidByName( char* pidName) -{ -	int fd, i, j; -	char device[] = "/dev/ps"; -	pid_t num_pids; -	pid_t* pid_array = NULL; -	pid_t* pidList=NULL; - -	/* open device */  -	fd = open(device, O_RDONLY); -	if (fd < 0) -		fatalError( "open failed for `%s': %s\n", device, strerror (errno)); - -	/* Find out how many processes there are */ -	if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0)  -		fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno)); -	 -	/* Allocate some memory -- grab a few extras just in case  -	 * some new processes start up while we wait. The kernel will -	 * just ignore any extras if we give it too many, and will trunc. -	 * the list if we give it too few.  */ -	pid_array = (pid_t*) xcalloc( num_pids+10, sizeof(pid_t)); -	pid_array[0] = num_pids+10; - -	/* Now grab the pid list */ -	if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0)  -		fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno)); - -	/* Now search for a match */ -	for (i=1, j=0; i<pid_array[0] ; i++) { -		char* p; -		struct pid_info info; - -	    info.pid = pid_array[i]; -	    if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0) -			fatalError( "\nDEVPS_GET_PID_INFO: %s\n", strerror (errno)); - -		/* Make sure we only match on the process name */ -		p=info.command_line+1; -		while ((*p != 0) && !isspace(*(p)) && (*(p-1) != '\\')) {  -			(p)++; -		} -		if (isspace(*(p))) -				*p='\0'; - -		if ((strstr(info.command_line, pidName) != NULL) -				&& (strlen(pidName) == strlen(info.command_line))) { -			pidList=xrealloc( pidList, sizeof(pid_t) * (j+2)); -			pidList[j++]=info.pid; -		} -	} -	if (pidList) -		pidList[j]=0; - -	/* Free memory */ -	free( pid_array); - -	/* close device */ -	if (close (fd) != 0)  -		fatalError( "close failed for `%s': %s\n",device, strerror (errno)); - -	return pidList; -} -#else		/* BB_FEATURE_USE_DEVPS_PATCH */ -#if ! defined BB_FEATURE_USE_PROCFS -#error Sorry, I depend on the /proc filesystem right now. -#endif - -/* findPidByName() - *   - *  This finds the pid of the specified process. - *  Currently, it's implemented by rummaging through  - *  the proc filesystem. - * - *  Returns a list of all matching PIDs - */ -extern pid_t* findPidByName( char* pidName) -{ -	DIR *dir; -	struct dirent *next; -	pid_t* pidList=NULL; -	int i=0; - -	dir = opendir("/proc"); -	if (!dir) -		fatalError( "Cannot open /proc: %s\n", strerror (errno)); -	 -	while ((next = readdir(dir)) != NULL) { -		FILE *status; -		char filename[256]; -		char buffer[256]; - -		/* If it isn't a number, we don't want it */ -		if (!isdigit(*next->d_name)) -			continue; - -		sprintf(filename, "/proc/%s/cmdline", next->d_name); -		status = fopen(filename, "r"); -		if (!status) { -			continue; -		} -		fgets(buffer, 256, status); -		fclose(status); - -		if (strstr(get_last_path_component(buffer), pidName) != NULL) { -			pidList=xrealloc( pidList, sizeof(pid_t) * (i+2)); -			pidList[i++]=strtol(next->d_name, NULL, 0); -		} -	} - -	if (pidList) -		pidList[i]=0; -	return pidList; -} -#endif							/* BB_FEATURE_USE_DEVPS_PATCH */ -#endif							/* BB_KILLALL || ( BB_FEATURE_LINUXRC && ( BB_HALT || BB_REBOOT || BB_POWEROFF )) */ - -#ifndef DMALLOC -/* this should really be farmed out to libbusybox.a */ -extern void *xmalloc(size_t size) -{ -	void *ptr = malloc(size); - -	if (!ptr) -		fatalError("memory_exhausted"); -	return ptr; -} - -extern void *xrealloc(void *old, size_t size) -{ -	void *ptr; -	if (!size) -			size = 1; -	ptr = realloc(old, size); -	if (!ptr) -		fatalError("memory_exhausted"); -	return ptr; -} - -extern void *xcalloc(size_t nmemb, size_t size) -{ -	void *ptr = calloc(nmemb, size); -	if (!ptr) -		fatalError("memory_exhausted"); -	return ptr; -} -#endif - -#if defined BB_FEATURE_NFSMOUNT || defined BB_SH || defined BB_LS -# ifndef DMALLOC -extern char * xstrdup (const char *s) { -	char *t; - -	if (s == NULL) -		return NULL; - -	t = strdup (s); - -	if (t == NULL) -		fatalError("memory_exhausted"); - -	return t; -} -# endif -#endif - -#if defined BB_FEATURE_NFSMOUNT -extern char * xstrndup (const char *s, int n) { -	char *t; - -	if (s == NULL) -		fatalError("xstrndup bug"); - -	t = xmalloc(n+1); -	strncpy(t,s,n); -	t[n] = 0; - -	return t; -} -#endif - - -#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT) -extern int vdprintf(int d, const char *format, va_list ap) -{ -	char buf[BUF_SIZE]; -	int len; - -	len = vsprintf(buf, format, ap); -	return write(d, buf, len); -} -#endif							/* BB_SYSLOGD */ - - -#if defined BB_FEATURE_MOUNT_LOOP -#include <fcntl.h> -#include "loop.h" /* Pull in loop device support */ - -extern int del_loop(const char *device) -{ -	int fd; - -	if ((fd = open(device, O_RDONLY)) < 0) { -		perror(device); -		return (FALSE); -	} -	if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { -		perror("ioctl: LOOP_CLR_FD"); -		return (FALSE); -	} -	close(fd); -	return (TRUE); -} - -extern int set_loop(const char *device, const char *file, int offset, -					int *loopro) -{ -	struct loop_info loopinfo; -	int fd, ffd, mode; - -	mode = *loopro ? O_RDONLY : O_RDWR; -	if ((ffd = open(file, mode)) < 0 && !*loopro -		&& (errno != EROFS || (ffd = open(file, mode = O_RDONLY)) < 0)) { -		perror(file); -		return 1; -	} -	if ((fd = open(device, mode)) < 0) { -		close(ffd); -		perror(device); -		return 1; -	} -	*loopro = (mode == O_RDONLY); - -	memset(&loopinfo, 0, sizeof(loopinfo)); -	strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); -	loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; - -	loopinfo.lo_offset = offset; - -	loopinfo.lo_encrypt_key_size = 0; -	if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { -		perror("ioctl: LOOP_SET_FD"); -		close(fd); -		close(ffd); -		return 1; -	} -	if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { -		(void) ioctl(fd, LOOP_CLR_FD, 0); -		perror("ioctl: LOOP_SET_STATUS"); -		close(fd); -		close(ffd); -		return 1; -	} -	close(fd); -	close(ffd); -	return 0; -} - -extern char *find_unused_loop_device(void) -{ -	char dev[20]; -	int i, fd; -	struct stat statbuf; -	struct loop_info loopinfo; - -	for (i = 0; i <= 7; i++) { -		sprintf(dev, "/dev/loop%d", i); -		if (stat(dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { -			if ((fd = open(dev, O_RDONLY)) >= 0) { -				if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == -1) { -					if (errno == ENXIO) {	/* probably free */ -						close(fd); -						return strdup(dev); -					} -				} -				close(fd); -			} -		} -	} -	return NULL; -} -#endif							/* BB_FEATURE_MOUNT_LOOP */ - -#if defined BB_MOUNT || defined BB_DF || ( defined BB_UMOUNT && ! defined BB_MTAB) -extern int find_real_root_device_name(char* name) -{ -	DIR *dir; -	struct dirent *entry; -	struct stat statBuf, rootStat; -	char fileName[BUFSIZ]; - -	if (stat("/", &rootStat) != 0) { -		errorMsg("could not stat '/'\n"); -		return( FALSE); -	} - -	dir = opendir("/dev"); -	if (!dir) { -		errorMsg("could not open '/dev'\n"); -		return( FALSE); -	} - -	while((entry = readdir(dir)) != NULL) { - -		/* Must skip ".." since that is "/", and so we  -		 * would get a false positive on ".."  */ -		if (strcmp(entry->d_name, "..") == 0) -			continue; - -		snprintf( fileName, strlen(name)+1, "/dev/%s", entry->d_name); - -		if (stat(fileName, &statBuf) != 0) -			continue; -		/* Some char devices have the same dev_t as block -		 * devices, so make sure this is a block device */ -		if (! S_ISBLK(statBuf.st_mode)) -			continue; -		if (statBuf.st_rdev == rootStat.st_rdev) { -			strcpy(name, fileName);  -			return ( TRUE); -		} -	} - -	return( FALSE); -} -#endif - - -/* get_line_from_file() - This function reads an entire line from a text file - * up to a newline. It returns a malloc'ed char * which must be stored and - * free'ed  by the caller. */ -extern char *get_line_from_file(FILE *file) -{ -	static const int GROWBY = 80; /* how large we will grow strings by */ - -	int ch; -	int idx = 0; -	char *linebuf = NULL; -	int linebufsz = 0; - -	while (1) { -		ch = fgetc(file); -		if (ch == EOF) -			break; -		/* grow the line buffer as necessary */ -		while (idx > linebufsz-2) -			linebuf = xrealloc(linebuf, linebufsz += GROWBY); -		linebuf[idx++] = (char)ch; -		if ((char)ch == '\n') -			break; -	} - -	if (idx == 0) -		return NULL; - -	linebuf[idx] = 0; -	return linebuf; -} - -#if defined BB_CAT -extern void print_file(FILE *file) -{ -	int c; - -	while ((c = getc(file)) != EOF) -		putc(c, stdout); -	fclose(file); -	fflush(stdout); -} - -extern int print_file_by_name(char *filename) -{ -	FILE *file; -	file = fopen(filename, "r"); -	if (file == NULL) { -		return FALSE; -	} -	print_file(file); -	return TRUE; -} -#endif /* BB_CAT || BB_LSMOD */ - -#if defined BB_ECHO || defined BB_TR -char process_escape_sequence(char **ptr) -{ -	char c; - -	switch (c = *(*ptr)++) { -	case 'a': -		c = '\a'; -		break; -	case 'b': -		c = '\b'; -		break; -	case 'f': -		c = '\f'; -		break; -	case 'n': -		c = '\n'; -		break; -	case 't': -		c = '\t'; -		break; -	case 'v': -		c = '\v'; -		break; -	case '\\': -		c = '\\'; -		break; -	case '0': case '1': case '2': case '3': -	case '4': case '5': case '6': case '7': -		c -= '0'; -		if ('0' <= **ptr && **ptr <= '7') { -			c = c * 8 + (*(*ptr)++ - '0'); -			if ('0' <= **ptr && **ptr <= '7') -				c = c * 8 + (*(*ptr)++ - '0'); -		} -		break; -	default: -		(*ptr)--; -		c = '\\'; -		break; -	} -	return c; -} -#endif - -#if defined BB_BASENAME || defined BB_LN || defined BB_SH -char *get_last_path_component(char *path) -{ -	char *s=path+strlen(path)-1; - -	/* strip trailing slashes */ -	while (s && *s == '/') { -		*s-- = '\0'; -	} - -	/* find last component */ -	s = strrchr(path, '/'); -	if (s==NULL) return path; -	else return s+1; -} -#endif - -#if defined BB_GREP || defined BB_SED -void xregcomp(regex_t *preg, const char *regex, int cflags) -{ -	int ret; -	if ((ret = regcomp(preg, regex, cflags)) != 0) { -		int errmsgsz = regerror(ret, preg, NULL, 0); -		char *errmsg = xmalloc(errmsgsz); -		regerror(ret, preg, errmsg, errmsgsz); -		fatalError("bb_regcomp: %s\n", errmsg); -	} -} -#endif - -/* END CODE */ -/* -Local Variables: -c-file-style: "linux" -c-basic-offset: 4 -tab-width: 4 -End: -*/ | 
