/* * VasEBoot -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. * * VasEBoot is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VasEBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VasEBoot. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma GCC diagnostic ignored "-Wformat-nonliteral" char * VasEBoot_install_help_filter (int key, const char *text, void *input __attribute__ ((unused))) { switch (key) { case VasEBoot_INSTALL_OPTIONS_INSTALL_THEMES: return xasprintf(text, "starfield"); case VasEBoot_INSTALL_OPTIONS_INSTALL_FONTS: return xasprintf(text, "unicode"); case VasEBoot_INSTALL_OPTIONS_DIRECTORY: case VasEBoot_INSTALL_OPTIONS_DIRECTORY2: return xasprintf(text, VasEBoot_util_get_pkglibdir ()); case VasEBoot_INSTALL_OPTIONS_LOCALE_DIRECTORY: return xasprintf(text, VasEBoot_util_get_localedir ()); case VasEBoot_INSTALL_OPTIONS_THEMES_DIRECTORY: return VasEBoot_util_path_concat (2, VasEBoot_util_get_pkgdatadir (), "themes"); default: return (char *) text; } } #pragma GCC diagnostic error "-Wformat-nonliteral" static int (*compress_func) (const char *src, const char *dest) = NULL; char *VasEBoot_install_copy_buffer; int VasEBoot_install_copy_file (const char *src, const char *dst, int is_needed) { VasEBoot_util_fd_t in, out; ssize_t r; VasEBoot_util_info ("copying `%s' -> `%s'", src, dst); in = VasEBoot_util_fd_open (src, VasEBoot_UTIL_FD_O_RDONLY); if (!VasEBoot_UTIL_FD_IS_VALID (in)) { if (is_needed) VasEBoot_util_error (_("cannot open `%s': %s"), src, VasEBoot_util_fd_strerror ()); else VasEBoot_util_info (_("cannot open `%s': %s"), src, VasEBoot_util_fd_strerror ()); return 0; } out = VasEBoot_util_fd_open (dst, VasEBoot_UTIL_FD_O_WRONLY | VasEBoot_UTIL_FD_O_CREATTRUNC); if (!VasEBoot_UTIL_FD_IS_VALID (out)) { VasEBoot_util_error (_("cannot open `%s': %s"), dst, VasEBoot_util_fd_strerror ()); VasEBoot_util_fd_close (in); return 0; } if (!VasEBoot_install_copy_buffer) VasEBoot_install_copy_buffer = xmalloc (VasEBoot_INSTALL_COPY_BUFFER_SIZE); while (1) { r = VasEBoot_util_fd_read (in, VasEBoot_install_copy_buffer, VasEBoot_INSTALL_COPY_BUFFER_SIZE); if (r <= 0) break; VasEBoot_util_fd_write (out, VasEBoot_install_copy_buffer, r); } VasEBoot_util_fd_sync (out); VasEBoot_util_fd_close (in); VasEBoot_util_fd_close (out); if (r < 0) VasEBoot_util_error (_("cannot copy `%s' to `%s': %s"), src, dst, VasEBoot_util_fd_strerror ()); return 1; } static int VasEBoot_install_compress_file (const char *in_name, const char *out_name, int is_needed) { int ret; if (!compress_func) ret = VasEBoot_install_copy_file (in_name, out_name, is_needed); else { VasEBoot_util_info ("compressing `%s' -> `%s'", in_name, out_name); ret = !compress_func (in_name, out_name); if (!ret && is_needed) VasEBoot_util_warn (_("can't compress `%s' to `%s'"), in_name, out_name); } if (!ret && is_needed) VasEBoot_util_error (_("cannot copy `%s' to `%s': %s"), in_name, out_name, VasEBoot_util_fd_strerror ()); return ret; } static int is_path_separator (char c) { #if defined (__MINGW32__) || defined (__CYGWIN__) if (c == '\\') return 1; #endif if (c == '/') return 1; return 0; } void VasEBoot_install_mkdir_p (const char *dst) { char *t = xstrdup (dst); char *p; for (p = t; *p; p++) { if (is_path_separator (*p)) { char s = *p; *p = '\0'; VasEBoot_util_mkdir (t); *p = s; } } VasEBoot_util_mkdir (t); free (t); } static void clean_VasEBoot_dir (const char *di) { VasEBoot_util_fd_dir_t d; VasEBoot_util_fd_dirent_t de; d = VasEBoot_util_fd_opendir (di); if (!d) VasEBoot_util_error (_("cannot open directory `%s': %s"), di, VasEBoot_util_fd_strerror ()); while ((de = VasEBoot_util_fd_readdir (d))) { const char *ext = strrchr (de->d_name, '.'); if ((ext && (strcmp (ext, ".mod") == 0 || strcmp (ext, ".lst") == 0 || strcmp (ext, ".img") == 0 || strcmp (ext, ".mo") == 0) && strcmp (de->d_name, "menu.lst") != 0) || strcmp (de->d_name, "efiemu32.o") == 0 || strcmp (de->d_name, "efiemu64.o") == 0) { char *x = VasEBoot_util_path_concat (2, di, de->d_name); if (VasEBoot_util_unlink (x) < 0) VasEBoot_util_error (_("cannot delete `%s': %s"), x, VasEBoot_util_fd_strerror ()); free (x); } } VasEBoot_util_fd_closedir (d); } struct install_list { int is_default; char **entries; size_t n_entries; size_t n_alloc; }; struct install_list install_modules = { 1, 0, 0, 0 }; struct install_list modules = { 1, 0, 0, 0 }; struct install_list install_locales = { 1, 0, 0, 0 }; struct install_list install_fonts = { 1, 0, 0, 0 }; struct install_list install_themes = { 1, 0, 0, 0 }; char *VasEBoot_install_source_directory = NULL; char *VasEBoot_install_locale_directory = NULL; char *VasEBoot_install_themes_directory = NULL; void VasEBoot_install_push_module (const char *val) { modules.is_default = 0; if (modules.n_entries + 1 >= modules.n_alloc) { modules.n_alloc <<= 1; if (modules.n_alloc < 16) modules.n_alloc = 16; modules.entries = xrealloc (modules.entries, modules.n_alloc * sizeof (*modules.entries)); } modules.entries[modules.n_entries++] = xstrdup (val); modules.entries[modules.n_entries] = NULL; } void VasEBoot_install_pop_module (void) { modules.n_entries--; free (modules.entries[modules.n_entries]); modules.entries[modules.n_entries] = NULL; } static void handle_install_list (struct install_list *il, const char *val, int default_all) { const char *ptr; char **ce; il->is_default = 0; free (il->entries); il->entries = NULL; il->n_entries = 0; if (strcmp (val, "all") == 0 && default_all) { il->is_default = 1; return; } ptr = val; while (1) { while (*ptr && VasEBoot_isspace (*ptr)) ptr++; if (!*ptr) break; while (*ptr && !VasEBoot_isspace (*ptr)) ptr++; il->n_entries++; } il->n_alloc = il->n_entries + 1; il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); ptr = val; for (ce = il->entries; ; ce++) { const char *bptr; while (*ptr && VasEBoot_isspace (*ptr)) ptr++; if (!*ptr) break; bptr = ptr; while (*ptr && !VasEBoot_isspace (*ptr)) ptr++; *ce = xmalloc (ptr - bptr + 1); memcpy (*ce, bptr, ptr - bptr); (*ce)[ptr - bptr] = '\0'; } *ce = NULL; } static char **pubkeys; static size_t npubkeys; static VasEBoot_compression_t compression; int VasEBoot_install_parse (int key, char *arg) { switch (key) { case 'C': if (VasEBoot_strcmp (arg, "xz") == 0) { #ifdef HAVE_LIBLZMA compression = VasEBoot_COMPRESSION_XZ; #else VasEBoot_util_error ("%s", _("VasEBoot-mkimage is compiled without XZ support")); #endif } else if (VasEBoot_strcmp (arg, "none") == 0) compression = VasEBoot_COMPRESSION_NONE; else if (VasEBoot_strcmp (arg, "auto") == 0) compression = VasEBoot_COMPRESSION_AUTO; else VasEBoot_util_error (_("Unknown compression format %s"), arg); return 1; case 'k': pubkeys = xrealloc (pubkeys, sizeof (pubkeys[0]) * (npubkeys + 1)); pubkeys[npubkeys++] = xstrdup (arg); return 1; case VasEBoot_INSTALL_OPTIONS_VERBOSITY: verbosity++; return 1; case VasEBoot_INSTALL_OPTIONS_DIRECTORY: case VasEBoot_INSTALL_OPTIONS_DIRECTORY2: free (VasEBoot_install_source_directory); VasEBoot_install_source_directory = xstrdup (arg); return 1; case VasEBoot_INSTALL_OPTIONS_LOCALE_DIRECTORY: free (VasEBoot_install_locale_directory); VasEBoot_install_locale_directory = xstrdup (arg); return 1; case VasEBoot_INSTALL_OPTIONS_THEMES_DIRECTORY: free (VasEBoot_install_themes_directory); VasEBoot_install_themes_directory = xstrdup (arg); return 1; case VasEBoot_INSTALL_OPTIONS_INSTALL_MODULES: handle_install_list (&install_modules, arg, 0); return 1; case VasEBoot_INSTALL_OPTIONS_MODULES: handle_install_list (&modules, arg, 0); return 1; case VasEBoot_INSTALL_OPTIONS_INSTALL_LOCALES: handle_install_list (&install_locales, arg, 0); return 1; case VasEBoot_INSTALL_OPTIONS_INSTALL_THEMES: handle_install_list (&install_themes, arg, 0); return 1; case VasEBoot_INSTALL_OPTIONS_INSTALL_FONTS: handle_install_list (&install_fonts, arg, 0); return 1; case VasEBoot_INSTALL_OPTIONS_INSTALL_COMPRESS: if (strcmp (arg, "no") == 0 || strcmp (arg, "none") == 0) { compress_func = NULL; return 1; } if (strcmp (arg, "gz") == 0) { compress_func = VasEBoot_install_compress_gzip; return 1; } if (strcmp (arg, "xz") == 0) { compress_func = VasEBoot_install_compress_xz; return 1; } if (strcmp (arg, "lzo") == 0) { compress_func = VasEBoot_install_compress_lzop; return 1; } VasEBoot_util_error (_("Unrecognized compression `%s'"), arg); case VasEBoot_INSTALL_OPTIONS_VasEBoot_MKIMAGE: return 1; default: return 0; } } static int decompressors (void) { if (compress_func == VasEBoot_install_compress_gzip) { VasEBoot_install_push_module ("gzio"); return 1; } if (compress_func == VasEBoot_install_compress_xz) { VasEBoot_install_push_module ("xzio"); VasEBoot_install_push_module ("gcry_crc"); return 2; } if (compress_func == VasEBoot_install_compress_lzop) { VasEBoot_install_push_module ("lzopio"); VasEBoot_install_push_module ("adler32"); VasEBoot_install_push_module ("gcry_crc"); return 3; } return 0; } void VasEBoot_install_make_image_wrap_file (const char *dir, const char *prefix, FILE *fp, const char *outname, char *memdisk_path, char *config_path, const char *mkimage_target, int note) { const struct VasEBoot_install_image_target_desc *tgt; const char *const compnames[] = { [VasEBoot_COMPRESSION_AUTO] = "auto", [VasEBoot_COMPRESSION_NONE] = "none", [VasEBoot_COMPRESSION_XZ] = "xz", [VasEBoot_COMPRESSION_LZMA] = "lzma", }; VasEBoot_size_t slen = 1; char *s, *p; char **pk, **md; int dc = decompressors (); if (memdisk_path) slen += 20 + VasEBoot_strlen (memdisk_path); if (config_path) slen += 20 + VasEBoot_strlen (config_path); for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) slen += 20 + VasEBoot_strlen (*pk); for (md = modules.entries; *md; md++) { slen += 10 + VasEBoot_strlen (*md); } p = s = xmalloc (slen); if (memdisk_path) { p = VasEBoot_stpcpy (p, "--memdisk '"); p = VasEBoot_stpcpy (p, memdisk_path); *p++ = '\''; *p++ = ' '; } if (config_path) { p = VasEBoot_stpcpy (p, "--config '"); p = VasEBoot_stpcpy (p, config_path); *p++ = '\''; *p++ = ' '; } for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) { p = VasEBoot_stpcpy (p, "--pubkey '"); p = VasEBoot_stpcpy (p, *pk); *p++ = '\''; *p++ = ' '; } for (md = modules.entries; *md; md++) { *p++ = '\''; p = VasEBoot_stpcpy (p, *md); *p++ = '\''; *p++ = ' '; } *p = '\0'; VasEBoot_util_info ("VasEBoot-mkimage --directory '%s' --prefix '%s'" " --output '%s' " "--format '%s' --compression '%s' %s %s\n", dir, prefix, outname, mkimage_target, compnames[compression], note ? "--note" : "", s); free (s); tgt = VasEBoot_install_get_image_target (mkimage_target); if (!tgt) VasEBoot_util_error (_("unknown target format %s"), mkimage_target); VasEBoot_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, pubkeys, npubkeys, config_path, tgt, note, compression); while (dc--) VasEBoot_install_pop_module (); } void VasEBoot_install_make_image_wrap (const char *dir, const char *prefix, const char *outname, char *memdisk_path, char *config_path, const char *mkimage_target, int note) { FILE *fp; fp = VasEBoot_util_fopen (outname, "wb"); if (! fp) VasEBoot_util_error (_("cannot open `%s': %s"), outname, strerror (errno)); VasEBoot_install_make_image_wrap_file (dir, prefix, fp, outname, memdisk_path, config_path, mkimage_target, note); VasEBoot_util_file_sync (fp); fclose (fp); } static void copy_by_ext (const char *srcd, const char *dstd, const char *extf, int req) { VasEBoot_util_fd_dir_t d; VasEBoot_util_fd_dirent_t de; d = VasEBoot_util_fd_opendir (srcd); if (!d && !req) return; if (!d) VasEBoot_util_error (_("cannot open directory `%s': %s"), srcd, VasEBoot_util_fd_strerror ()); while ((de = VasEBoot_util_fd_readdir (d))) { const char *ext = strrchr (de->d_name, '.'); if (ext && strcmp (ext, extf) == 0) { char *srcf = VasEBoot_util_path_concat (2, srcd, de->d_name); char *dstf = VasEBoot_util_path_concat (2, dstd, de->d_name); VasEBoot_install_compress_file (srcf, dstf, 1); free (srcf); free (dstf); } } VasEBoot_util_fd_closedir (d); } static void copy_all (const char *srcd, const char *dstd) { VasEBoot_util_fd_dir_t d; VasEBoot_util_fd_dirent_t de; d = VasEBoot_util_fd_opendir (srcd); if (!d) VasEBoot_util_error (_("cannot open directory `%s': %s"), srcd, VasEBoot_util_fd_strerror ()); while ((de = VasEBoot_util_fd_readdir (d))) { char *srcf; char *dstf; if (strcmp (de->d_name, ".") == 0 || strcmp (de->d_name, "..") == 0) continue; srcf = VasEBoot_util_path_concat (2, srcd, de->d_name); if (VasEBoot_util_is_special_file (srcf) || VasEBoot_util_is_directory (srcf)) continue; dstf = VasEBoot_util_path_concat (2, dstd, de->d_name); VasEBoot_install_compress_file (srcf, dstf, 1); free (srcf); free (dstf); } VasEBoot_util_fd_closedir (d); } static const char * get_localedir (void) { if (VasEBoot_install_locale_directory) return VasEBoot_install_locale_directory; else return VasEBoot_util_get_localedir (); } static void copy_locales (const char *dstd) { VasEBoot_util_fd_dir_t d; VasEBoot_util_fd_dirent_t de; const char *locale_dir = get_localedir (); d = VasEBoot_util_fd_opendir (locale_dir); if (!d) { VasEBoot_util_warn (_("cannot open directory `%s': %s"), locale_dir, VasEBoot_util_fd_strerror ()); return; } while ((de = VasEBoot_util_fd_readdir (d))) { char *srcf; char *dstf; char *ext; if (strcmp (de->d_name, ".") == 0) continue; if (strcmp (de->d_name, "..") == 0) continue; ext = VasEBoot_strrchr (de->d_name, '.'); if (ext && (VasEBoot_strcmp (ext, ".mo") == 0 || VasEBoot_strcmp (ext, ".gmo") == 0)) { srcf = VasEBoot_util_path_concat (2, locale_dir, de->d_name); dstf = VasEBoot_util_path_concat (2, dstd, de->d_name); ext = VasEBoot_strrchr (dstf, '.'); VasEBoot_strcpy (ext, ".mo"); } else { srcf = VasEBoot_util_path_concat_ext (4, locale_dir, de->d_name, "LC_MESSAGES", PACKAGE, ".mo"); dstf = VasEBoot_util_path_concat_ext (2, dstd, de->d_name, ".mo"); } VasEBoot_install_compress_file (srcf, dstf, 0); free (srcf); free (dstf); } VasEBoot_util_fd_closedir (d); } static struct { const char *cpu; const char *platform; } platforms[VasEBoot_INSTALL_PLATFORM_MAX] = { [VasEBoot_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, [VasEBoot_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, [VasEBoot_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, [VasEBoot_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, [VasEBoot_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, [VasEBoot_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, [VasEBoot_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, [VasEBoot_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, [VasEBoot_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, [VasEBoot_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, [VasEBoot_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, [VasEBoot_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, [VasEBoot_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, [VasEBoot_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, [VasEBoot_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, [VasEBoot_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, [VasEBoot_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, [VasEBoot_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, [VasEBoot_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, [VasEBoot_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, }; char * VasEBoot_install_get_platforms_string (void) { char **arr = xmalloc (sizeof (char *) * ARRAY_SIZE (platforms)); int platform_strins_len = 0; char *platforms_string; char *ptr; unsigned i; for (i = 0; i < ARRAY_SIZE (platforms); i++) { arr[i] = xasprintf ("%s-%s", platforms[i].cpu, platforms[i].platform); platform_strins_len += strlen (arr[i]) + 2; } ptr = platforms_string = xmalloc (platform_strins_len); qsort (arr, ARRAY_SIZE (platforms), sizeof (char *), VasEBoot_qsort_strcmp); for (i = 0; i < ARRAY_SIZE (platforms); i++) { strcpy (ptr, arr[i]); ptr += strlen (arr[i]); *ptr++ = ','; *ptr++ = ' '; free (arr[i]); } ptr[-2] = 0; free (arr); return platforms_string; } char * VasEBoot_install_get_platform_name (enum VasEBoot_install_plat platid) { return xasprintf ("%s-%s", platforms[platid].cpu, platforms[platid].platform); } const char * VasEBoot_install_get_platform_cpu (enum VasEBoot_install_plat platid) { return platforms[platid].cpu; } const char * VasEBoot_install_get_platform_platform (enum VasEBoot_install_plat platid) { return platforms[platid].platform; } void VasEBoot_install_copy_files (const char *src, const char *dst, enum VasEBoot_install_plat platid) { char *dst_platform, *dst_locale, *dst_fonts; const char *pkgdatadir = VasEBoot_util_get_pkgdatadir (); char *themes_dir; { char *platform; platform = xasprintf ("%s-%s", platforms[platid].cpu, platforms[platid].platform); dst_platform = VasEBoot_util_path_concat (2, dst, platform); free (platform); } dst_locale = VasEBoot_util_path_concat (2, dst, "locale"); dst_fonts = VasEBoot_util_path_concat (2, dst, "fonts"); VasEBoot_install_mkdir_p (dst_platform); VasEBoot_install_mkdir_p (dst_locale); clean_VasEBoot_dir (dst); clean_VasEBoot_dir (dst_platform); clean_VasEBoot_dir (dst_locale); if (install_modules.is_default) copy_by_ext (src, dst_platform, ".mod", 1); else { struct VasEBoot_util_path_list *path_list, *p; path_list = VasEBoot_util_resolve_dependencies (src, "moddep.lst", install_modules.entries); for (p = path_list; p; p = p->next) { const char *srcf = p->name; const char *dir; char *dstf; dir = VasEBoot_strrchr (srcf, '/'); if (dir) dir++; else dir = srcf; dstf = VasEBoot_util_path_concat (2, dst_platform, dir); VasEBoot_install_compress_file (srcf, dstf, 1); free (dstf); } VasEBoot_util_free_path_list (path_list); } const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o", "moddep.lst", "command.lst", "fs.lst", "partmap.lst", "parttool.lst", "video.lst", "crypto.lst", "terminal.lst", "modinfo.sh" }; size_t i; for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++) { char *srcf = VasEBoot_util_path_concat (2, src, pkglib_DATA[i]); char *dstf = VasEBoot_util_path_concat (2, dst_platform, pkglib_DATA[i]); if (i == 0 || i == 1) VasEBoot_install_compress_file (srcf, dstf, 0); else VasEBoot_install_compress_file (srcf, dstf, 1); free (srcf); free (dstf); } if (install_locales.is_default) { char *srcd = VasEBoot_util_path_concat (2, src, "po"); copy_by_ext (srcd, dst_locale, ".mo", 0); copy_locales (dst_locale); free (srcd); } else { const char *locale_dir = get_localedir (); for (i = 0; i < install_locales.n_entries; i++) { char *srcf = VasEBoot_util_path_concat_ext (3, src, "po", install_locales.entries[i], ".mo"); char *dstf = VasEBoot_util_path_concat_ext (2, dst_locale, install_locales.entries[i], ".mo"); if (VasEBoot_install_compress_file (srcf, dstf, 0)) { free (srcf); free (dstf); continue; } free (srcf); srcf = VasEBoot_util_path_concat_ext (4, locale_dir, install_locales.entries[i], "LC_MESSAGES", PACKAGE, ".mo"); if (VasEBoot_install_compress_file (srcf, dstf, 0)) { free (srcf); free (dstf); continue; } VasEBoot_util_error (_("cannot find locale `%s'"), install_locales.entries[i]); } } if (install_themes.is_default) { install_themes.is_default = 0; install_themes.n_entries = 1; install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0])); install_themes.entries[0] = xstrdup ("starfield"); install_themes.entries[1] = NULL; } if (VasEBoot_install_themes_directory) themes_dir = xstrdup (VasEBoot_install_themes_directory); else themes_dir = VasEBoot_util_path_concat (2, VasEBoot_util_get_pkgdatadir (), "themes"); for (i = 0; i < install_themes.n_entries; i++) { char *srcf = VasEBoot_util_path_concat (3, themes_dir, install_themes.entries[i], "theme.txt"); if (VasEBoot_util_is_regular (srcf)) { char *srcd = VasEBoot_util_path_concat (2, themes_dir, install_themes.entries[i]); char *dstd = VasEBoot_util_path_concat (3, dst, "themes", install_themes.entries[i]); VasEBoot_install_mkdir_p (dstd); copy_all (srcd, dstd); free (srcd); free (dstd); } free (srcf); } free (themes_dir); if (install_fonts.is_default) { install_fonts.is_default = 0; install_fonts.n_entries = 1; install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0])); install_fonts.entries[0] = xstrdup ("unicode"); install_fonts.entries[1] = NULL; } VasEBoot_install_mkdir_p (dst_fonts); for (i = 0; i < install_fonts.n_entries; i++) { char *srcf = VasEBoot_util_path_concat_ext (2, pkgdatadir, install_fonts.entries[i], ".pf2"); char *dstf = VasEBoot_util_path_concat_ext (2, dst_fonts, install_fonts.entries[i], ".pf2"); VasEBoot_install_compress_file (srcf, dstf, 0); free (srcf); free (dstf); } free (dst_platform); free (dst_locale); free (dst_fonts); } enum VasEBoot_install_plat VasEBoot_install_get_target (const char *src) { char *fn; VasEBoot_util_fd_t f; char buf[8192]; ssize_t r; char *c, *pl, *p; size_t i; fn = VasEBoot_util_path_concat (2, src, "modinfo.sh"); f = VasEBoot_util_fd_open (fn, VasEBoot_UTIL_FD_O_RDONLY); if (!VasEBoot_UTIL_FD_IS_VALID (f)) VasEBoot_util_error (_("%s doesn't exist. Please specify --target or --directory"), fn); r = VasEBoot_util_fd_read (f, buf, sizeof (buf) - 1); if (r < 0) VasEBoot_util_error (_("cannot read `%s': %s"), fn, strerror (errno)); VasEBoot_util_fd_close (f); buf[r] = '\0'; c = strstr (buf, "VasEBoot_modinfo_target_cpu="); if (!c || (c != buf && !VasEBoot_isspace (*(c-1)))) VasEBoot_util_error (_("invalid modinfo file `%s'"), fn); pl = strstr (buf, "VasEBoot_modinfo_platform="); if (!pl || (pl != buf && !VasEBoot_isspace (*(pl-1)))) VasEBoot_util_error (_("invalid modinfo file `%s'"), fn); c += sizeof ("VasEBoot_modinfo_target_cpu=") - 1; pl += sizeof ("VasEBoot_modinfo_platform=") - 1; for (p = c; *p && !VasEBoot_isspace (*p); p++); *p = '\0'; for (p = pl; *p && !VasEBoot_isspace (*p); p++); *p = '\0'; for (i = 0; i < ARRAY_SIZE (platforms); i++) if (strcmp (platforms[i].cpu, c) == 0 && strcmp (platforms[i].platform, pl) == 0) { free (fn); return i; } VasEBoot_util_error (_("Unknown platform `%s-%s'"), c, pl); } void VasEBoot_util_unlink_recursive (const char *name) { VasEBoot_util_fd_dir_t d; VasEBoot_util_fd_dirent_t de; d = VasEBoot_util_fd_opendir (name); while ((de = VasEBoot_util_fd_readdir (d))) { char *fp; if (strcmp (de->d_name, ".") == 0) continue; if (strcmp (de->d_name, "..") == 0) continue; fp = VasEBoot_util_path_concat (2, name, de->d_name); if (VasEBoot_util_is_special_file (fp)) { free (fp); continue; } if (VasEBoot_util_is_regular (fp)) VasEBoot_util_unlink (fp); else if (VasEBoot_util_is_directory (fp)) VasEBoot_util_unlink_recursive (fp); free (fp); } VasEBoot_util_rmdir (name); VasEBoot_util_fd_closedir (d); }