int main(int argc, char *argv[]) { struct wrapper_data data; memset(&data, 0, sizeof(data)); if (getenv("PATH")) data.path = xstrdup(getenv("PATH")); /* What should we find ? */ data.name = basename(argv[0]); /* Allow for common compiler names like cc->gcc */ size_t i; for (i = 0; i < ARRAY_SIZE(wrapper_aliases); ++i) if (!strcmp(data.name, wrapper_aliases[i].alias)) data.name = wrapper_aliases[i].target; /* What is the full name of our wrapper? */ data.fullname = xmalloc(strlen(data.name) + sizeof("@GENTOO_PORTAGE_EPREFIX@/usr/bin/") + 1); sprintf(data.fullname, "@GENTOO_PORTAGE_EPREFIX@/usr/bin/%s", data.name); find_wrapper_target(&data); modify_path(&data); free(data.path); data.path = NULL; /* Set argv[0] to the correct binary, else gcc can't find internal headers * http://bugs.gentoo.org/8132 */ argv[0] = data.bin; /* If $ABI is in env, add appropriate env flags */ char **newargv = argv; if (getenv("ABI")) { char envvar[50]; /* We use CFLAGS_${ABI} for gcc, g++, g77, etc as the flags that would * be in there are the same no matter which compiler we are using. */ snprintf(envvar, sizeof(envvar), "CFLAGS_%s", getenv("ABI")); envvar[sizeof(envvar)-1] = '\0'; if (getenv(envvar)) newargv = build_new_argv(argv, getenv(envvar)); } /* Ok, lets do it one more time ... */ execv(data.bin, newargv); /* shouldn't have made it here if things worked ... */ wrapper_err("could not run/locate '%s'", data.name); return 123; }
void sync_delete(const wchar_t** pszAbsPath, bool bThrow) { int nLen; for(nLen=0; pszAbsPath[nLen]; ++nLen); ++nLen; wchar_t** ppCopy=(wchar_t**)alloca(nLen * sizeof(const wchar_t*)); memcpy(ppCopy, pszAbsPath, nLen * sizeof(const wchar_t*)); wchar_t* szwEntry=NULL; modify_path(ppCopy, szwEntry); m_pStorage->region_load((const wchar_t**)ppCopy, true); m_pStorage->entry_destroy(szwEntry); };
int main(int argc, char *argv[]) { struct wrapper_data *data; size_t size; int i; char **newargv = argv; data = alloca(sizeof(*data)); if (data == NULL) wrapper_exit("%s wrapper: out of memory\n", argv[0]); memset(data, 0, sizeof(*data)); if (getenv("PATH")) { data->path = strdup(getenv("PATH")); if (data->path == NULL) wrapper_exit("%s wrapper: out of memory\n", argv[0]); } /* What should we find ? */ strcpy(data->name, basename(argv[0])); /* Allow for common compiler names like cc->gcc */ for (i = 0; wrapper_aliases[i].alias; ++i) if (!strcmp(data->name, wrapper_aliases[i].alias)) strcpy(data->name, wrapper_aliases[i].target); /* What is the full name of our wrapper? */ size = sizeof(data->fullname); i = snprintf(data->fullname, size, "/usr/bin/%s", data->name); if ((i == -1) || (i > (int)size)) wrapper_exit("invalid wrapper name: \"%s\"\n", data->name); find_wrapper_target(data); modify_path(data); if (data->path) free(data->path); data->path = NULL; /* Set argv[0] to the correct binary, else gcc can't find internal headers * http://bugs.gentoo.org/show_bug.cgi?id=8132 */ argv[0] = data->bin; /* If this is g{cc,++}{32,64}, we need to add -m{32,64} * otherwise we need to add ${CFLAGS_${ABI}} */ size = strlen(data->bin) - 2; if(!strcmp(data->bin + size, "32") ) { *(data->bin + size) = '\0'; newargv = build_new_argv(argv, "-m32"); } else if (!strcmp(data->bin + size, "64") ) { *(data->bin + size) = '\0'; newargv = build_new_argv(argv, "-m64"); } else if(getenv("ABI")) { char envvar[50]; /* We use CFLAGS_${ABI} for gcc, g++, g77, etc as they are * the same no matter which compiler we are using. */ snprintf(envvar, sizeof(envvar), "CFLAGS_%s", getenv("ABI")); if (getenv(envvar)) { newargv = build_new_argv(argv, getenv(envvar)); if(!newargv) wrapper_exit("%s wrapper: out of memory\n", argv[0]); } } /* Ok, lets do it one more time ... */ if (execv(data->bin, newargv) < 0) wrapper_exit("Could not run/locate \"%s\"\n", data->name); return 0; }
int main(int argc, char *argv[]) { struct wrapper_data data; size_t size; int i; char **newargv = argv; memset(&data, 0, sizeof(data)); if (getenv("PATH")) { data.path = strdup(getenv("PATH")); if (data.path == NULL) wrapper_exit("%s wrapper: out of memory\n", argv[0]); } /* What should we find ? */ strcpy(data.name, basename(argv[0])); /* Allow for common compiler names like cc->gcc */ for (i = 0; wrapper_aliases[i].alias; ++i) if (!strcmp(data.name, wrapper_aliases[i].alias)) strcpy(data.name, wrapper_aliases[i].target); /* What is the full name of our wrapper? */ size = sizeof(data.fullname); i = snprintf(data.fullname, size, "/usr/bin/%s", data.name); if ((i == -1) || (i > (int)size)) wrapper_exit("invalid wrapper name: \"%s\"\n", data.name); find_wrapper_target(&data); modify_path(&data); if (data.path) free(data.path); data.path = NULL; /* Set argv[0] to the correct binary, else gcc can't find internal headers * http://bugs.gentoo.org/8132 */ argv[0] = data.bin; /* If $ABI is in env, add appropriate env flags */ if (getenv("ABI")) { char envvar[50]; /* We use CFLAGS_${ABI} for gcc, g++, g77, etc as they are * the same no matter which compiler we are using. */ snprintf(envvar, sizeof(envvar), "CFLAGS_%s", getenv("ABI")); if (getenv(envvar)) { newargv = build_new_argv(argv, getenv(envvar)); if (!newargv) wrapper_exit("%s wrapper: out of memory\n", argv[0]); } } /* Ok, lets do it one more time ... */ if (execv(data.bin, newargv) < 0) wrapper_exit("Could not run/locate \"%s\"\n", data.name); return 123; }
/*ARGSUSED*/ error_t cvt_to_metal(menu_t *mp, char *osroot, char *menu_root) { const char *fcn = "cvt_to_metal()"; line_t *lp; entry_t *ent; size_t len, zfslen; char *delim = ","; char *newstr; char *osdev; char *title = NULL; char *findroot = NULL; char *bootfs = NULL; char *kernel = NULL; char *module = NULL; char *barchive_path = DIRECT_BOOT_ARCHIVE; char *kern_path = NULL; int curdef, newdef; int emit_bflag = 1; int ret = BAM_ERROR; assert(osroot); BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, "")); /* * First just check to verify osroot is a sane directory. */ if ((osdev = get_special(osroot)) == NULL) { bam_error(CANT_FIND_SPECIAL, osroot); return (BAM_ERROR); } free(osdev); /* * Found the GRUB signature on the target partitions, so now get the * default GRUB boot entry number from the menu.lst file */ curdef = atoi(mp->curdefault->arg); /* look for the first line of the matching boot entry */ for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef)); ent = ent->next) ; /* couldn't find it, so error out */ if (ent == NULL) { bam_error(CANT_FIND_DEFAULT, curdef); goto abort; } /* * Now process the entry itself. */ for (lp = ent->start; lp != NULL; lp = lp->next) { /* * Process important lines from menu.lst boot entry. */ if (lp->flags == BAM_TITLE) { title = alloca(strlen(lp->arg) + 1); (void) strcpy(title, lp->arg); } else if (strcmp(lp->cmd, "findroot") == 0) { findroot = alloca(strlen(lp->arg) + 1); (void) strcpy(findroot, lp->arg); } else if (strcmp(lp->cmd, "bootfs") == 0) { bootfs = alloca(strlen(lp->arg) + 1); (void) strcpy(bootfs, lp->arg); } else if (strcmp(lp->cmd, menu_cmds[MODULE_DOLLAR_CMD]) == 0) { if (strstr(lp->arg, "boot_archive") == NULL) { module = alloca(strlen(lp->arg) + 1); (void) strcpy(module, lp->arg); cvt_hyper_module(module, &kern_path); } else { barchive_path = alloca(strlen(lp->arg) + 1); (void) strcpy(barchive_path, lp->arg); } } else if ((strcmp(lp->cmd, menu_cmds[KERNEL_DOLLAR_CMD]) == 0) && (cvt_hyper_kernel(lp->arg) < 0)) { ret = BAM_NOCHANGE; goto abort; } if (lp == ent->end) break; } /* * If findroot, module or kern_path are NULL, the boot entry is * malformed. */ if (findroot == NULL) { bam_error(FINDROOT_NOT_FOUND, curdef); goto abort; } if (module == NULL) { bam_error(MODULE_NOT_PARSEABLE, curdef); goto abort; } if (kern_path == NULL) { bam_error(KERNEL_NOT_FOUND, curdef); goto abort; } /* * Assemble new kernel and module arguments from parsed values. * * First, change the kernel directory from the hypervisor version to * that needed for a metal kernel. */ newstr = modify_path(kern_path, HYPER_KERNEL_DIR, METAL_KERNEL_DIR); free(kern_path); kern_path = newstr; /* allocate initial space for the kernel path */ len = strlen(kern_path) + 1; zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0); if ((kernel = malloc(len + zfslen)) == NULL) { free(kern_path); bam_error(NO_MEM, len + zfslen); bam_exit(1); } (void) snprintf(kernel, len, "%s", kern_path); free(kern_path); if (zfs_boot) { char *zfsstr = alloca(zfslen + 1); (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT); (void) strcat(kernel, zfsstr); emit_bflag = 0; } /* * Process the bootenv.rc file to look for boot options that would be * the same as what the hypervisor had manually set, as we need not set * those explicitly. * * If there's no bootenv.rc, it's not an issue. */ parse_bootenvrc(osroot); /* * Don't emit a console setting if it's the same as what would be * set by bootenv.rc. */ if ((console_dev != NULL) && (bootenv_rc_console == NULL || (strcmp(console_dev, bootenv_rc_console) != 0))) { if (emit_bflag) { newstr = append_str(kernel, BFLAG, " "); free(kernel); kernel = append_str(newstr, "console=", " "); free(newstr); newstr = append_str(kernel, console_dev, ""); free(kernel); kernel = newstr; emit_bflag = 0; } else { newstr = append_str(kernel, "console=", ","); free(kernel); kernel = append_str(newstr, console_dev, ""); free(newstr); } } /* * We have to do some strange processing here because the hypervisor's * serial ports default to "9600,8,n,1,-" if "comX=auto" is specified, * or to "auto" if nothing is specified. * * This could result in a serial mode setting string being added when * it would otherwise not be needed, but it's better to play it safe. */ if (emit_bflag) { newstr = append_str(kernel, BFLAG, " "); free(kernel); kernel = newstr; delim = " "; emit_bflag = 0; } if ((serial_config[0] != NULL) && (bootenv_rc_serial[0] == NULL || (strcmp(serial_config[0], bootenv_rc_serial[0]) != 0))) { newstr = append_str(kernel, "ttya-mode='", delim); free(kernel); /* * Pass the serial configuration as the delimiter to * append_str() as it will be inserted between the current * string and the string we're appending, in this case the * closing single quote. */ kernel = append_str(newstr, "'", serial_config[0]); free(newstr); delim = ","; } if ((serial_config[1] != NULL) && (bootenv_rc_serial[1] == NULL || (strcmp(serial_config[1], bootenv_rc_serial[1]) != 0))) { newstr = append_str(kernel, "ttyb-mode='", delim); free(kernel); /* * Pass the serial configuration as the delimiter to * append_str() as it will be inserted between the current * string and the string we're appending, in this case the * closing single quote. */ kernel = append_str(newstr, "'", serial_config[1]); free(newstr); delim = ","; } /* shut off warning messages from the entry line parser */ if (ent->flags & BAM_ENTRY_BOOTADM) ent->flags &= ~BAM_ENTRY_BOOTADM; BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel)); BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, module)); if ((newdef = add_boot_entry(mp, title, findroot, kernel, NULL, barchive_path, bootfs)) == BAM_ERROR) { free(kernel); return (newdef); } /* * Now try to delete the current default entry from the menu and add * the new hypervisor entry with the parameters we've setup. */ if (delete_boot_entry(mp, curdef, DBE_QUIET) == BAM_SUCCESS) newdef--; else bam_print(NEW_BOOT_ENTRY, title); free(kernel); /* * If we successfully created the new entry, set the default boot * entry to that entry and let the caller know the new menu should * be written out. */ return (set_global(mp, menu_cmds[DEFAULT_CMD], newdef)); abort: if (ret != BAM_NOCHANGE) bam_error(METAL_ABORT, osroot); return (ret); }
error_t cvt_to_hyper(menu_t *mp, char *osroot, char *extra_args) { const char *fcn = "cvt_to_hyper()"; line_t *lp; entry_t *ent; size_t len, zfslen; char *newstr; char *osdev; char *title = NULL; char *findroot = NULL; char *bootfs = NULL; char *kernel = NULL; char *mod_kernel = NULL; char *module = NULL; char *kern_path = NULL; char *kern_bargs = NULL; int curdef, newdef; int kp_allocated = 0; int ret = BAM_ERROR; assert(osroot); BAM_DPRINTF((D_FUNC_ENTRY2, fcn, osroot, extra_args)); /* * First just check to verify osroot is a sane directory. */ if ((osdev = get_special(osroot)) == NULL) { bam_error(CANT_FIND_SPECIAL, osroot); return (BAM_ERROR); } free(osdev); /* * While the effect is purely cosmetic, if osroot is "/" don't * bother prepending it to any paths as they are constructed to * begin with "/" anyway. */ if (strcmp(osroot, "/") == 0) osroot = ""; /* * Found the GRUB signature on the target partitions, so now get the * default GRUB boot entry number from the menu.lst file */ curdef = atoi(mp->curdefault->arg); /* look for the first line of the matching boot entry */ for (ent = mp->entries; ((ent != NULL) && (ent->entryNum != curdef)); ent = ent->next) ; /* couldn't find it, so error out */ if (ent == NULL) { bam_error(CANT_FIND_DEFAULT, curdef); goto abort; } /* * We found the proper menu entry, so first we need to process the * bootenv.rc file to look for boot options the hypervisor might need * passed as kernel start options such as the console device and serial * port parameters. * * If there's no bootenv.rc, it's not an issue. */ parse_bootenvrc(osroot); if (bootenv_rc_console != NULL) console_metal_to_hyper(bootenv_rc_console); if (bootenv_rc_serial[0] != NULL) (void) serial_metal_to_hyper("ttya-mode", bootenv_rc_serial[0]); if (bootenv_rc_serial[1] != NULL) (void) serial_metal_to_hyper("ttyb-mode", bootenv_rc_serial[1]); /* * Now process the entry itself. */ for (lp = ent->start; lp != NULL; lp = lp->next) { /* * Process important lines from menu.lst boot entry. */ if (lp->flags == BAM_TITLE) { title = alloca(strlen(lp->arg) + 1); (void) strcpy(title, lp->arg); } else if (strcmp(lp->cmd, "findroot") == 0) { findroot = alloca(strlen(lp->arg) + 1); (void) strcpy(findroot, lp->arg); } else if (strcmp(lp->cmd, "bootfs") == 0) { bootfs = alloca(strlen(lp->arg) + 1); (void) strcpy(bootfs, lp->arg); } else if (strcmp(lp->cmd, menu_cmds[MODULE_DOLLAR_CMD]) == 0) { module = alloca(strlen(lp->arg) + 1); (void) strcpy(module, lp->arg); } else if ((strcmp(lp->cmd, menu_cmds[KERNEL_DOLLAR_CMD]) == 0) && (ret = cvt_metal_kernel(lp->arg, &kern_path)) != 0) { if (ret < 0) { ret = BAM_ERROR; bam_error(KERNEL_NOT_PARSEABLE, curdef); } else ret = BAM_NOCHANGE; goto abort; } if (lp == ent->end) break; } /* * If findroot, module or kern_path are NULL, the boot entry is * malformed. */ if (findroot == NULL) { bam_error(FINDROOT_NOT_FOUND, curdef); goto abort; } if (module == NULL) { bam_error(MODULE_NOT_PARSEABLE, curdef); goto abort; } if (kern_path == NULL) { bam_error(KERNEL_NOT_FOUND, curdef); goto abort; } /* assemble new kernel and module arguments from parsed values */ if (console_dev != NULL) { kern_bargs = s_strdup(console_dev); if (serial_config[0] != NULL) { newstr = append_str(kern_bargs, serial_config[0], " "); free(kern_bargs); kern_bargs = newstr; } if (serial_config[1] != NULL) { newstr = append_str(kern_bargs, serial_config[1], " "); free(kern_bargs); kern_bargs = newstr; } } if ((extra_args != NULL) && (*extra_args != NULL)) { newstr = append_str(kern_bargs, extra_args, " "); free(kern_bargs); kern_bargs = newstr; } len = strlen(osroot) + strlen(XEN_MENU) + strlen(kern_bargs) + WHITESPC(1) + 1; kernel = alloca(len); if (kern_bargs != NULL) { if (*kern_bargs != NULL) (void) snprintf(kernel, len, "%s%s %s", osroot, XEN_MENU, kern_bargs); free(kern_bargs); } else { (void) snprintf(kernel, len, "%s%s", osroot, XEN_MENU); } /* * Change the kernel directory from the metal version to that needed for * the hypervisor. Convert either "direct boot" path to the default * path. */ if ((strcmp(kern_path, DIRECT_BOOT_32) == 0) || (strcmp(kern_path, DIRECT_BOOT_64) == 0)) { kern_path = HYPERVISOR_KERNEL; } else { newstr = modify_path(kern_path, METAL_KERNEL_DIR, HYPER_KERNEL_DIR); free(kern_path); kern_path = newstr; kp_allocated = 1; } /* * We need to allocate space for the kernel path (twice) plus an * intervening space, possibly the ZFS boot string, and NULL, * of course. */ len = (strlen(kern_path) * 2) + WHITESPC(1) + 1; zfslen = (zfs_boot ? (WHITESPC(1) + strlen(ZFS_BOOT)) : 0); mod_kernel = alloca(len + zfslen); (void) snprintf(mod_kernel, len, "%s %s", kern_path, kern_path); if (kp_allocated) free(kern_path); if (zfs_boot) { char *zfsstr = alloca(zfslen + 1); (void) snprintf(zfsstr, zfslen + 1, " %s", ZFS_BOOT); (void) strcat(mod_kernel, zfsstr); } /* shut off warning messages from the entry line parser */ if (ent->flags & BAM_ENTRY_BOOTADM) ent->flags &= ~BAM_ENTRY_BOOTADM; BAM_DPRINTF((D_CVT_CMD_KERN_DOLLAR, fcn, kernel)); BAM_DPRINTF((D_CVT_CMD_MOD_DOLLAR, fcn, mod_kernel)); if ((newdef = add_boot_entry(mp, title, findroot, kernel, mod_kernel, module, bootfs)) == BAM_ERROR) return (newdef); /* * Now try to delete the current default entry from the menu and add * the new hypervisor entry with the parameters we've setup. */ if (delete_boot_entry(mp, curdef, DBE_QUIET) == BAM_SUCCESS) newdef--; else bam_print(NEW_BOOT_ENTRY, title); /* * If we successfully created the new entry, set the default boot * entry to that entry and let the caller know the new menu should * be written out. */ return (set_global(mp, menu_cmds[DEFAULT_CMD], newdef)); abort: if (ret != BAM_NOCHANGE) bam_error(HYPER_ABORT, ((*osroot == NULL) ? "/" : osroot)); return (ret); }