Annotation of qemu/roms/openbios/libopenbios/bootinfo_load.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *
        !             3:  *       <bootinfo_load.c>
        !             4:  *
        !             5:  *       bootinfo file loader
        !             6:  *
        !             7:  *   Copyright (C) 2009 Laurent Vivier ([email protected])
        !             8:  *
        !             9:  *   Original XML parser by Blue Swirl <[email protected]>
        !            10:  *
        !            11:  *   This program is free software; you can redistribute it and/or
        !            12:  *   modify it under the terms of the GNU General Public License
        !            13:  *   version 2
        !            14:  *
        !            15:  */
        !            16: 
        !            17: #include "config.h"
        !            18: #include "libopenbios/bindings.h"
        !            19: #include "libopenbios/bootinfo_load.h"
        !            20: #include "libopenbios/ofmem.h"
        !            21: #include "libc/vsprintf.h"
        !            22: 
        !            23: //#define DEBUG_BOOTINFO
        !            24: 
        !            25: #ifdef DEBUG_BOOTINFO
        !            26: #define DPRINTF(fmt, args...) \
        !            27:     do { printk("%s: " fmt, __func__ , ##args); } while (0)
        !            28: #else
        !            29: #define DPRINTF(fmt, args...) \
        !            30:     do { } while (0)
        !            31: #endif
        !            32: 
        !            33: static char *
        !            34: get_device( const char *path )
        !            35: {
        !            36:        int i;
        !            37:        static char buf[1024];
        !            38: 
        !            39:        for (i = 0; i < sizeof(buf) && path[i] && path[i] != ':'; i++)
        !            40:                buf[i] = path[i];
        !            41:        buf[i] = 0;
        !            42: 
        !            43:        return buf;
        !            44: }
        !            45: 
        !            46: static char *
        !            47: get_partition( const char *path )
        !            48: {
        !            49:        static char buf[2];
        !            50: 
        !            51:        buf[0] = '\0';
        !            52:        buf[1] = '\0';
        !            53: 
        !            54:        while ( *path && *path != ':' )
        !            55:                path++;
        !            56: 
        !            57:        if (!*path)
        !            58:                return buf;
        !            59:        path++;
        !            60: 
        !            61:        if (path[0] == ',' || !strchr(path, ',')) /* if there is not a ',' or no partition id then return */
        !            62:                return buf;
        !            63: 
        !            64:        /* Must be a partition id */
        !            65:        buf[0] = path[0];
        !            66: 
        !            67:        return buf;
        !            68: }
        !            69: 
        !            70: static char *
        !            71: get_filename( const char * path , char **dirname)
        !            72: {
        !            73:         static char buf[1024];
        !            74:         char *filename;
        !            75: 
        !            76:         while ( *path && *path != ':' )
        !            77:                 path++;
        !            78: 
        !            79:         if (!*path) {
        !            80:                 *dirname = NULL;
        !            81:                 return NULL;
        !            82:         }
        !            83:         path++;
        !            84: 
        !            85:         while ( *path && isdigit(*path) )
        !            86:                 path++;
        !            87: 
        !            88:         if (*path == ',')
        !            89:                 path++;
        !            90: 
        !            91:         strncpy(buf, path, sizeof(buf));
        !            92:         buf[sizeof(buf) - 1] = 0;
        !            93: 
        !            94:         filename = strrchr(buf, '\\');
        !            95:         if (filename) {
        !            96:                 *dirname = buf;
        !            97:                 (*filename++) = 0;
        !            98:         } else {
        !            99:                 *dirname = NULL;
        !           100:                 filename = buf;
        !           101:         }
        !           102: 
        !           103:         return filename;
        !           104: }
        !           105: 
        !           106: int
        !           107: is_bootinfo(char *bootinfo)
        !           108: {
        !           109:        return (strncasecmp(bootinfo, "<chrp-boot", 10) ? 0 : -1);
        !           110: }
        !           111: 
        !           112: int 
        !           113: bootinfo_load(struct sys_info *info, const char *filename)
        !           114: {
        !           115:        // Currently not implemented
        !           116:        return LOADER_NOT_SUPPORT;
        !           117: }
        !           118: 
        !           119: /*
        !           120:   Parse SGML structure like:
        !           121:   <chrp-boot>
        !           122:   <description>Debian/GNU Linux Installation on IBM CHRP hardware</description>
        !           123:   <os-name>Debian/GNU Linux for PowerPC</os-name>
        !           124:   <boot-script>boot &device;:\install\yaboot</boot-script>
        !           125:   <icon size=64,64 color-space=3,3,2>
        !           126: 
        !           127:   CHRP system bindings are described at:
        !           128:   http://playground.sun.com/1275/bindings/chrp/chrp1_7a.ps
        !           129: */
        !           130: 
        !           131: void
        !           132: bootinfo_init_program(void)
        !           133: {
        !           134:        char *base;
        !           135:        int proplen;
        !           136:        phandle_t chosen;
        !           137:        int tag, taglen, script, scriptlen, scriptvalid, entity, chrp;
        !           138:        char tagbuf[128], c;
        !           139:        char *device, *filename, *directory, *partition;
        !           140:        int current, size;
        !           141:        char *bootscript;
        !           142:         char *tmp;
        !           143:        char bootpath[1024];
        !           144: 
        !           145:        /* Parse the boot script */
        !           146: 
        !           147:        chosen = find_dev("/chosen");
        !           148:        tmp = get_property(chosen, "bootpath", &proplen);
        !           149:        memcpy(bootpath, tmp, proplen);
        !           150:        bootpath[proplen] = 0;
        !           151: 
        !           152:        DPRINTF("bootpath %s\n", bootpath);
        !           153: 
        !           154:        device = get_device(bootpath);
        !           155:        partition = get_partition(bootpath);
        !           156:        filename = get_filename(bootpath, &directory);
        !           157: 
        !           158:        feval("load-base");
        !           159:        base = (char*)cell2pointer(POP());
        !           160: 
        !           161:        feval("load-size");
        !           162:        size = POP();
        !           163: 
        !           164:        bootscript = malloc(size);
        !           165:        if (bootscript == NULL) {
        !           166:                DPRINTF("Can't malloc %d bytes\n", size);
        !           167:                return;
        !           168:        }
        !           169: 
        !           170:        if (!is_bootinfo(base)) {
        !           171:                DPRINTF("Not a valid bootinfo memory image\n");
        !           172:                 free(bootscript);
        !           173:                return;
        !           174:        }
        !           175: 
        !           176:        chrp = 0;
        !           177:        tag = 0;
        !           178:        taglen = 0;
        !           179:        script = 0;
        !           180:        scriptvalid = 0;
        !           181:        scriptlen = 0;
        !           182:        entity = 0;
        !           183:        current = 0;
        !           184:        while (current < size) {
        !           185: 
        !           186:                c = base[current++];
        !           187: 
        !           188:                if (c == '<') {
        !           189:                        script = 0;
        !           190:                        tag = 1;
        !           191:                        taglen = 0;
        !           192:                } else if (c == '>') {
        !           193:                        tag = 0;
        !           194:                        tagbuf[taglen] = '\0';
        !           195:                        if (strncasecmp(tagbuf, "chrp-boot", 9) == 0) {
        !           196:                                chrp = 1;
        !           197:                        } else if (chrp == 1) {
        !           198:                                if (strncasecmp(tagbuf, "boot-script", 11) == 0) {
        !           199:                                        script = 1;
        !           200:                                        scriptlen = 0;
        !           201:                                } else if (strncasecmp(tagbuf, "/boot-script", 12) == 0) {
        !           202: 
        !           203:                                        script = 0;
        !           204:                                        bootscript[scriptlen] = '\0';
        !           205: 
        !           206:                                        DPRINTF("got bootscript %s\n",
        !           207:                                                bootscript);
        !           208: 
        !           209:                                        scriptvalid = -1;
        !           210: 
        !           211:                                        break;
        !           212:                                } else if (strncasecmp(tagbuf, "/chrp-boot", 10) == 0)
        !           213:                                        break;
        !           214:                        }
        !           215:                } else if (tag && taglen < sizeof(tagbuf)) {
        !           216:                        tagbuf[taglen++] = c;
        !           217:                } else if (script && c == '&') {
        !           218:                        entity = 1;
        !           219:                        taglen = 0;
        !           220:                } else if (entity && c ==';') {
        !           221:                        entity = 0;
        !           222:                        tagbuf[taglen] = '\0';
        !           223:                        if (strncasecmp(tagbuf, "lt", 2) == 0) {
        !           224:                                bootscript[scriptlen++] = '<';
        !           225:                        } else if (strncasecmp(tagbuf, "gt", 2) == 0) {
        !           226:                                bootscript[scriptlen++] = '>';
        !           227:                        } else if (strncasecmp(tagbuf, "device", 6) == 0) {
        !           228:                                strcpy(bootscript + scriptlen, device);
        !           229:                                scriptlen += strlen(device);
        !           230:                        } else if (strncasecmp(tagbuf, "partition", 9) == 0) {
        !           231:                                strcpy(bootscript + scriptlen, partition);
        !           232:                                scriptlen += strlen(partition);
        !           233:                        } else if (strncasecmp(tagbuf, "directory", 9) == 0) {
        !           234:                                strcpy(bootscript + scriptlen, directory);
        !           235:                                scriptlen += strlen(directory);
        !           236:                        } else if (strncasecmp(tagbuf, "filename", 8) == 0) {
        !           237:                                strcpy(bootscript + scriptlen, filename);
        !           238:                                scriptlen += strlen(filename);
        !           239:                        } else if (strncasecmp(tagbuf, "full-path", 9) == 0) {
        !           240:                                strcpy(bootscript + scriptlen, bootpath);
        !           241:                                scriptlen += strlen(bootpath);
        !           242:                        } else { /* unknown, keep it */
        !           243:                                bootscript[scriptlen] = '&';
        !           244:                                strcpy(bootscript + scriptlen + 1, tagbuf);
        !           245:                                scriptlen += taglen + 1;
        !           246:                                bootscript[scriptlen] = ';';
        !           247:                                scriptlen++;
        !           248:                        }
        !           249:                } else if (entity && taglen < sizeof(tagbuf)) {
        !           250:                        tagbuf[taglen++] = c;
        !           251:                } else if (script && scriptlen < size) {
        !           252:                        bootscript[scriptlen++] = c;
        !           253:                }
        !           254:        }
        !           255: 
        !           256:        /* If the payload is bootinfo then we execute it immediately */
        !           257:        if (scriptvalid) {
        !           258:                DPRINTF("bootscript: %s\n", bootscript);
        !           259:                feval(bootscript);
        !           260:        }
        !           261:        else
        !           262:                DPRINTF("Unable to parse bootinfo bootscript\n");
        !           263: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.