More stuff
This commit is contained in:
parent
b0e9a709ba
commit
abc7d597cb
@ -71,7 +71,6 @@ int chmod_chown_chgrp_main(int argc, char **argv)
|
|||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
int recursiveFlag=FALSE;
|
int recursiveFlag=FALSE;
|
||||||
char *groupName;
|
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;
|
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 ) {
|
if ( whichApp == CHMOD_APP ) {
|
||||||
/* Find the specified modes */
|
/* Find the specified modes */
|
||||||
|
mode &= S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
|
||||||
if ( parse_mode(*argv, &mode) == FALSE ) {
|
if ( parse_mode(*argv, &mode) == FALSE ) {
|
||||||
fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv);
|
fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv);
|
||||||
exit( FALSE);
|
exit( FALSE);
|
||||||
|
267
init.c
267
init.c
@ -13,19 +13,21 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/kdaemon.h>
|
#include <sys/kdaemon.h>
|
||||||
#include <sys/swap.h>
|
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
#include <linux/serial.h> /* for serial_struct */
|
||||||
|
#include <sys/vt.h> /* for vt_stat */
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
const char init_usage[] = "Used internally by the system.";
|
static const char init_usage[] = "Used internally by the system.";
|
||||||
char console[16] = "";
|
static char console[16] = "";
|
||||||
const char * default_console = "/dev/tty1";
|
static const char* default_console = "/dev/tty2";
|
||||||
char * first_terminal = NULL;
|
static char* first_terminal = NULL;
|
||||||
const char * second_terminal = "/dev/tty2";
|
static const char* second_terminal = "/dev/tty2";
|
||||||
const char log[] = "/dev/tty3";
|
static const char* log = "/dev/tty3";
|
||||||
char * term_ptr = NULL;
|
static char* term_ptr = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
message(const char * terminal, const char * pattern, ...)
|
message(const char* terminal, const char * pattern, ...)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
FILE * con = 0;
|
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
|
* has switched consoles, the open will get the new console. If we kept
|
||||||
* the console open, we'd always print to the same one.
|
* 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) )
|
|| ((con = fdopen(fd, "w")) == NULL) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -158,44 +161,59 @@ run(const char* program, const char* const* arguments,
|
|||||||
static int
|
static int
|
||||||
mem_total()
|
mem_total()
|
||||||
{
|
{
|
||||||
char s[80];
|
char s[80];
|
||||||
char *p;
|
char *p;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
const char pattern[]="MemTotal:";
|
const char pattern[]="MemTotal:";
|
||||||
|
|
||||||
f=fopen("/proc/meminfo","r");
|
f=fopen("/proc/meminfo","r");
|
||||||
while (NULL != fgets(s,79,f)) {
|
while (NULL != fgets(s,79,f)) {
|
||||||
p=strstr(s, pattern);
|
p=strstr(s, pattern);
|
||||||
if (NULL != p) {
|
if (NULL != p) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return(atoi(p+strlen(pattern)));
|
return(atoi(p+strlen(pattern)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_free_pages()
|
set_free_pages()
|
||||||
{
|
{
|
||||||
char s[80];
|
char s[80];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f=fopen("/proc/sys/vm/freepages","r");
|
f=fopen("/proc/sys/vm/freepages","r");
|
||||||
fgets(s,79,f);
|
fgets(s,79,f);
|
||||||
if (atoi(s) < 32) {
|
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);
|
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/kernel/osrelease","r");
|
||||||
|
fscanf(f,"%d.%d.%d",&major,&minor,&patch);
|
||||||
|
fclose(f);
|
||||||
|
return major*65536 + minor*256 + patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
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 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();
|
sync();
|
||||||
/* Allow Ctrl-Alt-Del to reboot system. */
|
/* Allow Ctrl-Alt-Del to reboot system. */
|
||||||
reboot(RB_ENABLE_CAD);
|
reboot(RB_ENABLE_CAD);
|
||||||
@ -208,59 +226,72 @@ shutdown_system(int do_reboot)
|
|||||||
message(console, "Sending SIGKILL to all processes.\r\n");
|
message(console, "Sending SIGKILL to all processes.\r\n");
|
||||||
kill(-1, SIGKILL);
|
kill(-1, SIGKILL);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
waitfor(run("/bin/swapoff", swapoff_args, console, 0));
|
||||||
waitfor(run("/bin/umount", umount_args, console, 0));
|
waitfor(run("/bin/umount", umount_args, console, 0));
|
||||||
sync();
|
sync();
|
||||||
bdflush(1, 0);
|
if (get_kernel_revision() <= 2*65536+2*256+11) {
|
||||||
sync();
|
/* Removed bdflush call, kupdate in kernels >2.2.11 */
|
||||||
reboot(do_reboot ?RB_AUTOBOOT : RB_HALT_SYSTEM);
|
bdflush(1, 0);
|
||||||
exit(0);
|
sync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halt_signal(int sig)
|
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
|
static void
|
||||||
reboot_signal(int sig)
|
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
|
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;
|
char *tty;
|
||||||
|
struct serial_struct sr;
|
||||||
|
struct vt_stat vt;
|
||||||
|
|
||||||
|
|
||||||
switch (serial_cons) {
|
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:
|
case 1:
|
||||||
strcpy( console, "/dev/ttyS0" );
|
strcpy( console, "/dev/cua0" );
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
strcpy( console, "/dev/ttyS1" );
|
strcpy( console, "/dev/cua1" );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tty = ttyname(0);
|
tty = ttyname(0);
|
||||||
if (tty) {
|
if (tty) {
|
||||||
strcpy( console, tty );
|
strcpy( console, tty );
|
||||||
if (!strncmp( tty, "/dev/ttyS", 9 ))
|
if (!strncmp( tty, "/dev/cua", 8 ))
|
||||||
serial_cons=1;
|
serial_cons=1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -269,24 +300,33 @@ configure_terminals( int serial_cons )
|
|||||||
}
|
}
|
||||||
if (!first_terminal)
|
if (!first_terminal)
|
||||||
first_terminal = console;
|
first_terminal = console;
|
||||||
if (serial_cons && !strncmp(term_ptr,"TERM=linux",10))
|
#if #cpu (sparc)
|
||||||
term_ptr = "TERM=vt100";
|
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
|
extern int
|
||||||
init_main(int argc, char * * argv)
|
init_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
static const char* const rc = "etc/rc";
|
const char * rc_arguments[100];
|
||||||
const char * arguments[100];
|
const char * arguments[100];
|
||||||
int run_rc = 1;
|
int run_rc = TRUE;
|
||||||
int j;
|
int j;
|
||||||
int pid1 = 0;
|
int pid1 = 0;
|
||||||
int pid2 = 0;
|
int pid2 = 0;
|
||||||
int create_swap= -1;
|
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
const char * tty_commands[2] = { "bin/sh", "bin/sh"};
|
const char * tty_commands[3] = { "etc/init.d/rcS", "bin/sh"};
|
||||||
char swap[20];
|
|
||||||
int serial_console = 0;
|
int serial_console = 0;
|
||||||
|
int retval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If I am started as /linuxrc instead of /sbin/init, I don't have the
|
* 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(SIGUSR1, halt_signal);
|
||||||
signal(SIGUSR2, reboot_signal);
|
signal(SIGUSR2, reboot_signal);
|
||||||
signal(SIGINT, reboot_signal);
|
signal(SIGINT, reboot_signal);
|
||||||
signal(SIGTERM, exit_signal);
|
signal(SIGTERM, reboot_signal);
|
||||||
|
|
||||||
reboot(RB_DISABLE_CAD);
|
reboot(RB_DISABLE_CAD);
|
||||||
|
|
||||||
@ -307,7 +347,7 @@ init_main(int argc, char * * argv)
|
|||||||
|
|
||||||
for ( j = 1; j < argc; j++ ) {
|
for ( j = 1; j < argc; j++ ) {
|
||||||
if ( strcmp(argv[j], "single") == 0 ) {
|
if ( strcmp(argv[j], "single") == 0 ) {
|
||||||
run_rc = 0;
|
run_rc = FALSE;
|
||||||
tty_commands[0] = "bin/sh";
|
tty_commands[0] = "bin/sh";
|
||||||
tty_commands[1] = 0;
|
tty_commands[1] = 0;
|
||||||
}
|
}
|
||||||
@ -341,7 +381,6 @@ init_main(int argc, char * * argv)
|
|||||||
term_ptr=__environ[j];
|
term_ptr=__environ[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configure_terminals( serial_console );
|
|
||||||
|
|
||||||
printf("mounting /proc ...\n");
|
printf("mounting /proc ...\n");
|
||||||
if (mount("/proc","/proc","proc",0,0)) {
|
if (mount("/proc","/proc","proc",0,0)) {
|
||||||
@ -349,81 +388,75 @@ init_main(int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
printf("\tdone.\n");
|
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();
|
set_free_pages();
|
||||||
|
|
||||||
/* not enough memory to do anything useful*/
|
/* not enough memory to do anything useful*/
|
||||||
if (mem_total() < 2000) {
|
if (mem_total() < 2000) {
|
||||||
int retval;
|
retval= stat("/etc/fstab",&statbuf);
|
||||||
retval= stat("/etc/swappartition",&statbuf);
|
if (retval) {
|
||||||
if (retval) {
|
printf("You do not have enough RAM, sorry.\n");
|
||||||
printf("You do not have enough RAM, sorry.\n");
|
while (1) { sleep(1);}
|
||||||
while (1) { sleep(1);}
|
} else {
|
||||||
} else { /* everything OK */
|
/* Try to turn on swap */
|
||||||
FILE *f;
|
static const char * const swapon_args[] = {"/bin/swapon", "-a", 0};
|
||||||
|
waitfor(run("/bin/swapon", swapon_args, console, 0));
|
||||||
f=fopen("/etc/swappartition","r");
|
if (mem_total() < 2000) {
|
||||||
fgets(swap,19,f);
|
printf("You do not have enough RAM, sorry.\n");
|
||||||
fclose(f);
|
while (1) { sleep(1);}
|
||||||
*(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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't modify **argv directly, it would show up in the "ps" display.
|
* Don't modify **argv directly, it would show up in the "ps" display.
|
||||||
* I don't want "init" to look like "rc".
|
* I don't want "init" to look like "rc".
|
||||||
*/
|
*/
|
||||||
arguments[0] = rc;
|
rc_arguments[0] = tty_commands[0];
|
||||||
for ( j = 1; j < argc; j++ ) {
|
for ( j = 1; j < argc; j++ ) {
|
||||||
arguments[j] = argv[j];
|
rc_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] = 0;
|
||||||
|
|
||||||
arguments[0] = "-sh";
|
arguments[0] = "-sh";
|
||||||
arguments[1] = 0;
|
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 ( ; ; ) {
|
for ( ; ; ) {
|
||||||
int wpid;
|
int wpid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if ( pid1 == 0 && tty_commands[0] ) {
|
if ( pid1 == 0 && tty_commands[0] ) {
|
||||||
/* Ask before starting a shell */
|
if ( run_rc == TRUE ) {
|
||||||
/*
|
pid1 = run(tty_commands[0], rc_arguments, first_terminal, 0);
|
||||||
arguments[0] = tty_commands[0];
|
} else {
|
||||||
*/
|
pid2 = run(tty_commands[1], arguments, first_terminal, 1);
|
||||||
pid1 = run(tty_commands[0], 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);
|
pid2 = run(tty_commands[1], arguments, second_terminal, 1);
|
||||||
}
|
}
|
||||||
wpid = wait(&status);
|
wpid = wait(&status);
|
||||||
if ( wpid > 0 ) {
|
if ( wpid > 0 && wpid != pid1) {
|
||||||
/* DEBUGGING */
|
|
||||||
message(log, "pid %d exited, status=%x.\n", wpid, status);
|
message(log, "pid %d exited, status=%x.\n", wpid, status);
|
||||||
}
|
}
|
||||||
if ( wpid == pid1 ) {
|
if ( wpid == pid2 ) {
|
||||||
pid1 = 0;
|
|
||||||
}
|
|
||||||
if ( wpid == pid2 )
|
|
||||||
pid2 = 0;
|
pid2 = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
267
init/init.c
267
init/init.c
@ -13,19 +13,21 @@
|
|||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
#include <sys/kdaemon.h>
|
#include <sys/kdaemon.h>
|
||||||
#include <sys/swap.h>
|
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
#include <linux/serial.h> /* for serial_struct */
|
||||||
|
#include <sys/vt.h> /* for vt_stat */
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
const char init_usage[] = "Used internally by the system.";
|
static const char init_usage[] = "Used internally by the system.";
|
||||||
char console[16] = "";
|
static char console[16] = "";
|
||||||
const char * default_console = "/dev/tty1";
|
static const char* default_console = "/dev/tty2";
|
||||||
char * first_terminal = NULL;
|
static char* first_terminal = NULL;
|
||||||
const char * second_terminal = "/dev/tty2";
|
static const char* second_terminal = "/dev/tty2";
|
||||||
const char log[] = "/dev/tty3";
|
static const char* log = "/dev/tty3";
|
||||||
char * term_ptr = NULL;
|
static char* term_ptr = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
message(const char * terminal, const char * pattern, ...)
|
message(const char* terminal, const char * pattern, ...)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
FILE * con = 0;
|
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
|
* has switched consoles, the open will get the new console. If we kept
|
||||||
* the console open, we'd always print to the same one.
|
* 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) )
|
|| ((con = fdopen(fd, "w")) == NULL) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -158,44 +161,59 @@ run(const char* program, const char* const* arguments,
|
|||||||
static int
|
static int
|
||||||
mem_total()
|
mem_total()
|
||||||
{
|
{
|
||||||
char s[80];
|
char s[80];
|
||||||
char *p;
|
char *p;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
const char pattern[]="MemTotal:";
|
const char pattern[]="MemTotal:";
|
||||||
|
|
||||||
f=fopen("/proc/meminfo","r");
|
f=fopen("/proc/meminfo","r");
|
||||||
while (NULL != fgets(s,79,f)) {
|
while (NULL != fgets(s,79,f)) {
|
||||||
p=strstr(s, pattern);
|
p=strstr(s, pattern);
|
||||||
if (NULL != p) {
|
if (NULL != p) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return(atoi(p+strlen(pattern)));
|
return(atoi(p+strlen(pattern)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_free_pages()
|
set_free_pages()
|
||||||
{
|
{
|
||||||
char s[80];
|
char s[80];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f=fopen("/proc/sys/vm/freepages","r");
|
f=fopen("/proc/sys/vm/freepages","r");
|
||||||
fgets(s,79,f);
|
fgets(s,79,f);
|
||||||
if (atoi(s) < 32) {
|
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);
|
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/kernel/osrelease","r");
|
||||||
|
fscanf(f,"%d.%d.%d",&major,&minor,&patch);
|
||||||
|
fclose(f);
|
||||||
|
return major*65536 + minor*256 + patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
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 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();
|
sync();
|
||||||
/* Allow Ctrl-Alt-Del to reboot system. */
|
/* Allow Ctrl-Alt-Del to reboot system. */
|
||||||
reboot(RB_ENABLE_CAD);
|
reboot(RB_ENABLE_CAD);
|
||||||
@ -208,59 +226,72 @@ shutdown_system(int do_reboot)
|
|||||||
message(console, "Sending SIGKILL to all processes.\r\n");
|
message(console, "Sending SIGKILL to all processes.\r\n");
|
||||||
kill(-1, SIGKILL);
|
kill(-1, SIGKILL);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
waitfor(run("/bin/swapoff", swapoff_args, console, 0));
|
||||||
waitfor(run("/bin/umount", umount_args, console, 0));
|
waitfor(run("/bin/umount", umount_args, console, 0));
|
||||||
sync();
|
sync();
|
||||||
bdflush(1, 0);
|
if (get_kernel_revision() <= 2*65536+2*256+11) {
|
||||||
sync();
|
/* Removed bdflush call, kupdate in kernels >2.2.11 */
|
||||||
reboot(do_reboot ?RB_AUTOBOOT : RB_HALT_SYSTEM);
|
bdflush(1, 0);
|
||||||
exit(0);
|
sync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
halt_signal(int sig)
|
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
|
static void
|
||||||
reboot_signal(int sig)
|
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
|
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;
|
char *tty;
|
||||||
|
struct serial_struct sr;
|
||||||
|
struct vt_stat vt;
|
||||||
|
|
||||||
|
|
||||||
switch (serial_cons) {
|
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:
|
case 1:
|
||||||
strcpy( console, "/dev/ttyS0" );
|
strcpy( console, "/dev/cua0" );
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
strcpy( console, "/dev/ttyS1" );
|
strcpy( console, "/dev/cua1" );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tty = ttyname(0);
|
tty = ttyname(0);
|
||||||
if (tty) {
|
if (tty) {
|
||||||
strcpy( console, tty );
|
strcpy( console, tty );
|
||||||
if (!strncmp( tty, "/dev/ttyS", 9 ))
|
if (!strncmp( tty, "/dev/cua", 8 ))
|
||||||
serial_cons=1;
|
serial_cons=1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -269,24 +300,33 @@ configure_terminals( int serial_cons )
|
|||||||
}
|
}
|
||||||
if (!first_terminal)
|
if (!first_terminal)
|
||||||
first_terminal = console;
|
first_terminal = console;
|
||||||
if (serial_cons && !strncmp(term_ptr,"TERM=linux",10))
|
#if #cpu (sparc)
|
||||||
term_ptr = "TERM=vt100";
|
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
|
extern int
|
||||||
init_main(int argc, char * * argv)
|
init_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
static const char* const rc = "etc/rc";
|
const char * rc_arguments[100];
|
||||||
const char * arguments[100];
|
const char * arguments[100];
|
||||||
int run_rc = 1;
|
int run_rc = TRUE;
|
||||||
int j;
|
int j;
|
||||||
int pid1 = 0;
|
int pid1 = 0;
|
||||||
int pid2 = 0;
|
int pid2 = 0;
|
||||||
int create_swap= -1;
|
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
const char * tty_commands[2] = { "bin/sh", "bin/sh"};
|
const char * tty_commands[3] = { "etc/init.d/rcS", "bin/sh"};
|
||||||
char swap[20];
|
|
||||||
int serial_console = 0;
|
int serial_console = 0;
|
||||||
|
int retval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If I am started as /linuxrc instead of /sbin/init, I don't have the
|
* 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(SIGUSR1, halt_signal);
|
||||||
signal(SIGUSR2, reboot_signal);
|
signal(SIGUSR2, reboot_signal);
|
||||||
signal(SIGINT, reboot_signal);
|
signal(SIGINT, reboot_signal);
|
||||||
signal(SIGTERM, exit_signal);
|
signal(SIGTERM, reboot_signal);
|
||||||
|
|
||||||
reboot(RB_DISABLE_CAD);
|
reboot(RB_DISABLE_CAD);
|
||||||
|
|
||||||
@ -307,7 +347,7 @@ init_main(int argc, char * * argv)
|
|||||||
|
|
||||||
for ( j = 1; j < argc; j++ ) {
|
for ( j = 1; j < argc; j++ ) {
|
||||||
if ( strcmp(argv[j], "single") == 0 ) {
|
if ( strcmp(argv[j], "single") == 0 ) {
|
||||||
run_rc = 0;
|
run_rc = FALSE;
|
||||||
tty_commands[0] = "bin/sh";
|
tty_commands[0] = "bin/sh";
|
||||||
tty_commands[1] = 0;
|
tty_commands[1] = 0;
|
||||||
}
|
}
|
||||||
@ -341,7 +381,6 @@ init_main(int argc, char * * argv)
|
|||||||
term_ptr=__environ[j];
|
term_ptr=__environ[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configure_terminals( serial_console );
|
|
||||||
|
|
||||||
printf("mounting /proc ...\n");
|
printf("mounting /proc ...\n");
|
||||||
if (mount("/proc","/proc","proc",0,0)) {
|
if (mount("/proc","/proc","proc",0,0)) {
|
||||||
@ -349,81 +388,75 @@ init_main(int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
printf("\tdone.\n");
|
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();
|
set_free_pages();
|
||||||
|
|
||||||
/* not enough memory to do anything useful*/
|
/* not enough memory to do anything useful*/
|
||||||
if (mem_total() < 2000) {
|
if (mem_total() < 2000) {
|
||||||
int retval;
|
retval= stat("/etc/fstab",&statbuf);
|
||||||
retval= stat("/etc/swappartition",&statbuf);
|
if (retval) {
|
||||||
if (retval) {
|
printf("You do not have enough RAM, sorry.\n");
|
||||||
printf("You do not have enough RAM, sorry.\n");
|
while (1) { sleep(1);}
|
||||||
while (1) { sleep(1);}
|
} else {
|
||||||
} else { /* everything OK */
|
/* Try to turn on swap */
|
||||||
FILE *f;
|
static const char * const swapon_args[] = {"/bin/swapon", "-a", 0};
|
||||||
|
waitfor(run("/bin/swapon", swapon_args, console, 0));
|
||||||
f=fopen("/etc/swappartition","r");
|
if (mem_total() < 2000) {
|
||||||
fgets(swap,19,f);
|
printf("You do not have enough RAM, sorry.\n");
|
||||||
fclose(f);
|
while (1) { sleep(1);}
|
||||||
*(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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't modify **argv directly, it would show up in the "ps" display.
|
* Don't modify **argv directly, it would show up in the "ps" display.
|
||||||
* I don't want "init" to look like "rc".
|
* I don't want "init" to look like "rc".
|
||||||
*/
|
*/
|
||||||
arguments[0] = rc;
|
rc_arguments[0] = tty_commands[0];
|
||||||
for ( j = 1; j < argc; j++ ) {
|
for ( j = 1; j < argc; j++ ) {
|
||||||
arguments[j] = argv[j];
|
rc_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] = 0;
|
||||||
|
|
||||||
arguments[0] = "-sh";
|
arguments[0] = "-sh";
|
||||||
arguments[1] = 0;
|
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 ( ; ; ) {
|
for ( ; ; ) {
|
||||||
int wpid;
|
int wpid;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if ( pid1 == 0 && tty_commands[0] ) {
|
if ( pid1 == 0 && tty_commands[0] ) {
|
||||||
/* Ask before starting a shell */
|
if ( run_rc == TRUE ) {
|
||||||
/*
|
pid1 = run(tty_commands[0], rc_arguments, first_terminal, 0);
|
||||||
arguments[0] = tty_commands[0];
|
} else {
|
||||||
*/
|
pid2 = run(tty_commands[1], arguments, first_terminal, 1);
|
||||||
pid1 = run(tty_commands[0], 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);
|
pid2 = run(tty_commands[1], arguments, second_terminal, 1);
|
||||||
}
|
}
|
||||||
wpid = wait(&status);
|
wpid = wait(&status);
|
||||||
if ( wpid > 0 ) {
|
if ( wpid > 0 && wpid != pid1) {
|
||||||
/* DEBUGGING */
|
|
||||||
message(log, "pid %d exited, status=%x.\n", wpid, status);
|
message(log, "pid %d exited, status=%x.\n", wpid, status);
|
||||||
}
|
}
|
||||||
if ( wpid == pid1 ) {
|
if ( wpid == pid2 ) {
|
||||||
pid1 = 0;
|
|
||||||
}
|
|
||||||
if ( wpid == pid2 )
|
|
||||||
pid2 = 0;
|
pid2 = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user