From 4c5ec0343d57b631e66ae7d4d1b8c2479d65d2ac Mon Sep 17 00:00:00 2001 From: Denis Knauf Date: Mon, 21 May 2012 00:14:49 +0200 Subject: [PATCH] cmdline, linuxrc, Makefile --- Makefile | 25 +++++++++ cmdline.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ linuxrc | 90 +++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 Makefile create mode 100644 cmdline.c create mode 100755 linuxrc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0b60fd1 --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ + +CC ?= cc +INSTALL ?= install +RM ?= rm + +D ?= / +PREFIX ?= / +BIN_PREFIX ?= $(PREFIX)/bin +CFLAGS ?= -Os + +all: cmdline + +cmdline: cmdline.c + $(CC) $(CFLAGS) -o $@ -Dcmdline_main=main $< + +install: + $(INSTALL) -D -m 0755 cmdline $(D)/$(BIN_PREFIX) + $(INSTALL) -D -m 0744 isirc $(D)/$(BIN_PREFIX) + $(LN) -s isirc $(D)/init + $(LN) -s isirc $(D)/linuxrc + +clean: + $(RM) cmdline + +.PHONY: all install clean diff --git a/cmdline.c b/cmdline.c new file mode 100644 index 0000000..125e83f --- /dev/null +++ b/cmdline.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXREAD 1024 + +int scan( const char *key, const char *arg) { + int i = 0; + for( i = 0; key[i] && arg[i] && key[i] == arg[i]; i++); + if( key[i]) + return 0; + switch( arg[i]) { + case '=': + puts( arg+i+1); + case 0: + return 1; + } + return 0; +} + +#define IFS( X) ((X) == 0 || (X) == ' ' || (X) == '\t' || (X) == '\n' || (X) == '\r') +#define BUFREAD( I, S, D, F, M, E) \ + if( !( ++i < s)) { \ + if( -1 == (s = read( fd, d, MAXREAD))) \ + goto ERROR; \ + if( !s) \ + break; \ + i = 0; \ + } + +int scan_fd( char *key, int fd, char **val) { + ssize_t s = 0; + char *d = malloc( MAXREAD); + int i = 0, j, ret = 0; + + if( -1 == (s = read( fd, d, MAXREAD))) + goto ERROR; + while( s) { + // liest solange ein leeres zeichen da ist. + while( IFS( d[i])) + BUFREAD( i, s, d, fd, MAXREAD, ERROR); + // vergleicht das naechste wort mit dem schluessel. + j = 0; + while( key[j] && d[i] == key[j]) { + j++; + BUFREAD( i, s, d, fd, MAXREAD, ERROR); + } + // wenn das letzte zeichen vom schluessel erreicht wurde, + // stimmt der schluessel mit dem gescanten wort ueberein. + if( !key[j] && ( d[i] == '=' || IFS( d[i]))) + goto FOUND; + while( !IFS( d[i])) + BUFREAD( i, s, d, fd, MAXREAD, ERROR); + } + free( d); + return 0; + +FOUND: + // key gefunden und der wert wird ausgegeben. + if( d[i] == '=') { + char *p; + i++; + for( j = 0; i+j < s && !IFS( d[i+j]); j++); + if( !(p = malloc( j+1))) + goto ERROR; + memcpy( p, d+i, j); + i = 0; + if( !IFS( d[i+j])) { + if( -1 == (s = read( fd, d, MAXREAD))) + goto ERROR; + if( s) { + while( !IFS( d[i]) && s) { + if( !( ++i < s)) { + if( !(p = realloc( p, j+i+1))) + goto ERROR; + memcpy( p+j, d, i); + j += i; + if( -1 == (s = read( fd, d, MAXREAD))) + goto ERROR; + if( !s) + break; + } + } + if( !(p = realloc( p, j+i+1))) + goto ERROR; + memcpy( p+j, d, i); + } + } + p[j+i] = 0; + *val = p; + ret = 1; + } + // key gefunden, hat aber keinen wert, der ausgegeben werden muss. + else + ret = 2; + free( d); + return ret; + +ERROR: + free( d); + return -1; +} + +extern int cmdline_main( int argc, char **argv) { + int i = 0, action = 'a', fd = 0, ret = 255; + char c, *key = NULL, *val, *file = "/proc/cmdline"; + + while( (c = getopt( argc, argv, "+hcf:")) != -1) + switch( c) { + case 'h': + fprintf( stderr, "usage: %s [-c] [-f file] keyword [args...]\n", argv[0]); + fprintf( stderr, "parse the linux-like cmdline, which are given via args or:\n"); + fprintf( stderr, "\t-c: cmdline; -f file: file. file can be '-'.\n"); + exit( 0); + case 'f': file = optarg; + case 'c': action = 'f'; + } + if( !( argc > optind)) + return 3; + key = argv[optind]; + + switch( action) { + case 'a': + for( i = optind+1; i < argc; i++) + if( scan( key, argv[i])) { + ret = 0; + break; + } + break; + case 'f': + if( !( file[0] == '-' && file[1] == 0)) + if( -1 == (fd = open( file, O_RDONLY))) { + perror( argv[0]); + ret = 2; + } + switch( scan_fd( key, fd, &val)) { + case 1: + puts( val); + case 2: + ret = 0; + break; + case 0: + ret = 1; + break; + case -1: + ret = 2; + perror( argv[0]); + } + if( !fd) + close( fd); + } + + return ret; +} diff --git a/linuxrc b/linuxrc new file mode 100755 index 0000000..e291c82 --- /dev/null +++ b/linuxrc @@ -0,0 +1,90 @@ +#!/bin/sh + +QUITE=false + +log() { + if [ "X$QUITE" != "Xtrue" ] + then + echo "$*" + fi +} + +err() { + echo "$*" >&2 +} + +if [ "x${1}x" != "x-rx" ] +then + exec /dev/console 2>&1 + log "### ISIRD ###" + PATH=/bin + cd / + + log " mount proc and sysfs and / as rw" + mount -t proc proc /proc + mount -t sysfs sysfs /sys + mount -o remount,rw / + + log " mdev" + mdev -s + log " activate volume groups" + vgscan --mknodes --ignorelockingfailure + vgchange --ignorelockingfailure -P -a y + + if cmdline -c isirdsh + then + log " start shell" + exec sh + fi + +else + log " returned" +fi + +log " detect cmdline options..." +ROOT="$(cmdline -c root)" +log " root: #{ROOT}" +FLAGS="$(cmdline -c rootflags)" +log " flags: ${FLAGS}" +if cmdline -c ro +then + FLAGS="${FLAGS},ro" +elif cmdline -c rw +then + FLAGS="${FLAGS},rw" +fi +log " flags: ${FLAGS}" +FSTYPE="$(cmdline -c rootfstype)" +FSTYPE="${FSTYPE:-auto}" +log " umount sysfs" +umount /sys +FLAGS="${FLAGS#,}" +log " mount ${ROOT} as ${FSTYPE} with ${FLAGS}" +if ! mount -o "${FLAGS}" -t "${FSTYPE}" "${ROOT}" /mnt +then + err "Can't mount root!" + exec sh +fi + +if ! test -d /mnt/initrd || mkdir /mnt/initrd +then + err "/initrd doesn't exist on root!" + exec sh +fi + +log " Change to new root" +cd /mnt +if ! pivot_root . initrd +then + err "Can't pivot root!" + cd / + exec sh +fi + +log " OK :)" +export LD_LIBRARY_PATH="/initrd/lib" +LD_SO="${LD_LIBRARY_PATH}/ld-linux.so.2" +${LD_SO} /initrd/bin/ls /mnt/dev/* +echo 0x0100 > /initrd/proc/sys/kernel/real-root-dev +${LD_SO} /initrd/bin/umount -n /initrd/proc +exit 0