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

📄 init.c

📁 linux 安装程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * init.c *  * This is the install type init  * * Erik Troan (ewt@redhat.com) * Jeremy Katz (katzj@redhat.com) * * Copyright 1996 - 2004 Red Hat, Inc. * * This software may be freely redistributed under the terms of the GNU * general public license. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#if USE_MINILIBC#include "minilibc.h"#ifndef SOCK_STREAM# define SOCK_STREAM 1#endif #else#include <ctype.h>#include <dirent.h>#include <errno.h>#include <fcntl.h>#include <net/if.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/ioctl.h>#include <sys/klog.h>#include <sys/mount.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/swap.h>#include <sys/time.h>#include <sys/types.h>#include <sys/un.h>#include <sys/wait.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/reboot.h>#include <linux/vt.h>#include <termios.h>#include <libgen.h>#include "devt.h"#include "devices.h"#define syslog klogctl#endif#include <asm/types.h>#include <linux/cdrom.h>#include <linux/serial.h>#ifndef MS_REMOUNT#define MS_REMOUNT          32#endif#define ENV_PATH            0#define ENV_LD_LIBRARY_PATH 1#define ENV_HOME            2#define ENV_TERM            3#define ENV_DEBUG           4#define ENV_TERMINFO        5#define ENV_PYTHONPATH      6#define ENV_MALLOC_CHECK    7#define ENV_MALLOC_PERTURB  8/* * Snakes On A Plane... * * Define this macro if you want init to launch /bin/bash instead of loader. * You will want to populate initrd.img with bash, libraries, other commands * like strace or something, and whatever else you want.  This is purely for * debugging loader.  Things you will likely want in a debugging initrd: *    /lib/libc.so.6 *    /lib/libtermcap.so.2 *    /lib/ld-linux.so.2 *    /lib/libdl.so.2 *    /bin/bash *    /bin/strace * You get the idea.  Be creative.  Be imaginative.  Be bold. */#undef SNAKES_ON_A_PLANE/* #define SNAKES_ON_A_PLANE 1 */char * env[] = {    "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:"    "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:"    "/mnt/sysimage/usr/X11R6/bin",    /* we set a nicer ld library path specifically for bash -- a full       one makes anaconda unhappy */#if defined(__x86_64__) || defined(__s390x__) || defined(__ppc64__)    "LD_LIBRARY_PATH=/lib64:/usr/lib64:/lib:/usr/lib",#else    "LD_LIBRARY_PATH=/lib:/usr/lib",#endif    "HOME=/",    "TERM=linux",    "DEBUG=",    "TERMINFO=/etc/linux-terminfo",    "PYTHONPATH=/tmp/updates",    "_MALLOC_CHECK=2",    "MALLOC_PERTURB_=204",    NULL};/*  * this needs to handle the following cases: * *	1) run from a CD root filesystem *	2) run from a read only nfs rooted filesystem *      3) run from a floppy *	4) run from a floppy that's been loaded into a ramdisk  * */int testing=0;void unmountFilesystems(void);void disableSwap(void);void shutDown(int noKill, int doReboot, int doPowerOff);static int getNoKill(void);struct termios ts;static int mystrstr(char *str1, char *str2) {    char *p;    int rc=0;    for (p=str1; *p; p++) {        if (*p == *str2) {            char *s, *t;            rc = 1;            for (s=p, t=str2; *s && *t; s++, t++)                if (*s != *t) {                    rc = 0;                    p++;                }            if (rc)                return rc;        }     }    return rc;}static void printstr(char * string) {    int ret;    ret = write(1, string, strlen(string));}static void fatal_error(int usePerror) {/* FIXME */#if 0    if (usePerror)         perror("failed:");    else#endif    printf("failed.\n");    printf("\nI can't recover from this.\n");    if (testing)        exit(0);#if !defined(__s390__) && !defined(__s390x__)    while (1) ;#endif}static int logChunk(int len, char *inbuf, char *outbuf) {    int inctr, outctr;    for (inctr = 0, outctr = 0; inctr < len; inctr++) {        /* If the character is a NULL that's immediately followed by a open         * bracket, we've found the beginning of a new kernel message.  Put in         * a line separator.         */        if (inbuf[inctr] == '\0' && inctr+1 < len && inbuf[inctr+1] == '<') {            outbuf[outctr] = '\n';            outctr++;        }        /* Or, if we see a NULL right before the end of the chunk, that's also         * a good place to add a separator.         */        else if (inbuf[inctr] == '\0' && inctr+1 == len) {            outbuf[outctr] = '\n';            outctr++;        }        /* Otherwise, simply output the character as long as it's not NULL. */        else if (inbuf[inctr] != '\0') {            outbuf[outctr] = inbuf[inctr];            outctr++;        }    }    return outctr;}static void doklog(char * fn) {    fd_set readset, unixs;    int in, out, i;    int log;    socklen_t s;    int sock = -1;    struct sockaddr_un sockaddr;    char inbuf[1024], outbuf[1024];    int readfd;    int ret;    in = open("/proc/kmsg", O_RDONLY,0);    if (in < 0) {        /* FIXME: was perror */        printstr("open /proc/kmsg");        return;    }    out = open(fn, O_WRONLY, 0);    if (out < 0)         printf("couldn't open %s for syslog -- still using /tmp/syslog\n", fn);    log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644);    if (log < 0) {        /* FIXME: was perror */        printstr("error opening /tmp/syslog");        sleep(5);	        close(in);        return;    }    /* if we get this far, we should be in good shape */    if (fork()) {        /* parent */        close(in);        close(out);        close(log);        return;    }    close(0);     close(1);    close(2);    dup2(1, log);#if defined(USE_LOGDEV)    /* now open the syslog socket */    sockaddr.sun_family = AF_UNIX;    strcpy(sockaddr.sun_path, "/dev/log");    sock = socket(AF_UNIX, SOCK_STREAM, 0);    if (sock < 0) {        printf("error creating socket: %d\n", errno);        sleep(5);    }    printstr("got socket\n");    if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) + 			strlen(sockaddr.sun_path))) {        printf("bind error: %d\n", errno);        sleep(5);    }    printstr("bound socket\n");    chmod("/dev/log", 0666);    if (listen(sock, 5)) {        printf("listen error: %d\n", errno);        sleep(5);    }#endif    syslog(8, NULL, 1);    FD_ZERO(&unixs);    while (1) {        memcpy(&readset, &unixs, sizeof(unixs));        if (sock >= 0)            FD_SET(sock, &readset);        FD_SET(in, &readset);        i = select(20, &readset, NULL, NULL, NULL);        if (i <= 0) continue;        if (FD_ISSET(in, &readset)) {            i = read(in, inbuf, sizeof(inbuf));            if (i > 0) {                int loggedLen = logChunk(i, inbuf, outbuf);                if (out >= 0)                    ret = write(out, outbuf, loggedLen);                ret = write(log, outbuf, loggedLen);            }        }         for (readfd = 0; readfd < 20; ++readfd) {            if (FD_ISSET(readfd, &readset) && FD_ISSET(readfd, &unixs)) {                i = read(readfd, inbuf, sizeof(inbuf));                if (i > 0) {                    int loggedLen = logChunk(i, inbuf, outbuf);                    if (out >= 0)                        ret = write(out, outbuf, loggedLen);                    ret = write(log, outbuf, loggedLen);                } else if (i == 0) {                    /* socket closed */                    close(readfd);                    FD_CLR(readfd, &unixs);                }            }        }        if (sock >= 0 && FD_ISSET(sock, &readset)) {            s = sizeof(sockaddr);            readfd = accept(sock, (struct sockaddr *) &sockaddr, &s);            if (readfd < 0) {                if (out >= 0)                    ret = write(out, "error in accept\n", 16);                ret = write(log, "error in accept\n", 16);                close(sock);                sock = -1;            } else {                FD_SET(readfd, &unixs);            }        }    }    }static int setupTerminal(int fd) {    struct winsize winsize;    int fdn, len;    char buf[65535];    if (ioctl(fd, TIOCGWINSZ, &winsize)) {        printf("failed to get winsize");        fatal_error(1);    }    winsize.ws_row = 24;    winsize.ws_col = 80;    if (ioctl(fd, TIOCSWINSZ, &winsize)) {        printf("failed to set winsize");        fatal_error(1);    }    /* use the no-advanced-video vt100 definition */    env[ENV_TERM] = "TERM=vt100-nav";    /* unless the user specifies that they want utf8 */    if ((fdn = open("/proc/cmdline", O_RDONLY, 0)) != -1) {        len = read(fdn, buf, sizeof(buf) - 1);        close(fdn);        if (len > 0 && mystrstr(buf, "utf8"))            env[ENV_TERM] = "TERM=vt100";    }    return 0;}#if !defined(__s390__) && !defined(__s390x__)static int termcmp(struct termios *a, struct termios *b) {    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||        a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||        a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)        return 1;    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));}#endif/* Recursive -- copied (and tweaked)from loader2/method.c */ static int copyDirectory(char * from, char * to) {    DIR * dir;    struct dirent * ent;    int fd, outfd;    char buf[4096];    int i;    struct stat sb;    char filespec[256];    char filespec2[256];    char link[1024];    int ret;    mkdir(to, 0755);    if (!(dir = opendir(from))) {        printf("Failed to read directory %s: %s", from, strerror(errno));        return 1;    }    errno = 0;    while ((ent = readdir(dir))) {        if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue;        sprintf(filespec, "%s/%s", from, ent->d_name);        sprintf(filespec2, "%s/%s", to, ent->d_name);        lstat(filespec, &sb);        if (S_ISDIR(sb.st_mode)) {            if (copyDirectory(filespec, filespec2)) return 1;        } else if (S_ISLNK(sb.st_mode)) {            i = readlink(filespec, link, sizeof(link) - 1);            link[i] = '\0';            if (symlink(link, filespec2)) {                printf("failed to symlink %s to %s: %s", filespec2,                        link, strerror(errno));            }        } else {            fd = open(filespec, O_RDONLY);            if (fd == -1) {                printf("failed to open %s: %s", filespec, strerror(errno));                return 1;            }             outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644);            if (outfd == -1) {                printf("failed to create %s: %s", filespec2, strerror(errno));            } else {                fchmod(outfd, sb.st_mode & 07777);                while ((i = read(fd, buf, sizeof(buf))) > 0)                    ret = write(outfd, buf, i);                close(outfd);            }            close(fd);        }        errno = 0;    }    closedir(dir);    return 0;}static void createDevices(void) {    int i;    for (i = 0; devnodes[i].devname != NULL; i++) {        char devname[64];        int type = -1;

⌨️ 快捷键说明

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