More stuff
No binary (build failed)
—
(log yok)
| @@ -71,7 +71,6 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |
| struct passwd *pwd; | |
| int recursiveFlag=FALSE; | |
| char *groupName; | |
| - | mode_t andWithMode= S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; |
| whichApp = (strcmp(*argv, "chown")==0)? CHOWN_APP : (strcmp(*argv, "chmod")==0)? CHMOD_APP : CHGRP_APP; | |
| @@ -100,6 +99,7 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |
| if ( whichApp == CHMOD_APP ) { | |
| /* Find the specified modes */ | |
| + | mode &= S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; |
| if ( parse_mode(*argv, &mode) == FALSE ) { | |
| fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); | |
| exit( FALSE); | |
| @@ -13,19 +13,21 @@ | |
| #include <sys/mount.h> | |
| #include <sys/reboot.h> | |
| #include <sys/kdaemon.h> | |
| - | #include <sys/swap.h> |
| #include <sys/sysmacros.h> | |
| - | |
| - | const char init_usage[] = "Used internally by the system."; |
| - | char console[16] = ""; |
| - | const char * default_console = "/dev/tty1"; |
| - | char * first_terminal = NULL; |
| - | const char * second_terminal = "/dev/tty2"; |
| - | const char log[] = "/dev/tty3"; |
| - | char * term_ptr = NULL; |
| + | #include <linux/serial.h> /* for serial_struct */ |
| + | #include <sys/vt.h> /* for vt_stat */ |
| + | #include <sys/ioctl.h> |
| + | |
| + | static const char init_usage[] = "Used internally by the system."; |
| + | static char console[16] = ""; |
| + | static const char* default_console = "/dev/tty2"; |
| + | static char* first_terminal = NULL; |
| + | static const char* second_terminal = "/dev/tty2"; |
| + | static const char* log = "/dev/tty3"; |
| + | static char* term_ptr = NULL; |
| static void | |
| - | message(const char * terminal, const char * pattern, ...) |
| + | message(const char* terminal, const char * pattern, ...) |
| { | |
| int fd; | |
| FILE * con = 0; | |
| @@ -36,7 +38,8 @@ message(const char * terminal, const char * pattern, ...) | |
| * has switched consoles, the open will get the new console. If we kept | |
| * the console open, we'd always print to the same one. | |
| */ | |
| - | if ( ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) |
| + | if ( !terminal |
| + | || ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) |
| || ((con = fdopen(fd, "w")) == NULL) ) | |
| return; | |
| @@ -158,44 +161,59 @@ run(const char* program, const char* const* arguments, | |
| static int | |
| mem_total() | |
| { | |
| - | char s[80]; |
| - | char *p; |
| - | FILE *f; |
| - | const char pattern[]="MemTotal:"; |
| - | |
| - | f=fopen("/proc/meminfo","r"); |
| - | while (NULL != fgets(s,79,f)) { |
| - | p=strstr(s, pattern); |
| - | if (NULL != p) { |
| - | fclose(f); |
| - | return(atoi(p+strlen(pattern))); |
| + | char s[80]; |
| + | char *p; |
| + | FILE *f; |
| + | const char pattern[]="MemTotal:"; |
| + | |
| + | f=fopen("/proc/meminfo","r"); |
| + | while (NULL != fgets(s,79,f)) { |
| + | p=strstr(s, pattern); |
| + | if (NULL != p) { |
| + | fclose(f); |
| + | return(atoi(p+strlen(pattern))); |
| + | } |
| } | |
| - | } |
| - | return -1; |
| + | return -1; |
| } | |
| static void | |
| set_free_pages() | |
| { | |
| - | char s[80]; |
| + | char s[80]; |
| + | FILE *f; |
| + | |
| + | f=fopen("/proc/sys/vm/freepages","r"); |
| + | fgets(s,79,f); |
| + | if (atoi(s) < 32) { |
| + | fclose(f); |
| + | f=fopen("/proc/sys/vm/freepages","w"); |
| + | fprintf(f,"30\t40\t50\n"); |
| + | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); |
| + | } |
| + | fclose(f); |
| + | } |
| + | |
| + | static int |
| + | get_kernel_revision() |
| + | { |
| FILE *f; | |
| + | int major=0, minor=0, patch=0; |
| - | f=fopen("/proc/sys/vm/freepages","r"); |
| - | fgets(s,79,f); |
| - | if (atoi(s) < 32) { |
| - | fclose(f); |
| - | f=fopen("/proc/sys/vm/freepages","w"); |
| - | fprintf(f,"30\t40\t50\n"); |
| - | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); |
| - | } |
| + | f = fopen("/proc/sys/kernel/osrelease","r"); |
| + | fscanf(f,"%d.%d.%d",&major,&minor,&patch); |
| fclose(f); | |
| + | return major*65536 + minor*256 + patch; |
| } | |
| + | |
| static void | |
| - | shutdown_system(int do_reboot) |
| + | shutdown_system(void) |
| { | |
| static const char * const umount_args[] = {"/bin/umount", "-a", "-n", 0}; | |
| + | static const char * const swapoff_args[] = {"/bin/swapoff", "-a", 0}; |
| + | message(console, "The system is going down NOW !!"); |
| sync(); | |
| /* Allow Ctrl-Alt-Del to reboot system. */ | |
| reboot(RB_ENABLE_CAD); | |
| @@ -208,59 +226,72 @@ shutdown_system(int do_reboot) | |
| message(console, "Sending SIGKILL to all processes.\r\n"); | |
| kill(-1, SIGKILL); | |
| sleep(1); | |
| + | waitfor(run("/bin/swapoff", swapoff_args, console, 0)); |
| waitfor(run("/bin/umount", umount_args, console, 0)); | |
| sync(); | |
| - | bdflush(1, 0); |
| - | sync(); |
| - | reboot(do_reboot ?RB_AUTOBOOT : RB_HALT_SYSTEM); |
| - | exit(0); |
| + | if (get_kernel_revision() <= 2*65536+2*256+11) { |
| + | /* Removed bdflush call, kupdate in kernels >2.2.11 */ |
| + | bdflush(1, 0); |
| + | sync(); |
| + | } |
| } | |
| static void | |
| halt_signal(int sig) | |
| { | |
| - | shutdown_system(0); |
| + | shutdown_system(); |
| + | message(console, "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); |
| + | reboot( RB_HALT_SYSTEM); |
| + | exit(0); |
| } | |
| static void | |
| reboot_signal(int sig) | |
| { | |
| - | shutdown_system(1); |
| + | shutdown_system(); |
| + | message(console, "Please stand by while rebooting the system.\r\n"); |
| + | reboot( RB_AUTOBOOT); |
| + | exit(0); |
| } | |
| static void | |
| - | exit_signal(int sig) |
| + | configure_terminals( int serial_cons, int single_user_mode ) |
| { | |
| - | |
| - | /* initrd doesn't work anyway */ |
| - | |
| - | shutdown_system(1); |
| - | |
| - | /* This is used on the initial ramdisk */ |
| - | |
| - | /* message(log, "Init exiting."); |
| - | exit(0); |
| - | */ |
| - | } |
| - | |
| - | void |
| - | configure_terminals( int serial_cons ) |
| - | { |
| - | //struct stat statbuf; |
| char *tty; | |
| + | struct serial_struct sr; |
| + | struct vt_stat vt; |
| + | |
| switch (serial_cons) { | |
| + | case -1: |
| + | /* 2.2 kernels: |
| + | * identify the real console backend and try to make use of it */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | sprintf( console, "/dev/ttyS%d", sr.line ); |
| + | serial_cons = sr.line+1; |
| + | } |
| + | else if (ioctl(0, VT_GETSTATE, &vt) == 0) { |
| + | sprintf( console, "/dev/tty%d", vt.v_active ); |
| + | serial_cons = 0; |
| + | } |
| + | else { |
| + | /* unknown backend: fallback to /dev/console */ |
| + | strcpy( console, "/dev/console" ); |
| + | serial_cons = 0; |
| + | } |
| + | break; |
| + | |
| case 1: | |
| - | strcpy( console, "/dev/ttyS0" ); |
| + | strcpy( console, "/dev/cua0" ); |
| break; | |
| case 2: | |
| - | strcpy( console, "/dev/ttyS1" ); |
| + | strcpy( console, "/dev/cua1" ); |
| break; | |
| default: | |
| tty = ttyname(0); | |
| if (tty) { | |
| strcpy( console, tty ); | |
| - | if (!strncmp( tty, "/dev/ttyS", 9 )) |
| + | if (!strncmp( tty, "/dev/cua", 8 )) |
| serial_cons=1; | |
| } | |
| else | |
| @@ -269,24 +300,33 @@ configure_terminals( int serial_cons ) | |
| } | |
| if (!first_terminal) | |
| first_terminal = console; | |
| - | if (serial_cons && !strncmp(term_ptr,"TERM=linux",10)) |
| - | term_ptr = "TERM=vt100"; |
| + | #if #cpu (sparc) |
| + | if (serial_cons > 0 && !strncmp(term_ptr,"TERM=linux",10)) |
| + | term_ptr = "TERM=vt100"; |
| + | #endif |
| + | if (serial_cons) { |
| + | /* disable other but the first terminal: |
| + | * VT is not initialized anymore on 2.2 kernel when booting from |
| + | * serial console, therefore modprobe is flooding the display with |
| + | * "can't locate module char-major-4" messages. */ |
| + | log = 0; |
| + | second_terminal = 0; |
| + | } |
| } | |
| extern int | |
| init_main(int argc, char * * argv) | |
| { | |
| - | static const char* const rc = "etc/rc"; |
| + | const char * rc_arguments[100]; |
| const char * arguments[100]; | |
| - | int run_rc = 1; |
| + | int run_rc = TRUE; |
| int j; | |
| int pid1 = 0; | |
| int pid2 = 0; | |
| - | int create_swap= -1; |
| struct stat statbuf; | |
| - | const char * tty_commands[2] = { "bin/sh", "bin/sh"}; |
| - | char swap[20]; |
| + | const char * tty_commands[3] = { "etc/init.d/rcS", "bin/sh"}; |
| int serial_console = 0; | |
| + | int retval; |
| /* | |
| * If I am started as /linuxrc instead of /sbin/init, I don't have the | |
| @@ -299,7 +339,7 @@ init_main(int argc, char * * argv) | |
| signal(SIGUSR1, halt_signal); | |
| signal(SIGUSR2, reboot_signal); | |
| signal(SIGINT, reboot_signal); | |
| - | signal(SIGTERM, exit_signal); |
| + | signal(SIGTERM, reboot_signal); |
| reboot(RB_DISABLE_CAD); | |
| @@ -307,7 +347,7 @@ init_main(int argc, char * * argv) | |
| for ( j = 1; j < argc; j++ ) { | |
| if ( strcmp(argv[j], "single") == 0 ) { | |
| - | run_rc = 0; |
| + | run_rc = FALSE; |
| tty_commands[0] = "bin/sh"; | |
| tty_commands[1] = 0; | |
| } | |
| @@ -341,7 +381,6 @@ init_main(int argc, char * * argv) | |
| term_ptr=__environ[j]; | |
| } | |
| } | |
| - | configure_terminals( serial_console ); |
| printf("mounting /proc ...\n"); | |
| if (mount("/proc","/proc","proc",0,0)) { | |
| @@ -349,81 +388,75 @@ init_main(int argc, char * * argv) | |
| } | |
| printf("\tdone.\n"); | |
| + | if (get_kernel_revision() >= 2*65536+1*256+71) { |
| + | /* if >= 2.1.71 kernel, /dev/console is not a symlink anymore: |
| + | * use it as primary console */ |
| + | serial_console=-1; |
| + | } |
| + | |
| + | /* Make sure /etc/init.d/rc exists */ |
| + | retval= stat(tty_commands[0],&statbuf); |
| + | if (retval) |
| + | run_rc = FALSE; |
| + | |
| + | configure_terminals( serial_console, run_rc); |
| + | |
| set_free_pages(); | |
| /* not enough memory to do anything useful*/ | |
| if (mem_total() < 2000) { | |
| - | int retval; |
| - | retval= stat("/etc/swappartition",&statbuf); |
| - | if (retval) { |
| - | printf("You do not have enough RAM, sorry.\n"); |
| - | while (1) { sleep(1);} |
| - | } else { /* everything OK */ |
| - | FILE *f; |
| - | |
| - | f=fopen("/etc/swappartition","r"); |
| - | fgets(swap,19,f); |
| - | fclose(f); |
| - | *(strstr(swap,"\n"))='\0'; |
| - | |
| - | if (swapon(swap,0)) { |
| - | perror("swapon failed\n"); |
| - | } else { |
| - | f=fopen("/etc/swaps","w"); |
| - | fprintf(f,"%s none swap rw 0 0",swap); |
| - | fclose(f); |
| - | create_swap = 0; |
| + | retval= stat("/etc/fstab",&statbuf); |
| + | if (retval) { |
| + | printf("You do not have enough RAM, sorry.\n"); |
| + | while (1) { sleep(1);} |
| + | } else { |
| + | /* Try to turn on swap */ |
| + | static const char * const swapon_args[] = {"/bin/swapon", "-a", 0}; |
| + | waitfor(run("/bin/swapon", swapon_args, console, 0)); |
| + | if (mem_total() < 2000) { |
| + | printf("You do not have enough RAM, sorry.\n"); |
| + | while (1) { sleep(1);} |
| + | } |
| } | |
| - | } |
| } | |
| /* | |
| * Don't modify **argv directly, it would show up in the "ps" display. | |
| * I don't want "init" to look like "rc". | |
| */ | |
| - | arguments[0] = rc; |
| + | rc_arguments[0] = tty_commands[0]; |
| for ( j = 1; j < argc; j++ ) { | |
| - | arguments[j] = argv[j]; |
| - | } |
| - | arguments[j] = 0; |
| - | |
| - | if ( run_rc ) { |
| - | run(rc, arguments, console, 0); |
| - | //waitfor(run(rc, arguments, console, 0)); |
| - | } |
| - | |
| - | if ( 0 == create_swap) { |
| - | if (unlink("/etc/swappartition")) { |
| - | perror("unlinking /etc/swappartition"); |
| - | } |
| + | rc_arguments[j] = argv[j]; |
| } | |
| + | rc_arguments[j] = 0; |
| arguments[0] = "-sh"; | |
| arguments[1] = 0; | |
| + | |
| + | /* Ok, now launch the rc script /etc/init.d/rcS and prepare to start up |
| + | * some VTs on tty1 and tty2 if somebody hits enter |
| + | */ |
| for ( ; ; ) { | |
| int wpid; | |
| int status; | |
| - | if ( pid1 == 0 && tty_commands[0] ) { |
| - | /* Ask before starting a shell */ |
| - | /* |
| - | arguments[0] = tty_commands[0]; |
| - | */ |
| - | pid1 = run(tty_commands[0], arguments, first_terminal, 1); |
| + | if ( pid1 == 0 && tty_commands[0] ) { |
| + | if ( run_rc == TRUE ) { |
| + | pid1 = run(tty_commands[0], rc_arguments, first_terminal, 0); |
| + | } else { |
| + | pid2 = run(tty_commands[1], arguments, first_terminal, 1); |
| + | } |
| } | |
| - | if ( pid2 == 0 && tty_commands[1] ) { |
| + | if ( pid2 == 0 && second_terminal && tty_commands[1] ) { |
| pid2 = run(tty_commands[1], arguments, second_terminal, 1); | |
| } | |
| wpid = wait(&status); | |
| - | if ( wpid > 0 ) { |
| - | /* DEBUGGING */ |
| + | if ( wpid > 0 && wpid != pid1) { |
| message(log, "pid %d exited, status=%x.\n", wpid, status); | |
| } | |
| - | if ( wpid == pid1 ) { |
| - | pid1 = 0; |
| - | } |
| - | if ( wpid == pid2 ) |
| + | if ( wpid == pid2 ) { |
| pid2 = 0; | |
| + | } |
| } | |
| } | |
| @@ -13,19 +13,21 @@ | |
| #include <sys/mount.h> | |
| #include <sys/reboot.h> | |
| #include <sys/kdaemon.h> | |
| - | #include <sys/swap.h> |
| #include <sys/sysmacros.h> | |
| - | |
| - | const char init_usage[] = "Used internally by the system."; |
| - | char console[16] = ""; |
| - | const char * default_console = "/dev/tty1"; |
| - | char * first_terminal = NULL; |
| - | const char * second_terminal = "/dev/tty2"; |
| - | const char log[] = "/dev/tty3"; |
| - | char * term_ptr = NULL; |
| + | #include <linux/serial.h> /* for serial_struct */ |
| + | #include <sys/vt.h> /* for vt_stat */ |
| + | #include <sys/ioctl.h> |
| + | |
| + | static const char init_usage[] = "Used internally by the system."; |
| + | static char console[16] = ""; |
| + | static const char* default_console = "/dev/tty2"; |
| + | static char* first_terminal = NULL; |
| + | static const char* second_terminal = "/dev/tty2"; |
| + | static const char* log = "/dev/tty3"; |
| + | static char* term_ptr = NULL; |
| static void | |
| - | message(const char * terminal, const char * pattern, ...) |
| + | message(const char* terminal, const char * pattern, ...) |
| { | |
| int fd; | |
| FILE * con = 0; | |
| @@ -36,7 +38,8 @@ message(const char * terminal, const char * pattern, ...) | |
| * has switched consoles, the open will get the new console. If we kept | |
| * the console open, we'd always print to the same one. | |
| */ | |
| - | if ( ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) |
| + | if ( !terminal |
| + | || ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) |
| || ((con = fdopen(fd, "w")) == NULL) ) | |
| return; | |
| @@ -158,44 +161,59 @@ run(const char* program, const char* const* arguments, | |
| static int | |
| mem_total() | |
| { | |
| - | char s[80]; |
| - | char *p; |
| - | FILE *f; |
| - | const char pattern[]="MemTotal:"; |
| - | |
| - | f=fopen("/proc/meminfo","r"); |
| - | while (NULL != fgets(s,79,f)) { |
| - | p=strstr(s, pattern); |
| - | if (NULL != p) { |
| - | fclose(f); |
| - | return(atoi(p+strlen(pattern))); |
| + | char s[80]; |
| + | char *p; |
| + | FILE *f; |
| + | const char pattern[]="MemTotal:"; |
| + | |
| + | f=fopen("/proc/meminfo","r"); |
| + | while (NULL != fgets(s,79,f)) { |
| + | p=strstr(s, pattern); |
| + | if (NULL != p) { |
| + | fclose(f); |
| + | return(atoi(p+strlen(pattern))); |
| + | } |
| } | |
| - | } |
| - | return -1; |
| + | return -1; |
| } | |
| static void | |
| set_free_pages() | |
| { | |
| - | char s[80]; |
| + | char s[80]; |
| + | FILE *f; |
| + | |
| + | f=fopen("/proc/sys/vm/freepages","r"); |
| + | fgets(s,79,f); |
| + | if (atoi(s) < 32) { |
| + | fclose(f); |
| + | f=fopen("/proc/sys/vm/freepages","w"); |
| + | fprintf(f,"30\t40\t50\n"); |
| + | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); |
| + | } |
| + | fclose(f); |
| + | } |
| + | |
| + | static int |
| + | get_kernel_revision() |
| + | { |
| FILE *f; | |
| + | int major=0, minor=0, patch=0; |
| - | f=fopen("/proc/sys/vm/freepages","r"); |
| - | fgets(s,79,f); |
| - | if (atoi(s) < 32) { |
| - | fclose(f); |
| - | f=fopen("/proc/sys/vm/freepages","w"); |
| - | fprintf(f,"30\t40\t50\n"); |
| - | printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); |
| - | } |
| + | f = fopen("/proc/sys/kernel/osrelease","r"); |
| + | fscanf(f,"%d.%d.%d",&major,&minor,&patch); |
| fclose(f); | |
| + | return major*65536 + minor*256 + patch; |
| } | |
| + | |
| static void | |
| - | shutdown_system(int do_reboot) |
| + | shutdown_system(void) |
| { | |
| static const char * const umount_args[] = {"/bin/umount", "-a", "-n", 0}; | |
| + | static const char * const swapoff_args[] = {"/bin/swapoff", "-a", 0}; |
| + | message(console, "The system is going down NOW !!"); |
| sync(); | |
| /* Allow Ctrl-Alt-Del to reboot system. */ | |
| reboot(RB_ENABLE_CAD); | |
| @@ -208,59 +226,72 @@ shutdown_system(int do_reboot) | |
| message(console, "Sending SIGKILL to all processes.\r\n"); | |
| kill(-1, SIGKILL); | |
| sleep(1); | |
| + | waitfor(run("/bin/swapoff", swapoff_args, console, 0)); |
| waitfor(run("/bin/umount", umount_args, console, 0)); | |
| sync(); | |
| - | bdflush(1, 0); |
| - | sync(); |
| - | reboot(do_reboot ?RB_AUTOBOOT : RB_HALT_SYSTEM); |
| - | exit(0); |
| + | if (get_kernel_revision() <= 2*65536+2*256+11) { |
| + | /* Removed bdflush call, kupdate in kernels >2.2.11 */ |
| + | bdflush(1, 0); |
| + | sync(); |
| + | } |
| } | |
| static void | |
| halt_signal(int sig) | |
| { | |
| - | shutdown_system(0); |
| + | shutdown_system(); |
| + | message(console, "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); |
| + | reboot( RB_HALT_SYSTEM); |
| + | exit(0); |
| } | |
| static void | |
| reboot_signal(int sig) | |
| { | |
| - | shutdown_system(1); |
| + | shutdown_system(); |
| + | message(console, "Please stand by while rebooting the system.\r\n"); |
| + | reboot( RB_AUTOBOOT); |
| + | exit(0); |
| } | |
| static void | |
| - | exit_signal(int sig) |
| + | configure_terminals( int serial_cons, int single_user_mode ) |
| { | |
| - | |
| - | /* initrd doesn't work anyway */ |
| - | |
| - | shutdown_system(1); |
| - | |
| - | /* This is used on the initial ramdisk */ |
| - | |
| - | /* message(log, "Init exiting."); |
| - | exit(0); |
| - | */ |
| - | } |
| - | |
| - | void |
| - | configure_terminals( int serial_cons ) |
| - | { |
| - | //struct stat statbuf; |
| char *tty; | |
| + | struct serial_struct sr; |
| + | struct vt_stat vt; |
| + | |
| switch (serial_cons) { | |
| + | case -1: |
| + | /* 2.2 kernels: |
| + | * identify the real console backend and try to make use of it */ |
| + | if (ioctl(0,TIOCGSERIAL,&sr) == 0) { |
| + | sprintf( console, "/dev/ttyS%d", sr.line ); |
| + | serial_cons = sr.line+1; |
| + | } |
| + | else if (ioctl(0, VT_GETSTATE, &vt) == 0) { |
| + | sprintf( console, "/dev/tty%d", vt.v_active ); |
| + | serial_cons = 0; |
| + | } |
| + | else { |
| + | /* unknown backend: fallback to /dev/console */ |
| + | strcpy( console, "/dev/console" ); |
| + | serial_cons = 0; |
| + | } |
| + | break; |
| + | |
| case 1: | |
| - | strcpy( console, "/dev/ttyS0" ); |
| + | strcpy( console, "/dev/cua0" ); |
| break; | |
| case 2: | |
| - | strcpy( console, "/dev/ttyS1" ); |
| + | strcpy( console, "/dev/cua1" ); |
| break; | |
| default: | |
| tty = ttyname(0); | |
| if (tty) { | |
| strcpy( console, tty ); | |
| - | if (!strncmp( tty, "/dev/ttyS", 9 )) |
| + | if (!strncmp( tty, "/dev/cua", 8 )) |
| serial_cons=1; | |
| } | |
| else | |
| @@ -269,24 +300,33 @@ configure_terminals( int serial_cons ) | |
| } | |
| if (!first_terminal) | |
| first_terminal = console; | |
| - | if (serial_cons && !strncmp(term_ptr,"TERM=linux",10)) |
| - | term_ptr = "TERM=vt100"; |
| + | #if #cpu (sparc) |
| + | if (serial_cons > 0 && !strncmp(term_ptr,"TERM=linux",10)) |
| + | term_ptr = "TERM=vt100"; |
| + | #endif |
| + | if (serial_cons) { |
| + | /* disable other but the first terminal: |
| + | * VT is not initialized anymore on 2.2 kernel when booting from |
| + | * serial console, therefore modprobe is flooding the display with |
| + | * "can't locate module char-major-4" messages. */ |
| + | log = 0; |
| + | second_terminal = 0; |
| + | } |
| } | |
| extern int | |
| init_main(int argc, char * * argv) | |
| { | |
| - | static const char* const rc = "etc/rc"; |
| + | const char * rc_arguments[100]; |
| const char * arguments[100]; | |
| - | int run_rc = 1; |
| + | int run_rc = TRUE; |
| int j; | |
| int pid1 = 0; | |
| int pid2 = 0; | |
| - | int create_swap= -1; |
| struct stat statbuf; | |
| - | const char * tty_commands[2] = { "bin/sh", "bin/sh"}; |
| - | char swap[20]; |
| + | const char * tty_commands[3] = { "etc/init.d/rcS", "bin/sh"}; |
| int serial_console = 0; | |
| + | int retval; |
| /* | |
| * If I am started as /linuxrc instead of /sbin/init, I don't have the | |
| @@ -299,7 +339,7 @@ init_main(int argc, char * * argv) | |
| signal(SIGUSR1, halt_signal); | |
| signal(SIGUSR2, reboot_signal); | |
| signal(SIGINT, reboot_signal); | |
| - | signal(SIGTERM, exit_signal); |
| + | signal(SIGTERM, reboot_signal); |
| reboot(RB_DISABLE_CAD); | |
| @@ -307,7 +347,7 @@ init_main(int argc, char * * argv) | |
| for ( j = 1; j < argc; j++ ) { | |
| if ( strcmp(argv[j], "single") == 0 ) { | |
| - | run_rc = 0; |
| + | run_rc = FALSE; |
| tty_commands[0] = "bin/sh"; | |
| tty_commands[1] = 0; | |
| } | |
| @@ -341,7 +381,6 @@ init_main(int argc, char * * argv) | |
| term_ptr=__environ[j]; | |
| } | |
| } | |
| - | configure_terminals( serial_console ); |
| printf("mounting /proc ...\n"); | |
| if (mount("/proc","/proc","proc",0,0)) { | |
| @@ -349,81 +388,75 @@ init_main(int argc, char * * argv) | |
| } | |
| printf("\tdone.\n"); | |
| + | if (get_kernel_revision() >= 2*65536+1*256+71) { |
| + | /* if >= 2.1.71 kernel, /dev/console is not a symlink anymore: |
| + | * use it as primary console */ |
| + | serial_console=-1; |
| + | } |
| + | |
| + | /* Make sure /etc/init.d/rc exists */ |
| + | retval= stat(tty_commands[0],&statbuf); |
| + | if (retval) |
| + | run_rc = FALSE; |
| + | |
| + | configure_terminals( serial_console, run_rc); |
| + | |
| set_free_pages(); | |
| /* not enough memory to do anything useful*/ | |
| if (mem_total() < 2000) { | |
| - | int retval; |
| - | retval= stat("/etc/swappartition",&statbuf); |
| - | if (retval) { |
| - | printf("You do not have enough RAM, sorry.\n"); |
| - | while (1) { sleep(1);} |
| - | } else { /* everything OK */ |
| - | FILE *f; |
| - | |
| - | f=fopen("/etc/swappartition","r"); |
| - | fgets(swap,19,f); |
| - | fclose(f); |
| - | *(strstr(swap,"\n"))='\0'; |
| - | |
| - | if (swapon(swap,0)) { |
| - | perror("swapon failed\n"); |
| - | } else { |
| - | f=fopen("/etc/swaps","w"); |
| - | fprintf(f,"%s none swap rw 0 0",swap); |
| - | fclose(f); |
| - | create_swap = 0; |
| + | retval= stat("/etc/fstab",&statbuf); |
| + | if (retval) { |
| + | printf("You do not have enough RAM, sorry.\n"); |
| + | while (1) { sleep(1);} |
| + | } else { |
| + | /* Try to turn on swap */ |
| + | static const char * const swapon_args[] = {"/bin/swapon", "-a", 0}; |
| + | waitfor(run("/bin/swapon", swapon_args, console, 0)); |
| + | if (mem_total() < 2000) { |
| + | printf("You do not have enough RAM, sorry.\n"); |
| + | while (1) { sleep(1);} |
| + | } |
| } | |
| - | } |
| } | |
| /* | |
| * Don't modify **argv directly, it would show up in the "ps" display. | |
| * I don't want "init" to look like "rc". | |
| */ | |
| - | arguments[0] = rc; |
| + | rc_arguments[0] = tty_commands[0]; |
| for ( j = 1; j < argc; j++ ) { | |
| - | arguments[j] = argv[j]; |
| - | } |
| - | arguments[j] = 0; |
| - | |
| - | if ( run_rc ) { |
| - | run(rc, arguments, console, 0); |
| - | //waitfor(run(rc, arguments, console, 0)); |
| - | } |
| - | |
| - | if ( 0 == create_swap) { |
| - | if (unlink("/etc/swappartition")) { |
| - | perror("unlinking /etc/swappartition"); |
| - | } |
| + | rc_arguments[j] = argv[j]; |
| } | |
| + | rc_arguments[j] = 0; |
| arguments[0] = "-sh"; | |
| arguments[1] = 0; | |
| + | |
| + | /* Ok, now launch the rc script /etc/init.d/rcS and prepare to start up |
| + | * some VTs on tty1 and tty2 if somebody hits enter |
| + | */ |
| for ( ; ; ) { | |
| int wpid; | |
| int status; | |
| - | if ( pid1 == 0 && tty_commands[0] ) { |
| - | /* Ask before starting a shell */ |
| - | /* |
| - | arguments[0] = tty_commands[0]; |
| - | */ |
| - | pid1 = run(tty_commands[0], arguments, first_terminal, 1); |
| + | if ( pid1 == 0 && tty_commands[0] ) { |
| + | if ( run_rc == TRUE ) { |
| + | pid1 = run(tty_commands[0], rc_arguments, first_terminal, 0); |
| + | } else { |
| + | pid2 = run(tty_commands[1], arguments, first_terminal, 1); |
| + | } |
| } | |
| - | if ( pid2 == 0 && tty_commands[1] ) { |
| + | if ( pid2 == 0 && second_terminal && tty_commands[1] ) { |
| pid2 = run(tty_commands[1], arguments, second_terminal, 1); | |
| } | |
| wpid = wait(&status); | |
| - | if ( wpid > 0 ) { |
| - | /* DEBUGGING */ |
| + | if ( wpid > 0 && wpid != pid1) { |
| message(log, "pid %d exited, status=%x.\n", wpid, status); | |
| } | |
| - | if ( wpid == pid1 ) { |
| - | pid1 = 0; |
| - | } |
| - | if ( wpid == pid2 ) |
| + | if ( wpid == pid2 ) { |
| pid2 = 0; | |
| + | } |
| } | |
| } | |