/* configuration-dependent initialization */ int main_configure(char *arg1, char *arg2) { if(options_cmdline(arg1, arg2)) return 1; options_apply(); str_canary_init(); /* needs prng initialization from options_cmdline */ #if !defined(USE_WIN32) && !defined(__vms) /* syslog_open() must be called before change_root() * to be able to access /dev/log socket */ syslog_open(); #endif /* !defined(USE_WIN32) && !defined(__vms) */ if(bind_ports()) return 1; #ifdef HAVE_CHROOT /* change_root() must be called before drop_privileges() * since chroot() needs root privileges */ if(change_root()) return 1; #endif /* HAVE_CHROOT */ if(drop_privileges(1)) return 1; /* log_open() must be be called after drop_privileges() * or logfile rotation won't be possible */ /* log_open() must be be called before daemonize() * since daemonize() invalidates stderr */ if(log_open()) return 1; #ifndef USE_FORK num_clients=0; /* the first valid config */ #endif return 0; }
/* * process_root_flag - chroot if given the --root option * * This shall be called before accessing the passwd, group, shadow, * gshadow, useradd's default, login.defs files (non exhaustive list) * or authenticating the caller. * * The audit, syslog, or locale files shall be open before */ extern void process_root_flag (const char* short_opt, int argc, char **argv) { /* * Parse the command line options. */ int i; const char *newroot = NULL; for (i = 0; i < argc; i++) { if ( (strcmp (argv[i], "--root") == 0) || (strcmp (argv[i], short_opt) == 0)) { if (NULL != newroot) { fprintf (stderr, _("%s: multiple --root options\n"), Prog); exit (E_BAD_ARG); } if (i + 1 == argc) { fprintf (stderr, _("%s: option '%s' requires an argument\n"), Prog, argv[i]); exit (E_BAD_ARG); } newroot = argv[i + 1]; } } if (NULL != newroot) { change_root (newroot); } }
/* configuration-dependent initialization */ int main_configure(char *arg1, char *arg2) { if(parse_commandline(arg1, arg2)) return 1; str_canary_init(); /* needs prng initialization from parse_commandline */ #if !defined(USE_WIN32) && !defined(__vms) /* syslog_open() must be called before change_root() * to be able to access /dev/log socket */ syslog_open(); #endif /* !defined(USE_WIN32) && !defined(__vms) */ if(bind_ports()) return 1; #ifdef HAVE_CHROOT /* change_root() must be called before drop_privileges() * since chroot() needs root privileges */ if(change_root()) return 1; #endif /* HAVE_CHROOT */ #if !defined(USE_WIN32) && !defined(__vms) && !defined(USE_OS2) if(drop_privileges(1)) return 1; #endif /* standard Unix */ /* log_open() must be be called after drop_privileges() * or logfile rotation won't be possible */ /* log_open() must be be called before daemonize() * since daemonize() invalidates stderr */ log_open(); return 0; }
/* Process command line args, create the bound socket, * spawn child (worker) processes, and wait for them all to die * (which they shouldn't!) */ int main(int argc, char **argv) { parse_cli(argc, argv); if (OPTIONS.SYSLOG) openlog("stud", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON); signal(SIGPIPE, SIG_IGN); listener_socket = create_main_socket(); struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; const int gai_err = getaddrinfo(OPTIONS.BACK_IP, OPTIONS.BACK_PORT, &hints, &backaddr); if (gai_err != 0) { ERR("{getaddrinfo}: [%s]", gai_strerror(gai_err)); exit(1); } /* load certificate, pass to handle_connections */ SSL_CTX * ctx = init_openssl(); master_pid = getpid(); if (OPTIONS.CHROOT && OPTIONS.CHROOT[0]) change_root(); if (OPTIONS.UID || OPTIONS.GID) drop_privileges(); for (child_num=0; child_num < OPTIONS.NCORES; child_num++) { int pid = fork(); if (pid == -1) { ERR("{core} fork() failed! Goodbye cruel world!\n"); exit(1); } else if (pid == 0) // child goto handle; } int child_status; int dead_child_pid = wait(&child_status); ERR("{core} A child (%d) died! This should not happen! Goodbye cruel world!\n", dead_child_pid); kill(0, SIGTERM); exit(2); handle: handle_connections(ctx); return 0; }
void *grow_tree (tree_s *tree, unint len) { void *root; branch_s *branch; int rc; FN; if (root_blkno(tree)) { root = bget(tree->t_dev, root_blkno(tree)); if (!root) return NULL; switch (type(root)) { case LEAF: if (!leaf_is_full(root, len)) { return root; } break; case BRANCH: if (!branch_is_full(root)) { return root; } break; default: bput(root); error("Bad block"); exit(1); break; } branch = new_branch(tree->t_dev); branch->br_first = bblkno(root); bput(root); root = branch; } else { root = new_leaf(tree->t_dev); } rc = change_root(tree, root); if (rc) { error("Couldn't grow tree"); return NULL; } return root; }
static void *grow_tree (tree_s *tree, unint size) { head_s *head; branch_s *branch; int rc; FN; if (root(tree)) { head = tau_bget(tree_inode(tree), root(tree)); if (!head) return NULL; switch (head->h_magic) { case LEAF: if (!leaf_is_full((leaf_s *)head, size)) { return head; } break; case BRANCH: if (!branch_is_full((branch_s *)head)) { return head; } break; default: tau_bput(head); eprintk("Bad block"); BUG(); break; } branch = new_branch(tree); branch->br_first = tau_bnum(head); tau_bput(head); head = (head_s *)branch; } else { head = (head_s *)new_leaf(tree); } rc = change_root(tree, head); if (rc) { error("Couldn't grow tree"); return NULL; } return head; }
void os_setup_post(void) { int fd = 0; if (daemonize) { if (chdir("/")) { error_report("not able to chdir to /: %s", strerror(errno)); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) { exit(1); } } change_root(); change_process_uid(); if (daemonize) { uint8_t status = 0; ssize_t len; dup2(fd, 0); dup2(fd, 1); /* In case -D is given do not redirect stderr to /dev/null */ if (!qemu_logfile) { dup2(fd, 2); } close(fd); do { len = write(daemon_pipe, &status, 1); } while (len < 0 && errno == EINTR); if (len != 1) { exit(1); } } }
void os_setup_post(void) { int fd = 0; if (daemonize) { uint8_t status = 0; ssize_t len; again1: len = write(fds[1], &status, 1); LOGV("%s:%s=%d, write(), len = %d", __FILE__, __func__, status, len); if (len == -1 && (errno == EINTR)) goto again1; if (len != 1) exit(1); if (chdir("/")) { perror("not able to chdir to /"); exit(1); } TFR(fd = qemu_open("/dev/null", O_RDWR)); if (fd == -1) exit(1); } change_root(); change_process_uid(); if (daemonize) { dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); close(fd); } }
void *grow_tree (tree_s *tree, unint size) { void *node; branch_s *branch; int rc; FN; node = root(tree); if (node) { switch (magic(node)) { case LEAF: if (!leaf_is_full(node, size)) { return node; } break; case BRANCH: if (!branch_is_full(node)) { return node; } break; default: eprintf("Bad node"); break; } branch = new_branch(tree); branch->br_first = node; node = branch; } else { node = new_leaf(tree); } rc = change_root(tree, node); if (rc) { eprintf("Couldn't grow tree"); return NULL; } return node; }
/* argc, *argv[] assume usual meaning */ int main(int argc, char *argv[]) { char buf[BUFSIZE+1]; /* temporary buffer for storing the line input */ char pwd[BUFSIZE+1]; /* stores the present working directory */ char errstr[BUFSIZE+1]; /* stores the error occured */ char *tok[ARGNUM]; /* for storing the tokens */ int n, i; /* n will store the no. of tokens starting from 0 */ int returnval; /* used by wait() */ // n = ARGNUM-1; signal(SIGINT, SIG_IGN); signal(SIGINT, ignore_line); /* ignore current line on Ctrl-C */ while (1) { /* very important: */ /* reset the state to -1 */ state = -1; /* reset the token array */ for (i = 0; i <= n; i++) tok[i] = "\0"; /* reset the buffer */ for (i = 0; i <= BUFSIZE; i++) buf[i] = '\0'; /* print the prompt with the pwd */ set_prompt(); /* read input from STDIN */ read(STDIN_FILENO, buf, BUFSIZE); #ifdef DEBUG { fprintf(stderr, "buf: %s", buf); /* no newline is given because buf includes newline from read() */ } #endif /* extract the first token (the command)*/ tok[0] = strtok(buf, DELIMS); n = 1; /* extract the remaining tokens */ while ((tok[n] = strtok(NULL, DELIMS)) != NULL) /* sending NULL in subsequent strtok calls will return the remaining tokens */ n++; tok[n] = NULL; /* very importatnt to set the last token as NULL, for specifying the end of tokens */ n--; /* remove the extra 1 that is added to n */ /* if debug mode is on, print all tokens */ #ifdef DEBUG { i = 0; fprintf(stderr, "tokenizing buf\n"); fprintf(stderr, "n: %d\n", n); while (i <= n) { fprintf(stderr, "tok[%d]: %s\n", i, tok[i]); i++; } fprintf(stderr, "looking up on token: %s\n", tok[0]); } #endif /* lookup on the first token */ for (i = _EXIT; i < CMDNUM; i++) if (strcmp(tok[0], cmd[i]) == 0) state = i; /* set the state to its command equivalent */ /* switch to a state (execute a command) based on the token */ switch (state) { case _EXIT: return 0; case _SYS: switch (fork()) /* is this the child process? */ { case 0: returnval = execvp(tok[1], &tok[1]); /* tok[1] because tok[0] would contain sys */ exit(returnval); /* child always exits with 200 on success */ default: wait(&returnval); } /* wait till the first child process dies */ wait(&returnval); break; case _LS: list_dir(n, tok); break; case _ECHO: for(i = 1; i <= n; i++) fprintf(stdout, "%s ", tok[i]); fprintf(stdout, "\n"); break; case _PWD: getcwd(pwd, BUFSIZE); fprintf(stdout, "%s\n", pwd); break; case _CLEAR: system(tok[0]); break; case _CD: /* if no argument is given, change to home directory */ if (n == 0) if (chdir((char *)getenv("HOME")) == -1) perror("cd"); else { if (chdir(tok[1]) == -1) perror("cd");} break; case _CAT: cat(n, tok); break; case _MKDIR: create_dir(n, tok); break; case _RMDIR: remove_dir(n, tok); break; case _HELP: /* print a list of commands with basic usage help */ fprintf(stdout, "You are running Dhanu-sh\nType 'help (command)' for more details\n"); if (n == 0) { fprintf(stdout, "The following commands are available:\n"); for (i = 0; i < CMDNUM; i++) fprintf(stdout, " %s\n", cmd[i]); } else { for (i = 0; i < CMDNUM; i++) if (strcmp(cmd[i], tok[1]) == 0) fprintf(stdout, " %s usage: %s\n%s \n", cmd[i], usage[i], desc[i]); } break; case _RM: remove_file(n, tok); break; case _CHROOT: change_root(n, tok); break; case _MV: move(n, tok); break; case _CP: copy_file(n, tok); break; default: switch (fork()) { case 0: returnval = execvp(tok[0], &tok[0]); fprintf(stderr, "%s: No such file or directory\n", tok[0]); exit(returnval); default: wait(&returnval); } } } return 0; }
static int init(void * unused) { int pid,i; #ifdef CONFIG_BLK_DEV_INITRD int real_root_mountflags; #endif /* Launch bdflush from here, instead of the old syscall way. */ kernel_thread(bdflush, NULL, 0); /* Start the background pageout daemon. */ kswapd_setup(); kernel_thread(kswapd, NULL, 0); #ifdef CONFIG_BLK_DEV_INITRD real_root_dev = ROOT_DEV; real_root_mountflags = root_mountflags; if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY; else mount_initrd =0; #endif setup(); #ifdef __SMP__ /* * With the devices probed and setup we can * now enter SMP mode. */ smp_begin(); #endif #ifdef CONFIG_UMSDOS_FS { /* When mounting a umsdos fs as root, we detect the pseudo_root (/linux) and initialise it here. pseudo_root is defined in fs/umsdos/inode.c */ extern struct inode *pseudo_root; if (pseudo_root != NULL){ current->fs->root = pseudo_root; current->fs->pwd = pseudo_root; } } #endif #ifdef CONFIG_BLK_DEV_INITRD root_mountflags = real_root_mountflags; if (mount_initrd && ROOT_DEV != real_root_dev && ROOT_DEV == MKDEV(RAMDISK_MAJOR,0)) { int error; pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); if (pid>0) while (pid != wait(&i)); if (real_root_dev != MKDEV(RAMDISK_MAJOR, 0)) { error = change_root(real_root_dev,"/initrd"); if (error) printk(KERN_ERR "Change root to /initrd: " "error %d\n",error); } } #endif /* * This keeps serial console MUCH cleaner, but does assume * the console driver checks there really is a video device * attached (Sparc effectively does). */ if ((open("/dev/tty1",O_RDWR,0) < 0) && (open("/dev/ttyS0",O_RDWR,0) < 0)) printk("Unable to open an initial console.\n"); (void) dup(0); (void) dup(0); if (!execute_command) { execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/sbin/init",argv_init,envp_init); /* if this fails, fall through to original stuff */ pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD); if (pid>0) while (pid != wait(&i)) /* nothing */; } while (1) { pid = kernel_thread(do_shell, execute_command ? execute_command : "/bin/sh", SIGCHLD); if (pid < 0) { printf("Fork failed in init\n\r"); continue; } while (1) if (pid == wait(&i)) break; printf("\n\rchild %d died with code %04x\n\r",pid,i); sync(); } return -1; }
/* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */ static void __init do_basic_setup(void) { #ifdef CONFIG_BLK_DEV_INITRD int real_root_mountflags; #endif /* * Tell the world that we're going to be the grim * reaper of innocent orphaned children. * * We don't want people to have to make incorrect * assumptions about where in the task array this * can be found. */ child_reaper = current; #if defined(CONFIG_MTRR) /* Do this after SMP initialization */ /* * We should probably create some architecture-dependent "fixup after * everything is up" style function where this would belong better * than in init/main.c.. */ mtrr_init(); #endif #ifdef CONFIG_SYSCTL sysctl_init(); #endif /* * Ok, at this point all CPU's should be initialized, so * we can start looking into devices.. */ #ifdef CONFIG_PCI pci_init(); #endif #ifdef CONFIG_SBUS sbus_init(); #endif #if defined(CONFIG_PPC) powermac_init(); #endif #ifdef CONFIG_MCA mca_init(); #endif #ifdef CONFIG_ARCH_ACORN ecard_init(); #endif #ifdef CONFIG_ZORRO zorro_init(); #endif #ifdef CONFIG_DIO dio_init(); #endif #ifdef CONFIG_TC tc_init(); #endif #ifdef CONFIG_PS2 ps2_dev_init(); /* PlayStation 2 devices */ #endif /* Networking initialization needs a process context */ sock_init(); /* Launch bdflush from here, instead of the old syscall way. */ kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); /* Start the background pageout daemon. */ kswapd_setup(); kernel_thread(kswapd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); #if CONFIG_AP1000 /* Start the async paging daemon. */ { extern int asyncd(void *); kernel_thread(asyncd, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); } #endif #ifdef CONFIG_BLK_DEV_INITRD real_root_dev = ROOT_DEV; real_root_mountflags = root_mountflags; if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY; else mount_initrd =0; #endif /* Set up devices .. */ device_setup(); /* .. executable formats .. */ binfmt_setup(); /* .. filesystems .. */ filesystem_setup(); /* Mount the root filesystem.. */ mount_root(); #ifdef CONFIG_UMSDOS_FS { /* When mounting a umsdos fs as root, we detect the pseudo_root (/linux) and initialise it here. pseudo_root is defined in fs/umsdos/inode.c */ extern struct inode *pseudo_root; if (pseudo_root != NULL){ current->fs->root = pseudo_root->i_sb->s_root; current->fs->pwd = pseudo_root->i_sb->s_root; } } #endif #ifdef CONFIG_BLK_DEV_INITRD root_mountflags = real_root_mountflags; if (mount_initrd && ROOT_DEV != real_root_dev && MAJOR(ROOT_DEV) == RAMDISK_MAJOR && MINOR(ROOT_DEV) == 0) { int error; int i, pid; pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); if (pid>0) while (pid != wait(&i)); if (MAJOR(real_root_dev) != RAMDISK_MAJOR || MINOR(real_root_dev) != 0) { error = change_root(real_root_dev,"/initrd"); if (error) printk(KERN_ERR "Change root to /initrd: " "error %d\n",error); } } #endif }