⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 linux 安装程序
💻 C
📖 第 1 页 / 共 2 页
字号:
        snprintf(devname, 63, "/dev/%s", devnodes[i].devname);        switch (devnodes[i].type) {        case DIRTYPE:            if (mkdir(devname, devnodes[i].perms) < 0) {                fprintf(stderr, "Unable to create directory %s: %s\n",                         devname, strerror(errno));            }            break;        case CHARDEV:            type = S_IFCHR;            break;        case BLOCKDEV:            type = S_IFBLK;            break;        }        if (type == -1) continue;        if (mknod(devname, type | devnodes[i].perms,                   makedev(devnodes[i].major, devnodes[i].minor)) < 0)            fprintf(stderr, "Unable to create device %s: %s\n", devname,                     strerror(errno));    }}static void termReset(void) {    /* change to tty1 */    ioctl(0, VT_ACTIVATE, 1);    /* reset terminal */    tcsetattr(0, TCSANOW, &ts);    /* Shift in, default color, move down 100 lines */    /* ^O        ^[[0m          ^[[100E */    printf("\017\033[0m\033[100E\n");}/* reboot handler */static void sigintHandler(int signum) {    termReset();    shutDown(getNoKill(), 1, 0);}/* halt handler */static void sigUsr1Handler(int signum) {    termReset();    shutDown(getNoKill(), 0, 0);}/* poweroff handler */static void sigUsr2Handler(int signum) {    termReset();    shutDown(getNoKill(), 0, 1);}static int getNoKill(void) {    int fd;    int len;    char buf[1024];    /* look through /proc/cmdline for special options */    if ((fd = open("/proc/cmdline", O_RDONLY,0)) > 0) {        len = read(fd, buf, sizeof(buf) - 1);        close(fd);        if (len > 0 && mystrstr(buf, "nokill"))            return 1;    }    return 0;}static int getInitPid(void) {    int fd = 0, pid = -1, ret;    char * buf = calloc(1, 10);    fd = open("/var/run/init.pid", O_RDONLY);    if (fd < 0) {        fprintf(stderr, "Unable to find pid of init!!!\n");        return -1;    }    ret = read(fd, buf, 9);    close(fd);    ret = sscanf(buf, "%d", &pid);    return pid;}int main(int argc, char **argv) {    pid_t installpid, childpid;    int waitStatus;    int fd = -1;    int doReboot = 0;    int doShutdown =0;    int isSerial = 0;    char * console = NULL;    int noKill = 0;    char * argvc[15];    char ** argvp = argvc;    char twelve = 12;    struct serial_struct si;    int i, disable_keys;    if (!strncmp(basename(argv[0]), "poweroff", 8)) {        printf("Running poweroff...\n");        fd = getInitPid();        if (fd > 0)            kill(fd, SIGUSR2);        exit(0);    } else if (!strncmp(basename(argv[0]), "halt", 4)) {        printf("Running halt...\n");        fd = getInitPid();        if (fd > 0)            kill(fd, SIGUSR1);        exit(0);    } else if (!strncmp(basename(argv[0]), "reboot", 6)) {        printf("Running reboot...\n");        fd = getInitPid();        if (fd > 0)            kill(fd, SIGINT);        exit(0);    }#if !defined(__s390__) && !defined(__s390x__)    testing = (getppid() != 0) && (getppid() != 1);#endif    if (!testing) {        /* turn off screen blanking */        printstr("\033[9;0]");        printstr("\033[8]");    } else {        printstr("(running in test mode).\n");    }    umask(022);    printstr("\nGreetings.\n");    printf("anaconda installer init version %s starting\n", VERSION);    printf("mounting /proc filesystem... ");     if (!testing) {        if (mount("/proc", "/proc", "proc", 0, NULL))            fatal_error(1);    }    printf("done\n");    printf("creating /dev filesystem... ");     if (!testing) {        if (mount("/dev", "/dev", "tmpfs", 0, NULL))            fatal_error(1);        createDevices();    }    printf("done\n");    printf("mounting /dev/pts (unix98 pty) filesystem... ");     if (!testing) {        if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL))            fatal_error(1);    }    printf("done\n");    printf("mounting /sys filesystem... ");     if (!testing) {        if (mount("/sys", "/sys", "sysfs", 0, NULL))            fatal_error(1);    }    printf("done\n");    /* these args are only for testing from commandline */    for (i = 1; i < argc; i++) {        if (!strcmp (argv[i], "serial")) {            isSerial = 1;            break;        }    }    noKill = getNoKill();#if !defined(__s390__) && !defined(__s390x__)    static struct termios orig_cmode;    struct termios cmode, mode;    int cfd;        cfd =  open("/dev/console", O_RDONLY);    tcgetattr(cfd,&orig_cmode);    close(cfd);    cmode = orig_cmode;    cmode.c_lflag &= (~ECHO);    cfd = open("/dev/console", O_WRONLY);    tcsetattr(cfd,TCSANOW,&cmode);    close(cfd);    /* handle weird consoles */#if defined(__powerpc__)    char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */                          "/dev/hvsi0", "/dev/hvsi1",                          "/dev/hvsi2", /* hvsi for POWER5 */                          NULL };#elif defined (__ia64__)    char * consoles[] = { "/dev/ttySG0", "/dev/xvc0", NULL };#elif defined (__i386__) || defined (__x86_64__)    char * consoles[] = { "/dev/xvc0", NULL };#else    char * consoles[] = { NULL };#endif    for (i = 0; consoles[i] != NULL; i++) {        if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) {            printf("anaconda installer init version %s using %s as console\n",                   VERSION, consoles[i]);            isSerial = 3;            console = strdup(consoles[i]);            break;        }        close(fd);    }    cfd = open("/dev/console", O_WRONLY);    tcsetattr(cfd,TCSANOW,&orig_cmode);    close(cfd);     if ((fd < 0) && (ioctl (0, TIOCLINUX, &twelve) < 0)) {        isSerial = 2;        if (ioctl(0, TIOCGSERIAL, &si) == -1) {            isSerial = 0;        }    }    if (isSerial && (isSerial != 3)) {        char *device = "/dev/ttyS0";        printf("anaconda installer init version %s using a serial console\n",                VERSION);        if (isSerial == 2)            device = "/dev/console";        fd = open(device, O_RDWR, 0);        if (fd < 0)            device = "/dev/tts/0";        if (fd < 0) {            printf("failed to open %s\n", device);            fatal_error(1);        }        setupTerminal(fd);    } else if (isSerial == 3) {        setupTerminal(fd);    } else if (fd < 0)  {        fd = open("/dev/tty1", O_RDWR, 0);        if (fd < 0)            fd = open("/dev/vc/1", O_RDWR, 0);        if (fd < 0) {            printf("failed to open /dev/tty1 and /dev/vc/1");            fatal_error(1);        }    }    if (testing)        exit(0);    setsid();    if (ioctl(0, TIOCSCTTY, NULL)) {        printf("could not set new controlling tty\n");    }    dup2(fd, 0);    dup2(fd, 1);    dup2(fd, 2);    if (fd > 2)        close(fd);#else    dup2(0, 1);    dup2(0, 2);#endif    /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */#ifdef SNAKES_ON_A_PLANE    disable_keys = 0;#else    disable_keys = 1;    if (argc > 1)        if (mystrstr(argv[1], "rescue"))            disable_keys = 0;#endif    if (disable_keys) {        tcgetattr(0, &ts);        ts.c_iflag &= ~BRKINT;        ts.c_iflag |= IGNBRK;        ts.c_iflag &= ~ISIG;        tcsetattr(0, TCSANOW, &ts);    }    if (!testing) {        int ret;        ret = sethostname("localhost.localdomain", 21);        /* the default domainname (as of 2.0.35) is "(none)", which confuses          glibc */        ret = setdomainname("", 0);    }    printf("trying to remount root filesystem read write... ");    if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) {        fatal_error(1);    }    printf("done\n");            /* we want our /tmp to be ramfs, but we also want to let people hack     * their initrds to add things like a ks.cfg, so this has to be a little     * tricky */    if (!testing) {        rename("/tmp", "/oldtmp");        mkdir("/tmp", 0755);        printf("mounting /tmp as ramfs... ");        if (mount("none", "/tmp", "ramfs", 0, NULL))            fatal_error(1);        printf("done\n");        copyDirectory("/oldtmp", "/tmp");        unlink("/oldtmp");    }    /* Now we have some /tmp space set up, and /etc and /dev point to       it. We should be in pretty good shape. */    if (!testing)         doklog("/dev/tty4");    /* write out a pid file */    if ((fd = open("/var/run/init.pid", O_WRONLY|O_CREAT)) > 0) {        char * buf = malloc(10);        int ret;        snprintf(buf, 9, "%d", getpid());        ret = write(fd, buf, strlen(buf));        close(fd);        free(buf);    } else {        printf("unable to write init.pid (%d): %s\n", errno, strerror(errno));        sleep(2);    }    /* Go into normal init mode - keep going, and then do a orderly shutdown       when:       1) /bin/install exits       2) we receive a SIGHUP     */    printf("running install...\n");     setsid();#ifdef SNAKES_ON_A_PLANE    printf("> Snakes on a Plane <\n");    /* hack to load core modules for debugging mode */    char * modvc[15];    char ** modvp = modvc;    *modvp++ = "/bin/modprobe";    *modvp++ = "ehci-hcd";    *modvp++ = "uhci-hcd";    *modvp++ = "ohci-hcd";    *modvp++ = NULL;    pid_t blah = fork();    int qux;    if (blah == 0) {        printf("loading core debugging modules...\n");        execve(modvc[0], modvc, env);    } else {        waitpid(blah, &qux, WNOHANG);    }#endif    if (!(installpid = fork())) {        /* child */#ifdef SNAKES_ON_A_PLANE        *argvp++ = "/bin/strace";#endif        *argvp++ = "/sbin/loader";        if (isSerial == 3) {            *argvp++ = "--virtpconsole";            *argvp++ = console;        }        *argvp++ = NULL;        printf("running %s\n", argvc[0]);        execve(argvc[0], argvc, env);        shutDown(1, 0, 0);    }    /* signal handlers for halt/poweroff */    signal(SIGUSR1, sigUsr1Handler);    signal(SIGUSR2, sigUsr2Handler);    /* set up the ctrl+alt+delete handler to kill our pid, not pid 1 */    signal(SIGINT, sigintHandler);    if ((fd = open("/proc/sys/kernel/cad_pid", O_WRONLY)) != -1) {        char buf[7];        size_t count;        sprintf(buf, "%d", getpid());        count = write(fd, buf, strlen(buf));        close(fd);        /* if we succeeded in writing our pid, turn off the hard reboot           ctrl-alt-del handler */        if (count == strlen(buf) &&            (fd = open("/proc/sys/kernel/ctrl-alt-del", O_WRONLY)) != -1) {            int ret;            ret = write(fd, "0", 1);            close(fd);        }    }        while (!doShutdown) {        childpid = waitpid(-1, &waitStatus, 0);        if (childpid == installpid)             doShutdown = 1;    }    if (!WIFEXITED(waitStatus) ||        (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) {        printf("install exited abnormally [%d/%d] ", WIFEXITED(waitStatus),                                                     WEXITSTATUS(waitStatus));        if (WIFSIGNALED(waitStatus)) {            printf("-- received signal %d", WTERMSIG(waitStatus));        }        printf("\n");    } else {        doReboot = 1;    }    if (testing)        exit(0);    shutDown(noKill, doReboot, 0);    return 0;}/* vim:set shiftwidth=4 softtabstop=4 ts=4: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -