cmdline, linuxrc, Makefile

This commit is contained in:
Denis Knauf 2012-05-21 00:14:49 +02:00
commit 4c5ec0343d
3 changed files with 274 additions and 0 deletions

25
Makefile Normal file
View file

@ -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

159
cmdline.c Normal file
View file

@ -0,0 +1,159 @@
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#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;
}

90
linuxrc Executable file
View file

@ -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 >/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