Browse Source

Juergen Sawinski, Dimitar Zhekov, Rene Rebe:

further improved linuxrc: frst try iso9660, a trygets function, use waitpid,
                          trywait function and a tryexeclp macro, exchangeable
                          tar compression program argument ...


git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@2488 c5f82cb5-29bc-0310-9cd0-bff59a50e3bc
rocklinux
Juergen "George" Sawinski 21 years ago
parent
commit
a80e033a6e
1 changed files with 104 additions and 94 deletions
  1. +104
    -94
      target/bootdisk/linuxrc.c

+ 104
- 94
target/bootdisk/linuxrc.c

@ -22,7 +22,7 @@
*
* --- ROCK-COPYRIGHT-NOTE-END ---
*
* linuxrc.c is Copyright (C) 2003 Cliford Wolf and Rene Rebe
* linuxrc.c is Copyright (C) 2003, 2004 Cliford Wolf and Rene Rebe
*
*/
@ -39,6 +39,7 @@
#include <sys/klog.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#ifndef MS_MOVE
# define MS_MOVE 8192
@ -52,7 +53,11 @@
# define STAGE_2_SMALL_IMAGE "2nd_stage_small.tar.gz"
#endif
/* 64 MB should be enought for the tmpfs */
#ifndef STAGE_2_COMPRESS_ARG
# define STAGE_2_COMPRESS_ARG "--use-compress-program=gzip"
#endif
/* 640kB, err, 64 MB should be enought for the tmpfs ;-) */
#define TMPFS_OPTIONS "size=67108864"
/* It seams like we need this prototype here ... */
@ -89,25 +94,68 @@ void doboot()
int trymount (const char* source, const char* target)
{
return mount(source, target, "ext3", MS_RDONLY, NULL) &&
return mount(source, target, "iso9660", MS_RDONLY, NULL) &&
mount(source, target, "ext3", MS_RDONLY, NULL) &&
mount(source, target, "ext2", MS_RDONLY, NULL) &&
mount(source, target, "minix", MS_RDONLY, NULL) &&
mount(source, target, "vfat", MS_RDONLY, NULL) &&
mount(source, target, "iso9660", MS_RDONLY, NULL);
mount(source, target, "vfat", MS_RDONLY, NULL);
}
void trygets(char *s, int len)
{
s[0]=0;
if (fgets(s, len, stdin) == NULL) {
if (ferror(stdin)) perror("fgets");
else printf("EOF\n");
sleep(1);
execl("/linuxrc", "/linuxrc", NULL);
printf("\nCan't start /linuxrc!! Life sucks.\n\n");
exit(0);
}
// guarantee a 0 termination and remove the trailing newline
s[len-1]=0;
if (strlen(s) > 0) s[strlen(s)-1]=0;
}
int trywait(int pid)
{
int status = -1;
if (pid < 0)
perror("fork");
else if (waitpid(pid, &status, 0) >= 0)
status = !WIFEXITED(status) || WEXITSTATUS(status);
return status;
}
#define tryexeclp(file, arg, ...) ( { \
int i = 0, pid; \
\
if ( (pid = fork()) == 0 ) { \
execlp(file, arg, __VA_ARGS__); \
perror(file); \
exit(1); \
} \
\
trywait(pid); \
} )
void httpload()
{
int fd[2];
char baseurl[200];
char filename[100];
char url[500];
int pid_wget, pid_tar;
printf("Enter base URL (e.g. http://1.2.3.4/rock): ");
fflush(stdout);
baseurl[0]=0; fgets(baseurl, 200, stdin); baseurl[199]=0;
if (strlen(baseurl) > 0) baseurl[strlen(baseurl)-1]=0;
trygets(baseurl, 200);
if (baseurl[0] == 0) return;
printf("Select a stage 2 image file:\n\n"
@ -115,8 +163,7 @@ void httpload()
"Enter number or image file name (default=1): ",
STAGE_2_BIG_IMAGE, STAGE_2_SMALL_IMAGE);
filename[0]=0; fgets(filename, 100, stdin); filename[99]=0;
if (strlen(filename) > 0) filename[strlen(filename)-1]=0;
trygets(filename, 100);
if (filename[0] == 0) strcpy(filename, STAGE_2_BIG_IMAGE);
else if (!strcmp(filename, "1")) strcpy(filename, STAGE_2_BIG_IMAGE);
else if (!strcmp(filename, "2")) strcpy(filename, STAGE_2_SMALL_IMAGE);
@ -137,23 +184,23 @@ void httpload()
if ( pipe(fd) < 0 )
{ perror("Can't create pipe"); exit_linuxrc=0; }
if ( fork() == 0 ) {
if ( (pid_wget = fork()) == 0 ) {
dup2(fd[1],1); close(fd[0]); close(fd[1]);
execlp("wget", "wget", "-O", "-", url, NULL);
perror("wget");
_exit(1);
}
if ( fork() == 0 ) {
if ( (pid_tar = fork()) == 0 ) {
dup2(fd[0],0); close(fd[0]); close(fd[1]);
execlp("tar", "tar", "--use-compress-program=gzip",
execlp("tar", "tar", STAGE_2_COMPRESS_ARG,
"-C", "/mnt_root", "-xf", "-", NULL);
perror("tar");
_exit(1);
}
close(fd[0]); close(fd[1]);
wait(NULL); wait(NULL);
waitpid(pid_wget, NULL, 0); waitpid(pid_tar, NULL, 0);
printf("finished ... now booting 2nd stage\n");
doboot();
}
@ -164,6 +211,7 @@ void load_modules(char * dir)
char text[100], filename[200];
char *execargs[100];
int n, m=0, len;
int pid;
n = scandir(dir, &namelist, 0, alphasort);
if (n > 0) {
@ -191,8 +239,7 @@ void load_modules(char * dir)
fflush(stdout);
while (1) {
text[0]=0; fgets(text, 100, stdin); text[99]=0;
if (strlen(text) > 0) text[strlen(text)-1]=0;
trygets(text, 100);
if (text[0] == 0) return;
snprintf(filename, 200, "%s/%s.o", dir, strtok(text, " "));
@ -206,12 +253,12 @@ void load_modules(char * dir)
}
if ( fork() == 0 ) {
if ( (pid = fork()) == 0 ) {
execvp(execargs[0], execargs);
printf("Can't start %s!\n", execargs[0]);
exit(1);
}
wait(NULL);
waitpid(pid, NULL, 0);
return;
}
@ -226,6 +273,7 @@ void load_ramdisk_file()
char filename[100];
int nr=0;
int i, tmp_nr;
int pid;
printf("Select a device for loading the 2nd stage system from: \n\n");
@ -250,14 +298,11 @@ void load_ramdisk_file()
printf("\nEnter number or device file name (default=0): ");
fflush(stdout);
while (1) {
text[0]=0; fgets(text, 100, stdin); text[99]=0;
if (strlen(text) > 0)
text[strlen(text)-1]=0;
if (text[0] == 0)
strcpy (text, "0");
trygets(text, 100);
if (text[0] == 0)
strcpy (text, "0");
while (1) {
if ( ! access(text, R_OK) ) {
strcpy(devicefile, text);
break;
@ -270,6 +315,8 @@ void load_ramdisk_file()
printf("No such device found. Try again (enter=back): ");
fflush(stdout);
trygets(text, 100);
if (text[0] == 0) return;
}
printf("Select a stage 2 image file:\n\n"
@ -277,8 +324,7 @@ void load_ramdisk_file()
"Enter number or image file name (default=1): ",
STAGE_2_BIG_IMAGE, STAGE_2_SMALL_IMAGE);
text[0]=0; fgets(text, 100, stdin); text[99]=0;
if (strlen(text) > 0) text[strlen(text)-1]=0;
trygets(text, 100);
if (text[0] == 0) strcpy(filename, STAGE_2_BIG_IMAGE);
else if (! strcmp(text, "1")) strcpy(filename, STAGE_2_BIG_IMAGE);
else if (! strcmp(text, "2")) strcpy(filename, STAGE_2_SMALL_IMAGE);
@ -299,15 +345,15 @@ void load_ramdisk_file()
if ( mount("none", "/mnt_root", "tmpfs", 0, TMPFS_OPTIONS) )
{ perror("Can't mount /mnt_root"); exit_linuxrc=0; }
if ( fork() == 0 ) {
if ( (pid = fork()) == 0 ) {
printf("Extracting 2nd stage filesystem to ram ...\n");
snprintf(text, 100, "/mnt_source/%s", filename);
execlp( "tar", "tar", "--use-compress-program=gzip",
execlp( "tar", "tar", STAGE_2_COMPRESS_ARG,
"-C", "/mnt_root", "-xf", text, NULL);
printf("Can't run tar on %s!\n", filename);
exit(1);
}
wait(NULL);
waitpid(pid, NULL, 0);
if ( umount("/mnt_source") )
{ perror("Can't umount /mnt_source"); exit_linuxrc=0; }
@ -327,7 +373,7 @@ void activate_swap()
printf("\nEnter file name of swap device: ");
fflush(stdout);
text[0]=0; fgets(text, 100, stdin); text[99]=0;
trygets(text, 100);
if ( text[0] ) {
if ( swapon(text, 0) < 0 )
perror("Can't activate swap device");
@ -340,75 +386,38 @@ void config_net()
char ip[100]="";
char gw[100]="";
if ( fork() == 0 ) {
execlp("ip", "ip", "addr", NULL);
perror("ip");
exit(1);
}
wait(NULL);
tryexeclp("ip", "ip", "addr", NULL);
printf("\n");
if ( fork() == 0 ) {
execlp("ip", "ip", "route", NULL);
perror("ip");
exit(1);
}
wait(NULL);
tryexeclp("ip", "ip", "route", NULL);
perror("ip");
printf("\n");
printf("Enter interface name (eth0): ");
fflush(stdout); fgets(dv, 100, stdin); dv[99]=0;
if (strlen(dv) > 0) dv[strlen(dv)-1]=0;
fflush(stdout);
trygets(dv, 100);
if (dv[0] == 0) strcpy(dv, "eth0");
printf("Enter ip (192.168.0.254/24): ");
fflush(stdout); fgets(ip, 100, stdin); ip[99]=0;
if (strlen(ip) > 0) ip[strlen(ip)-1]=0;
fflush(stdout);
trygets(ip, 100);
if (ip[0] == 0) strcpy(ip, "192.168.0.254/24");
if ( fork() == 0 ) {
execlp("ip", "ip", "addr", "add", ip, "dev", dv, NULL);
perror("ip");
exit(1);
}
wait(NULL);
if ( fork() == 0 ) {
execlp("ip", "ip", "link", "set", dv, "up", NULL);
perror("ip");
exit(1);
}
wait(NULL);
tryexeclp("ip", "ip", "addr", "add", ip, "dev", dv, NULL);
tryexeclp("ip", "ip", "link", "set", dv, "up", NULL);
printf("Enter default gateway (none): ");
fflush(stdout); fgets(gw, 100, stdin); gw[99]=0;
if (strlen(gw) > 0) gw[strlen(gw)-1]=0;
if (gw[0] != 0) {
if ( fork() == 0 ) {
execlp("ip", "ip", "route", "add",
"default", "via", gw, NULL);
perror("ip");
exit(1);
}
wait(NULL);
}
fflush(stdout);
trygets(gw, 100);
if (gw[0] != 0)
tryexeclp("ip", "ip", "route", "add",
"default", "via", gw, NULL);
printf("\n");
if ( fork() == 0 ) {
execlp("ip", "ip", "addr", NULL);
perror("ip");
exit(1);
}
wait(NULL);
tryexeclp("ip", "ip", "addr", NULL);
printf("\n");
if ( fork() == 0 ) {
execlp("ip", "ip", "route", NULL);
perror("ip");
exit(1);
}
wait(NULL);
tryexeclp("ip", "ip", "route", NULL);
}
void autoload_modules()
@ -416,11 +425,12 @@ void autoload_modules()
char line[200], cmd[200], module[200];
int fd[2], rc;
FILE *f;
int pid;
if (pipe(fd) <0)
{ perror("Can't create pipe"); return; }
if ( fork() == 0 ) {
if ( (pid = fork()) == 0 ) {
dup2(fd[1],1); close(fd[0]); close(fd[1]);
execlp("gawk", "gawk", "-f", "/bin/hwscan", NULL);
printf("Can't start >>hwscan<< program with gawk!\n");
@ -442,29 +452,31 @@ void autoload_modules()
}
}
fclose(f);
wait(NULL);
waitpid(pid, NULL, 0);
}
void exec_sh()
{
int rc;
printf ("Quit the shell to return to the stage 1 loader!\n");
if ( fork() == 0 ) {
execl("/bin/kiss", "kiss", NULL);
if ( (rc = fork()) == 0 ) {
execl("/bin/kiss", "kiss", "-E", NULL);
perror("kiss");
_exit(1);
}
wait(NULL);
waitpid(rc, NULL, 0);
}
int main()
{
char text[100];
int input=1;
if ( mount("none", "/dev", "devfs", 0, NULL) && errno != EBUSY )
perror("Can't mount /dev");
if ( mount("none", "/proc", "proc", 0, NULL) )
if ( mount("none", "/proc", "proc", 0, NULL) && errno != EBUSY )
perror("Can't mount /proc");
/* Only print important stuff to console */
@ -498,10 +510,7 @@ drivers (if needed) and configure the installation source so the\n\
What do you want to do [0-7] (default=0)? ");
fflush(stdout);
text[0]=0; fgets(text, 100, stdin); text[99]=0;
if (strlen(text) > 0)
text[strlen(text)-1]=0;
text[0]=0; trygets(text, 100);
input=atoi(text);
switch (input) {
@ -557,3 +566,4 @@ What do you want to do [0-7] (default=0)? ");
printf("\nCan't start /linuxrc!! Life sucks.\n\n");
return 0;
}

Loading…
Cancel
Save