struct MINI_Section *mini_load(char *text) { char *it = text; struct MINI_Section *section_it = NULL; struct MINI_Section *section_start = NULL; struct MINI_KeyValue *value_it = NULL; while(*it != 0) { if(*it == '#') { it = handle_comment(it); if(*it == 0) { return section_start; } } else if(*it == '[') { it++; it = skip_wspace(it); if(*it == 0) { return NULL; } if(section_start == NULL) { section_start = calloc(1, sizeof(struct MINI_Section)); if(section_start == NULL) { return NULL; } section_it = section_start; section_it->next = NULL; } else { section_it->next = calloc(1, sizeof(struct MINI_Section)); if(section_it->next == NULL) { return NULL; } section_it = section_it->next; section_it->next = NULL; } section_it->values = NULL; section_it->name = get_name(&it); if(*section_it->name == 0) { return NULL; } it = skip_wspace(it); if(*it == 0) { return NULL; } if(*it != ']') { return NULL; } it++; while(1) { it = skip_wspace(it); if(*it == 0) { return section_start; } else if(*it == '#') { it = handle_comment(it); if(*it == 0) { return section_start; } } else if(*it == '[') { break; } else { if(section_it->values == NULL) { section_it->values = calloc(1, sizeof(struct MINI_KeyValue)); if(section_it->values == NULL) { return NULL; } value_it = section_it->values; value_it->next = NULL; } else { value_it->next = calloc(1, sizeof(struct MINI_KeyValue)); if(value_it->next == NULL) { return NULL; } value_it = value_it->next; value_it->next = NULL; } value_it->name = get_name(&it); if(*value_it->name == 0) { return NULL; } it = skip_wspace(it); if(*it == 0) { return NULL; } if(*it != '=') { return NULL; } /* first letter after = */ it++; if(*it == 0) { return NULL; } it = skip_wspace(it); if(*it == 0) { return NULL; } value_it->value = get_value(&it); if(*value_it->value == 0) { return NULL; } } } } if(*it == '[') { continue; } it++; } return 0; }
/* * The parse_kernel_line function examines a menu.lst kernel line. For * multiboot, this is: * * kernel <multiboot path> <flags1> <kernel path> <flags2> * * <multiboot path> is either /platform/i86pc/multiboot or /boot/multiboot * * <kernel path> may be missing, or may be any full or relative path to unix. * We check for it by looking for a word ending in "/unix". If it ends * in "kernel/unix", we upgrade it to a 32-bit entry. If it ends in * "kernel/amd64/unix", we upgrade it to the default entry. Otherwise, * it's a custom kernel, and we skip it. * * <flags*> are anything that doesn't fit either of the above - these will be * copied over. * * For direct boot, the defaults are * * kernel$ <kernel path> <flags> * * <kernel path> is one of: * /platform/i86pc/kernel/$ISADIR/unix * /boot/platform/i86pc/kernel/$ISADIR/unix * /platform/i86pc/kernel/unix * /platform/i86pc/kernel/amd64/unix * /boot/platform/i86pc/kernel/unix * /boot/platform/i86pc/kernel/amd64/unix * * If <kernel path> is any of the last four, the command may also be "kernel". * * <flags> is anything that isn't <kernel path>. * * This function is only called to convert a multiboot entry to a dboot entry * * For safety, we do one more check: if the kernel path starts with /boot, * we verify that the new kernel exists before changing it. This is mainly * done for bfu, as it may cause the failsafe archives to be a different * boot architecture from the newly bfu'ed system. */ static error_t cvt_kernel_line(line_t *line, const char *osroot, entry_t *entry) { char path[PATH_MAX], path_64[PATH_MAX]; char linebuf[PATH_MAX]; char new_arg[PATH_MAX]; struct stat sb, sb_64; char *old_ptr; char *unix_ptr; char *flags1_ptr; char *flags2_ptr; const char *fcn = "cvt_kernel_line()"; BAM_DPRINTF((D_FUNC_ENTRY2, fcn, line->line, osroot)); /* * We only convert multiboot to dboot and nothing else. */ if (!(entry->flags & BAM_ENTRY_MULTIBOOT)) { BAM_DPRINTF((D_NOT_MULTIBOOT_CONVERT, fcn)); return (BAM_SUCCESS); } if (entry->flags & BAM_ENTRY_FAILSAFE) { /* * We're attempting to change failsafe to dboot. * In the bfu case, we may not have a dboot failsafe * kernel i.e. a "unix" under the "/boot" hierarchy. * If so, just emit a message in verbose mode and * return success. */ BAM_DPRINTF((D_TRYING_FAILSAFE_CVT_TO_DBOOT, fcn)); (void) snprintf(path, PATH_MAX, "%s%s", osroot, DIRECT_BOOT_FAILSAFE_32); (void) snprintf(path_64, PATH_MAX, "%s%s", osroot, DIRECT_BOOT_FAILSAFE_64); if (stat(path, &sb) != 0 && stat(path_64, &sb_64) != 0) { if (bam_verbose) { bam_error(FAILSAFE_MISSING, line->lineNum); } BAM_DPRINTF((D_NO_FAILSAFE_UNIX_CONVERT, fcn)); return (BAM_SUCCESS); } } /* * Make sure we have the correct cmd */ free(line->cmd); line->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]); BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, line->cmd)); assert(sizeof (linebuf) > strlen(line->arg) + 32); (void) strlcpy(linebuf, line->arg, sizeof (linebuf)); old_ptr = strpbrk(linebuf, " \t\n"); old_ptr = skip_wspace(old_ptr); if (old_ptr == NULL) { /* * only multiboot and nothing else * i.e. flags1 = unix = flags2 = NULL */ flags1_ptr = unix_ptr = flags2_ptr = NULL; BAM_DPRINTF((D_FLAGS1_UNIX_FLAGS2_NULL, fcn)) goto create; }
/* * The parse_kernel_line function examines a menu.lst kernel line. For * multiboot, this is: * * kernel <multiboot path> <flags1> <kernel path> <flags2> * * <multiboot path> is either /platform/i86pc/multiboot or /boot/multiboot * * <kernel path> may be missing, or may be any full or relative path to unix. * We check for it by looking for a word ending in "/unix". If it ends * in "kernel/unix", we upgrade it to a 32-bit entry. If it ends in * "kernel/amd64/unix", we upgrade it to the default entry. Otherwise, * it's a custom kernel, and we skip it. * * <flags*> are anything that doesn't fit either of the above - these will be * copied over. * * For direct boot, the defaults are * * kernel$ <kernel path> <flags> * * <kernel path> is one of: * /platform/i86pc/kernel/$ISADIR/unix * /boot/platform/i86pc/kernel/$ISADIR/unix * /platform/i86pc/kernel/unix * /platform/i86pc/kernel/amd64/unix * /boot/platform/i86pc/kernel/unix * /boot/platform/i86pc/kernel/amd64/unix * * If <kernel path> is any of the last four, the command may also be "kernel". * * <flags> is anything that isn't <kernel path>. * * This function is only called to convert a multiboot entry to a dboot entry * * For safety, we do one more check: if the kernel path starts with /boot, * we verify that the new kernel exists before changing it. This is mainly * done for bfu, as it may cause the failsafe archives to be a different * boot architecture from the newly bfu'ed system. */ static error_t cvt_kernel_line(line_t *line, const char *osroot, entry_t *entry) { char path[PATH_MAX], path_64[PATH_MAX]; char linebuf[PATH_MAX]; char new_arg[PATH_MAX]; struct stat sb, sb_64; char *old_ptr; char *unix_ptr; char *flags1_ptr; char *flags2_ptr; const char *fcn = "cvt_kernel_line()"; BAM_DPRINTF(("%s: entered. args: %s %s\n", fcn, line->line, osroot)); /* * We only convert multiboot to dboot and nothing else. */ if (!(entry->flags & BAM_ENTRY_MULTIBOOT)) { BAM_DPRINTF(("%s: not MULTIBOOT, not converting\n", fcn)); return (BAM_SUCCESS); } if (entry->flags & BAM_ENTRY_FAILSAFE) { /* * We're attempting to change failsafe to dboot. * In the bfu case, we may not have a dboot failsafe * kernel i.e. a "unix" under the "/boot" hierarchy. * If so, just emit a message in verbose mode and * return success. */ BAM_DPRINTF(("%s: trying to convert failsafe to DBOOT\n", fcn)); (void) snprintf(path, PATH_MAX, "%s%s", osroot, DIRECT_BOOT_FAILSAFE_32); (void) snprintf(path_64, PATH_MAX, "%s%s", osroot, DIRECT_BOOT_FAILSAFE_64); if (stat(path, &sb) != 0 && stat(path_64, &sb_64) != 0) { if (bam_verbose) { bam_error(_("bootadm -m upgrade run, but the " "failsafe archives have not been\nupdated. " "Not updating line %d\n"), line->lineNum); } BAM_DPRINTF(("%s: no FAILSAFE unix, not converting\n", fcn)); return (BAM_SUCCESS); } } /* * Make sure we have the correct cmd */ free(line->cmd); line->cmd = s_strdup(menu_cmds[KERNEL_DOLLAR_CMD]); BAM_DPRINTF(("%s: converted kernel cmd to %s\n", fcn, line->cmd)); assert(sizeof (linebuf) > strlen(line->arg) + 32); (void) strlcpy(linebuf, line->arg, sizeof (linebuf)); old_ptr = strpbrk(linebuf, " \t\n"); old_ptr = skip_wspace(old_ptr); if (old_ptr == NULL) { /* * only multiboot and nothing else * i.e. flags1 = unix = flags2 = NULL */ flags1_ptr = unix_ptr = flags2_ptr = NULL; BAM_DPRINTF(("%s: NULL flags1, unix, flags2\n", fcn)) goto create; }