diff --git a/ChangeLog b/ChangeLog index a8fab4bcc..53a664d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,616 @@ +2010-05-19 BVK Chaitanya + + Fix grub-mkrescue usage unit testing. + + * tests/util/grub-shell.in: Use --grub-mkimage with grub-mkrescue. + +2010-05-18 Christian Franke + + * util/grub.d/10_windows.in: Use path names instead of + drive letters to prevent warning from Cygwin 1.7. + Add drivemap command to menuentry if needed. + +2010-05-18 Justus Winter <4winter@informatik.uni-hamburg.de> + + * util/grub.d/10_hurd.in: Include all gnumach* kernels, not only + gnumach and gnumach.gz. + +2010-05-18 Vladimir Serbinenko + + * include/grub/i18n.h (gettext): Inline instead of using #define. + (grub_gettext): Likewise. + (_): Likewise. + +2010-05-18 Vladimir Serbinenko + + * Makefile.in (CPPFLAGS): Replace -DGRUB_LIBDIR with + -DGRUB_PKGLIBROOTDIR= and prepend @PACKAGE_TARNAME@. All users updated. + * util/grub-mkimage.c (image_targets): Add i386-multiboot. + (main): Add a slash after pkglibdirroot. + +2010-05-18 Vladimir Serbinenko + + * util/grub-install.in: Add missing "in" keyword. + +2010-05-18 Vladimir Serbinenko + + * util/grub-mkrescue.in: Remove -O i386-pc duplication. + Reported by: Seth Goldberg. + +2010-05-18 Vladimir Serbinenko + + * po/POTFILES: Rename util/grub-mkrawimage.c to util/grub-mkimage.c. + +2010-05-18 Colin Watson + + * configure.ac: Check for Linux device-mapper support. + + * util/hostdisk.c (device_is_mapped): New function. + (find_partition_start): New function, partly broken out from + linux_find_partition and grub_util_biosdisk_get_grub_dev but with + device-mapper support added. + (linux_find_partition): Use find_partition_start. + (convert_system_partition_to_system_disk): Add `st' argument. + Support Linux /dev/mapper/* devices if device-mapper support is + available; only DM-RAID devices are understood at present. + (find_system_device): Add `st' argument. Pass it to + convert_system_partition_to_system_disk. + (grub_util_biosdisk_get_grub_dev): Pass stat result to + find_system_device and convert_system_partition_to_system_disk. Use + find_partition_start. + + * conf/common.rmk (grub_mkdevicemap_SOURCES): Add kern/env.c, + kern/err.c, kern/list.c, kern/misc.c, and kern/emu/mm.c. + * util/deviceiter.c [__linux__]: Define MINOR. + (grub_util_iterate_devices): Add support for DM-RAID disk devices. + * util/mkdevicemap.c (grub_putchar): New function. + (grub_getkey): New function. + (grub_refresh): New function. + (main): Set debug=all if -v -v is used. + +2010-05-18 Colin Watson + + Fix build with non-GNU libcs. + + * util/misc.c (canonicalize_file_name): Move to ... + * kern/emu/misc.c (canonicalize_file_name): ... here. Needed by + grub_make_system_path_relative_to_its_root. + +2010-05-18 Colin Watson + + * util/grub-mkrescue.in: Sync up with grub-install in terms of how + we handle finding grub-mkimage. Default to finding grub-mkimage in + ${bindir} with program_transform_name applied, and provide a + --grub-mkimage option to override this. + +2010-05-17 Vladimir Serbinenko + + Remove grub-mkisofs. + + * conf/common.rmk (bin_UTILITIES): Remove grub-mkisofs. + (grub_mkisofs_SOURCES): Removed. + (grub_mkisofs_CFLAGS): Removed. + * util/mkisofs/defaults.h: Removed. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/include/: Likewise. + * util/mkisofs/include/fctldefs.h: Likewise. + * util/mkisofs/include/mconfig.h: Likewise. + * util/mkisofs/include/prototyp.h: Likewise. + * util/mkisofs/include/statdefs.h: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/match.c: Likewise. + * util/mkisofs/match.h: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/msdos_partition.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + +2010-05-17 Vladimir Serbinenko + + Unify grub-mkimage accross platforms. + + * Makefile.in (CPPFLAGS): Set GRUB_LIBDIR to $(libdir). + * conf/common.rmk (bin_UTILITIES): Removed grub-mkelfimage. + (grub_mkelfimage_SOURCES): Removed. + (util/elf/grub-mkimage.c_DEPENDENCIES): Renamed to .. + (util/grub-mkimage.c_DEPENDENCIES): .. this. + (bin_UTILITIES): Add grub-mkimage. + (grub_mkimage_SOURCES): New variable. + (kernel_img_HEADERS): Remove machine/kernel.h. + * conf/i386-pc.rmk (pkglib_IMAGES): Remove kernel.img. + (pkglib_PROGRAMS): Add kernel.img. + (kernel_img_HEADERS): Add machine/kernel.h. + (kernel_img_FORMAT): Removed. + (bin_UTILITIES): Remove grub-mkimage. + (grub_mkimage_SOURCES): Removed. + (grub_mkimage_CFLAGS): Likewise. + (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. + * conf/i386-qemu.rmk (pkglib_IMAGES): Remove kernel.img. + (pkglib_PROGRAMS): Add kernel.img. + (bin_UTILITIES): Remove grub-mkimage. + (grub_mkimage_SOURCES): Removed. + (grub_mkimage_CFLAGS): Likewise. + (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. + * conf/mips-qemu-mips.rmk (pkglib_IMAGES): Remove kernel.img. + (pkglib_PROGRAMS): Add kernel.img. + * conf/mips-yeeloong.rmk (pkglib_IMAGES): Remove kernel.img. + (pkglib_PROGRAMS): Add kernel.img. + * conf/mips.rmk (bin_UTILITIES): Remove grub-mkimage. + (grub_mkimage_SOURCES): Removed. + (grub_mkimage_CFLAGS): Likewise. + (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. + * conf/sparc64-ieee1275.rmk (pkglib_IMAGES): Remove kernel.img. + (pkglib_PROGRAMS): Add kernel.img. + (bin_UTILITIES): Remove grub-mkimage. + (grub_mkimage_SOURCES): Removed. + (grub_mkimage_CFLAGS): Likewise. + (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. + * conf/x86-efi.rmk (bin_UTILITIES): Remove grub-mkimage. + (grub_mkimage_SOURCES): Removed. + (grub_mkimage_CFLAGS): Likewise. + (util/grub-mkrawimage.c_DEPENDENCIES): Likewise. + * configure.ac (machine_CFLAGS): Add "-DMACHINE". + * include/grub/efi/pe32.h (grub_pe32_optional_header): Split into ... + (grub_pe32_optional_header): ... this. + (grub_pe64_optional_header): ... and this. All users updated. + (GRUB_PE32_PE32_MAGIC): Split into .. + (GRUB_PE32_PE32_MAGIC): .. this. + (GRUB_PE32_PE64_MAGIC): .. and this. + (GRUB_PE32_SIGNATURE_SIZE): New definition. + * include/grub/elf.h (PT_GNU_STACK): New definition. + * include/grub/i386/coreboot/kernel.h: Merged into include/grub/offsets.h. All users updated. + * include/grub/i386/efi/kernel.h: Likewise. + * include/grub/i386/kernel.h: Likewise. + * include/grub/i386/pc/kernel.h: Likewise. + * include/grub/i386/qemu/boot.h: Likewise. + * include/grub/mips/kernel.h: Likewise. + * include/grub/mips/qemu-mips/kernel.h: Likewise. + * include/grub/powerpc/ieee1275/kernel.h: Likewise. + * include/grub/powerpc/kernel.h: Likewise. + * include/grub/sparc64/ieee1275/boot.h: Likewise. + * include/grub/sparc64/ieee1275/kernel.h: Likewise. + * include/grub/sparc64/kernel.h: Likewise. + * include/grub/x86_64/efi/kernel.h: Likewise. + * include/grub/x86_64/kernel.h: Likewise. + * include/grub/offsets.h: New file. + * include/grub/kernel.h (grub_module_info): Split into ... + (grub_module_info32): ... this. + (grub_module_info64): ... and this. + * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_KERNEL_SEG): Moved from here ... + * include/grub/offsets.h (GRUB_BOOT_I386_PC_KERNEL_SEG): ... here. + (grub_boot_blocklist): Moved from here ... + * include/grub/offsets.h (grub_pc_bios_boot_blocklist): ... here. + * include/grub/i386/pc/memory.h (GRUB_MEMORY_MACHINE_UPPER): Moved from here. + * include/grub/offsets.h (GRUB_MEMORY_I386_PC_UPPER): .. here. + * include/grub/types.h (grub_target_to_host16): Removed. + (grub_target_to_host32): Likewise. + (grub_target_to_host64): Likewise. + (grub_host_to_target16): Likewise. + (grub_host_to_target32): Likewise. + (grub_host_to_target64): Likewise. + (grub_host_to_target_addr): Likewise. + + Support grub-mkrescue for efi, coreboot and qemu. + + * conf/x86-efi.rmk (bin_SCRIPTS): Add grub-mkrescue. + * kern/efi/init.c (grub_efi_set_prefix): Handle baked in prefix. + * util/elf/grub-mkimage.c: Merged into util/grub-mkimage.c. + * util/grub-mkrawimage.c: Moved from here ... + * util/grub-mkimage.c: ... here. All users updated. + (ALIGN_ADDR): Use image_target. + (TARGET_NO_FIELD): New const. + (image_target_desc): New type. + (image_targets): New array. + (grub_target_to_host64): Use image_target. + (grub_target_to_host32): Likewise. + (grub_target_to_host16): Likewise. + (grub_host_to_target64): Likewise. + (grub_host_to_target32): Likewise. + (grub_host_to_target16): Likewise. + (grub_host_to_target_addr): Likewise. + (generate_image): Handle multiimage. + (main): Require -O parameter. All users updated. + * util/grub-mkimagexx.c: New file. Based on util/grub-mkrawimage.c and + util/efi/grub-mkimage.c + * util/grub-mkrescue.in: Handle coreboot, efi and qemu. + New option --rom-directory. + Use xorriso. + * util/i386/efi/grub-mkimage.c: Removed. + * util/i386/pc/grub-setup.c (grub_target_to_host16): New definition. + (grub_target_to_host32): Likewise. + (grub_target_to_host64): Likewise. + (grub_host_to_target16): Likewise. + (grub_host_to_target32): Likewise. + (grub_host_to_target64): Likewise. + * util/sparc64/ieee1275/grub-setup.c (grub_target_to_host16): New definition. + (grub_target_to_host32): Likewise. + (grub_target_to_host64): Likewise. + (grub_host_to_target16): Likewise. + (grub_host_to_target32): Likewise. + (grub_host_to_target64): Likewise. + +2010-05-17 BVK Chaitanya + + Source tree is reorganized for emu build. + + * include/grub/util/console.h: Move from here... + * include/grub/emu/console.h: ...to here. + * include/grub/util/getroot.h: Move from here... + * include/grub/emu/getroot.h: ...to here. + * include/grub/util/hostdisk.h: Move from here... + * include/grub/emu/hostdisk.h: ...to here. + * util/console.c: Move from here... + * kern/emu/console.c: ...to here. + * util/getroot.c: Move from here... + * kern/emu/getroot.c: ...to here. + * util/grub-emu.c: Move from here... + * kern/emu/main.c: ...to here. + * util/hostdisk.c: Move from here... + * kern/emu/hostdisk.c: ...to here. + * util/hostfs.c: Move from here... + * kern/emu/hostfs.c: ...to here. + * util/mm.c: Move from here... + * kern/emu/mm.c: ...to here. + * util/pci.c: Move from here... + * bus/emu/pci.c: ...to here. + * util/sdl.c: Move from here... + * video/emu/sdl.c: ...to here. + * util/time.c: Move from here... + * kern/emu/time.c: ...to here. + * util/usb.c: Move from here... + * bus/usb/emu/usb.c: ...to here. + + * include/grub/emu/misc.h: New header for grub-emu functions. + * kern/emu/misc.c: grub-emu functions separated from util/misc.c + + * conf/any-emu.rmk: Rule updates for above renames. + * conf/common.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/i386-qemu.rmk: Likewise. + * conf/mips.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86-efi.rmk: Likewise. + + * disk/lvm.h: #include updates for above renames. + * util/grub-mkrelpath.c: Likewise. + * util/grub-probe.c: Likewise. + * util/i386/pc/grub-setup.c: Likewise. + * util/sparc64/ieee1275/grub-setup.c: Likewise. + * kern/emu/console.c: Likewise. + * kern/emu/getroot.c: Likewise. + * kern/emu/hostdisk.c: Likewise. + * kern/emu/main.c: Likewise. (was grub-emu.c earlier) + + * include/grub/dl.h: Remove grub_dl_{ref,unref}. + * include/grub/util/misc.h: Move grub-emu functions to emu/misc.h. + * kern/dl.c: Handle null mod in grub_dl_{ref,unref}. + * util/misc.c: Remove grub-emu functions. + +2010-05-13 Vladimir Serbinenko + + Fix gfxmenu crash. + Reported by: Thorsten Grützmacher. + + * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister + timeout hook. + (circprog_set_property): Register and unregister timeout hook. + * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. + (label_destroy): Free template. and unregister hook. + (label_set_state): New function. + (label_set_property): Handle templates and hooks. + * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister + timeout hook. + (progress_bar_set_property): Register and unregister timeout hook. + * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... + * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here + * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. + (update_timeout_visit): Removed. + (update_timeouts): New function. + (redraw_timeouts): Likewise. + (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. + (grub_gfxmenu_clear_timeout): Likewise. + * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. + (grub_gfxmenu_timeout_notify): Likewise. + (grub_gfxmenu_timeout_notifications): New external variable. + (grub_gfxmenu_timeout_register): New function. + (grub_gfxmenu_timeout_unregister): Likewise. + +2010-05-09 Vladimir Serbinenko + + Transform (broken) vga terminal into (working) vga video driver. + + * conf/i386-pc.rmk (vga_mod_SOURCES): Change term/i386/pc/vga.c to + video/i386/pc/vga.c. + * include/grub/video.h (grub_video_driver_id): + Add GRUB_VIDEO_DRIVER_VGA. + * term/i386/pc/vga.c: Renamed to ... + * video/i386/pc/vga.c: ...this + (DEBUG_VGA): Removed. + (CHAR_WIDTH): Likewise. + (CHAR_HEIGHT): Likewise. + (TEXT_WIDTH): Likewise. + (TEXT_HEIGHT): Likewise. + (DEFAULT_FG_COLOR): Likewise. + (DEFAULT_BG_COLOR): Likewise. + (colored_char): Likewise. + (xpos): Likewise. + (ypos): Likewise. + (cursor_state): Likewise. + (fg_color): Likewise. + (bg_color): Likewise. + (text_buf): Likewise. + (page): Likewise. + (font): Likewise. + (framebuffer): New variable. + (set_read_map): Disabled. + (setup): New variable. + (is_target): Likewise. + (grub_vga_mod_init): Likewise. + (grub_vga_mod_fini): Likewise. + (check_vga_mem): Likewise. + (write_char): Likewise. + (write_cursor): Likewise. + (scroll_up): Likewise. + (grub_vga_putchar): Likewise. + (grub_vga_getcharwidth): Likewise. + (grub_vga_getwh): Likewise. + (grub_vga_getxy): Likewise. + (grub_vga_gotoxy): Likewise. + (grub_vga_cls): Likewise. + (grub_vga_setcolorstate): Likewise. + (grub_vga_setcursor): Likewise. + (grub_video_vga_init): New function. + (grub_video_vga_setup): Likewise. + (grub_video_vga_fini): Likewise. + (update_target): Likewise. + (grub_video_vga_blit_bitmap): Likewise. + (grub_video_vga_blit_render_target): Likewise. + (grub_video_vga_set_active_render_target): Likewise. + (grub_video_vga_get_active_render_target): Likewise. + (grub_video_vga_swap_buffers): Likewise. + (grub_video_vga_set_palette): Likewise. + (grub_video_vga_get_info_and_fini): Likewise. + (grub_vga_term): Removed. + (grub_video_vga_adapter): New variable. + (GRUB_MOD_INIT): Register a video driver instead of terminal. + (GRUB_MOD_FINI): Unrefister a video driver instead of terminal. + +2010-05-05 Vladimir Serbinenko + + * video/readers/jpeg.c: Indented. + +2010-05-05 Vladimir Serbinenko + + Various jpeg cleanups. + + * video/readers/jpeg.c (grub_jpeg_get_huff_code): Use ARRAY_SIZE. + (grub_jpeg_decode_quan_table): Use sizeof. + (grub_jpeg_decode_du): Use ARRAY_SIZE. + +2010-05-05 Peter Hurley (tiny change) + + * video/readers/jpeg.c (grub_jpeg_decode_huff_table): Loop over all + tables. Ignore non-last ac bit. + (grub_jpeg_decode_quan_table): Likewise. + +2010-05-05 Vladimir Serbinenko + + * include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New value + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM. + * kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM on qemu. + * kern/ieee1275/init.c (grub_claim_heap): Don0t allocate below + 1.5MiB if GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM is set. + +2010-05-05 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_getkey): Fix off-by-one + error. + +2010-05-05 Vladimir Serbinenko + + * term/ieee1275/ofconsole.c (grub_ofconsole_readkey): Support C0 code. + +2010-05-03 Vladimir Serbinenko + + * commands/parttool.c (grub_cmd_parttool): Fix #if !GRUB_NO_MODULES + condition. + +2010-05-03 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Put magic and size assignment in common + part. + +2010-05-03 Vladimir Serbinenko + + * kern/mm.c (grub_mm_init_region): Check for region size after aligning + pointers. + +2010-05-03 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Fix size calculation when extra == 0. + +2010-05-01 Christian Franke + + * util/grub-mkconfig_lib.in (make_system_path_relative_to_its_root): + Remove broken Cygwin path conversion. + * util/misc.c: [__CYGWIN__] Add include and define. + [__CYGWIN__] (get_win32_path): Copy function from getroot.c, modify + for Cygwin 1.7. + (make_system_path_relative_to_its_root): Simplify loop, replace early + return by break. + [__CYGWIN__] Add conversion to win32 path. + Include "/" case in trailing slash removal. + +2010-05-01 Vladimir Serbinenko + + * kern/main.c (grub_load_config): Fix copy-pasted comment. + Reported by: Seth Goldberg + +2010-05-01 Vladimir Serbinenko + + * commands/help.c (grub_cmd_help): Fix a typo. + Reported by: Seth Goldberg + +2010-05-01 Vladimir Serbinenko + + * commands/hashsum.c (GRUB_MOD_INIT): Remove duplication of command + name and add N_. + * commands/i386/pc/drivemap.c (GRUB_MOD_INIT): Likewise. + * commands/iorw.c (GRUB_MOD_INIT): Likewise. + * commands/password_pbkdf2.c (GRUB_MOD_INIT): Likewise. + * commands/regexp.c (GRUB_MOD_INIT): Likewise. + * commands/setpci.c (GRUB_MOD_INIT): Likewise. + * commands/terminal.c (GRUB_MOD_INIT): Likewise. + * efiemu/main.c (GRUB_MOD_INIT): Likewise. + * font/font_cmd.c (GRUB_MOD_INIT): Likewise. + * kern/corecmd.c (GRUB_MOD_INIT): Likewise. + * mmap/mmap.c (GRUB_MOD_INIT): Likewise. + * normal/context.c (GRUB_MOD_INIT): Likewise. + * normal/main.c (GRUB_MOD_INIT): Likewise. + * term/gfxterm.c (GRUB_MOD_INIT): Likewise. + * term/serial.c (GRUB_MOD_INIT): Likewise. + * term/terminfo.c (GRUB_MOD_INIT): Likewise. + +2010-05-01 Vladimir Serbinenko + + * kern/mm.c (grub_real_malloc): Satisfy alignment requirement when + extra == 0. + +2010-05-01 Vladimir Serbinenko + + * commands/iorw.c: New file. + * conf/i386.rmk (pkglib_MODULES): Add iorw.mod. + (iorw_mod_SOURCES): New variable. + (iorw_mod_CFLAGS): Likewise. + (iorw_mod_LDFLAGS): Likewise. + +2010-05-01 Vladimir Serbinenko + + Hotkey support + + * include/grub/menu.h (grub_menu_entry): New field 'hotkey'. + * normal/main.c (hotkey_aliases): New variable. + (grub_normal_add_menu_entry): Parse "--hotkey". + * normal/menu_text.c (run_menu): Handle hotkeys. + +2010-05-01 Vladimir Serbinenko + + * kern/i386/coreboot/init.c (grub_machine_init): Call + grub_machine_mmap_init on qemu. + +2010-05-01 Vladimir Serbinenko + + * boot/i386/qemu/boot.S: Add a missing .code16. + +2010-05-01 Vladimir Serbinenko + + Use LBIO on coreboot. + + * conf/i386-coreboot.rmk (kernel_img_SOURCES): Change + kern/i386/multiboot_mmap.c to kern/i386/coreboot/mmap.c. + * include/grub/i386/coreboot/memory.h (GRUB_LINUXBIOS_MEMBER_LINK): + New declaration. + * kern/i386/coreboot/init.c (grub_machine_init): Don't call + grub_machine_mmap_init on coreboot. + * kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate): Handle + GRUB_LINUXBIOS_MEMBER_LINK. + (grub_machine_mmap_iterate): Fix declaration. + * kern/i386/coreboot/startup.S: Don't save mbi location on coreboot. + +2010-05-01 Vladimir Serbinenko + + Split coreboot and multiboot ports. + + * conf/i386-multiboot.rmk: New file. + * configure.ac: Add multiboot port. + * include/grub/i386/multiboot/boot.h: New file. + * include/grub/i386/multiboot/console.h: Likewise. + * include/grub/i386/multiboot/init.h: Likewise. + * include/grub/i386/multiboot/kernel.h: Likewise. + * include/grub/i386/multiboot/loader.h: Likewise. + * include/grub/i386/multiboot/memory.h: Likewise. + * include/grub/i386/multiboot/serial.h: Likewise. + * include/grub/i386/multiboot/time.h: Likewise. + * include/grub/multiboot.h: Add GRUB_MACHINE_MULTIBOOT to ifdef. + * loader/multiboot.c: Likewise. + * loader/multiboot_mbi2.c: Likewise. + * util/grub-mkrescue.in: Generate multiboot rescue. + +2010-05-01 Vladimir Serbinenko + + * kern/parser.c (grub_parser_execute): Cope with read-only config. + +2010-05-01 Vladimir Serbinenko + + Merge handling of input and output terminals. Fix a hang. + + * commands/terminal.c (abstract_terminal): New struct. + (handle_command): New function. Based on grub_cmd_terminal_input. + (grub_cmd_terminal_input): Use handle_command. + (grub_cmd_terminal_output): Use handle_command. + +2010-05-01 BVK Chaitanya + + Fix comment handling. + + * tests/grub_script_comments.in: New testcase. + * conf/tests.rmk: Rules for new testcase. + * script/yylex.l: Updated flex rules. + +2010-04-28 Samuel Thibault + + * docs/grub.texi (play): Document that zero pitches produce rests. + * commands/i386/pc/play.c (grub_cmd_play): Call 'grub_file_open' only + if argc is 1. + +2010-04-27 Vladimir Serbinenko + + * conf/x86-efi.rmk (linux_mod_SOURCES): Write explicitly to avoid + autogen issues. + +2010-04-26 Christian Franke + + * include/grub/util/getroot.h (grub_get_prefix): Remove prototype. + * util/getroot.c [__CYGWIN__] (get_win32_path): Remove function. + (grub_get_prefix): Remove function. + * util/grub-emu.c (main): Replace grub_get_prefix () call by + make_system_path_relative_to_its_root (). + * util/sparc64/ieee1275/grub-setup.c (main): Likewise. + +2010-04-24 Christian Franke + + * Makefile.in (TARGET_LDFLAGS): Add -static-libgcc. + (kernel_img_LDFLAGS): Remove -static-libgcc. + +2010-04-24 Christian Franke + + * configure.ac: Do not CHECK_BSS_START_SYMBOL + and CHECK_END_SYMBOL if grub-emu is built. + Unset TARGET_OBJ2ELF if grub-emu is built + without module support. + +2010-04-24 Jiro SEKIBA + + Nilfs2 support. + + * conf/common.rmk (grub_probe_SOURCES): Add fs/nilfs2.c. + (grub_fstest_SOURCES): Likewise. + (pkglib_MODULES): Add nilfs2.mod. + (nilfs2_mod_SOURCES): New variable. + (nilfs2_mod_CFLAGS): Likewise. + (nilfs2_mod_LDFLAGS): Likewise. + * conf/i386-pc.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Add fs/nilfs2.c. + * fs/nilfs2.c: New file. + 2010-04-21 Vladimir Serbinenko * configure.ac: Refuse to compile for x86_64-efi is mcmodel=large @@ -69,7 +682,7 @@ * disk/lvm.c (grub_lvm_memberlist): Issue an error if pv->disk = 0. -2010-04-17 Christian Franke +2010-04-17 Christian Franke * Makefile.in: Add missing localedir setting. diff --git a/Makefile.in b/Makefile.in index 29f997213..75388e3c8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -90,7 +90,7 @@ GNULIB_CFLAGS = $(GNULIB_UTIL_CFLAGS) $(POSIX_CFLAGS) ASFLAGS = @ASFLAGS@ LDFLAGS = @LDFLAGS@ $(LIBS) CPPFLAGS = @CPPFLAGS@ -I$(builddir) -I$(builddir)/include -I$(srcdir)/gnulib -I$(srcdir)/include -Wall -W \ - -DGRUB_LIBDIR=\"$(pkglibdir)\" -DLOCALEDIR=\"$(localedir)\" + -DGRUB_PKGLIBROOTDIR=\"$(libdir)/`echo @PACKAGE_TARNAME@ | sed '$(transform)'`\" -DLOCALEDIR=\"$(localedir)\" TARGET_CC = @TARGET_CC@ TARGET_CFLAGS = -ffreestanding @TARGET_CFLAGS@ TARGET_ASFLAGS = -nostdinc -fno-builtin @TARGET_ASFLAGS@ @@ -99,12 +99,12 @@ TARGET_APPLE_CC = @TARGET_APPLE_CC@ OBJCONV = @OBJCONV@ TARGET_CPPFLAGS = @TARGET_CPPFLAGS@ -I$(srcdir)/include -I$(builddir) -I$(builddir)/include \ -Wall -W -TARGET_LDFLAGS = -nostdlib @TARGET_LDFLAGS@ +TARGET_LDFLAGS = -nostdlib -static-libgcc @TARGET_LDFLAGS@ TARGET_IMG_LDSCRIPT = @TARGET_IMG_LDSCRIPT@ TARGET_IMG_LDFLAGS = -nostdlib @TARGET_IMG_LDFLAGS@ TARGET_IMG_CFLAGS = @TARGET_IMG_CFLAGS@ TARGET_OBJ2ELF = @TARGET_OBJ2ELF@ -kernel_img_LDFLAGS = -static-libgcc -lgcc +kernel_img_LDFLAGS = -lgcc EXEEXT = @EXEEXT@ OBJCOPY = @OBJCOPY@ STRIP = @STRIP@ diff --git a/boot/i386/qemu/boot.S b/boot/i386/qemu/boot.S index a93fe3943..a84bd77a8 100644 --- a/boot/i386/qemu/boot.S +++ b/boot/i386/qemu/boot.S @@ -31,7 +31,7 @@ _start: jmp 1f - . = _start + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 1: @@ -63,5 +63,8 @@ VARIABLE(grub_core_entry_addr) *right here* and this is why we need this kludge. */ . = GRUB_BOOT_MACHINE_SIZE - 16 + + .code16 + jmp _start . = GRUB_BOOT_MACHINE_SIZE diff --git a/boot/sparc64/ieee1275/diskboot.S b/boot/sparc64/ieee1275/diskboot.S index a4d4b5bf9..83dfee098 100644 --- a/boot/sparc64/ieee1275/diskboot.S +++ b/boot/sparc64/ieee1275/diskboot.S @@ -19,6 +19,7 @@ #include #include +#include .text .align 4 @@ -87,8 +88,8 @@ after_info_block: call console_write mov NOTIFICATION_STRING_LEN, %o3 - GET_ABS(firstlist - GRUB_BOOT_MACHINE_LIST_SIZE, %l2) - set GRUB_BOOT_MACHINE_IMAGE_ADDRESS, %l3 + GET_ABS(firstlist - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2) + set GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS, %l3 bootloop: lduw [%l2 + 0x08], %o0 brz %o0, bootit @@ -115,7 +116,7 @@ bootloop: mov NOTIFICATION_STEP_LEN, %o3 ba bootloop - sub %l2, GRUB_BOOT_MACHINE_LIST_SIZE, %l2 + sub %l2, GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE, %l2 bootit: GET_ABS(prom_close_name, %o0) @@ -127,8 +128,8 @@ bootit: GET_ABS(notification_done, %o2) call console_write mov NOTIFICATION_DONE_LEN, %o3 - sethi %hi(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o2 - jmpl %o2 + %lo(GRUB_BOOT_MACHINE_IMAGE_ADDRESS), %o7 + sethi %hi(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o2 + jmpl %o2 + %lo(GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS), %o7 mov CIF_REG, %o4 1: ba,a 1b @@ -136,7 +137,7 @@ lastlist: .word 0 .word 0 - . = _start + (0x200 - GRUB_BOOT_MACHINE_LIST_SIZE) + . = _start + (0x200 - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE) blocklist_default_start: .word 0 .word 2 diff --git a/util/pci.c b/bus/emu/pci.c similarity index 100% rename from util/pci.c rename to bus/emu/pci.c diff --git a/util/usb.c b/bus/usb/emu/usb.c similarity index 97% rename from util/usb.c rename to bus/usb/emu/usb.c index a687eea9b..187857b5b 100644 --- a/util/usb.c +++ b/bus/usb/emu/usb.c @@ -105,14 +105,14 @@ grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused))) grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, grub_uint8_t request, grub_uint16_t value, - grub_uint16_t index, grub_size_t size, char *data) + grub_uint16_t idx, grub_size_t size, char *data) { usb_dev_handle *devh; struct usb_device *d = dev->data; devh = usb_open (d); if (usb_control_msg (devh, reqtype, request, - value, index, data, size, 20) < 0) + value, idx, data, size, 20) < 0) { usb_close (devh); return GRUB_USB_ERR_STALL; diff --git a/commands/hashsum.c b/commands/hashsum.c index 951479fa7..d5f551dbb 100644 --- a/commands/hashsum.c +++ b/commands/hashsum.c @@ -24,13 +24,14 @@ #include #include #include +#include static const struct grub_arg_option options[] = { - {"hash", 'h', 0, "Specify hash to use.", "HASH", ARG_TYPE_STRING}, - {"check", 'c', 0, "Check hash list file.", "FILE", ARG_TYPE_STRING}, - {"prefix", 'p', 0, "Base directory for hash list.", "DIRECTORY", + {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING}, + {"check", 'c', 0, N_("Check hash list file."), N_("FILE"), ARG_TYPE_STRING}, + {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"), ARG_TYPE_STRING}, - {"keep-going", 'k', 0, "Don't stop after first error.", 0, 0}, + {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -249,21 +250,21 @@ GRUB_MOD_INIT(hashsum) options); cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "md5sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", - "Compute or check hash checksum.", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), options); cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "sha256sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), "Compute or check hash checksum.", options); cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, GRUB_COMMAND_FLAG_BOTH, - "sha512sum [-c FILE [-p PREFIX]] " - "[FILE1 [FILE2 ...]]", - "Compute or check hash checksum.", + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), options); } diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..c2aad03b2 100644 --- a/commands/help.c +++ b/commands/help.c @@ -100,7 +100,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) grub_arg_show_help ((grub_extcmd_t) cmd->data); else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary), _(cmd->description)); } } diff --git a/commands/i386/pc/drivemap.c b/commands/i386/pc/drivemap.c index 3baacba49..4afc43358 100644 --- a/commands/i386/pc/drivemap.c +++ b/commands/i386/pc/drivemap.c @@ -402,11 +402,10 @@ GRUB_MOD_INIT (drivemap) grub_get_root_biosnumber_saved = grub_get_root_biosnumber; grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap; cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap, - GRUB_COMMAND_FLAG_BOTH, - "drivemap" - N_("-l | -r | [-s] grubdev osdisk."), - N_("Manage the BIOS drive mappings."), - options); + GRUB_COMMAND_FLAG_BOTH, + N_("-l | -r | [-s] grubdev osdisk."), + N_("Manage the BIOS drive mappings."), + options); drivemap_hook = grub_loader_register_preboot_hook (&install_int13_handler, &uninstall_int13_handler, diff --git a/commands/i386/pc/play.c b/commands/i386/pc/play.c index 44d98a1f0..4ed937d4a 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -177,16 +177,20 @@ static grub_err_t grub_cmd_play (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - grub_file_t file; if (argc < 1) return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name or tempo and notes required"); - file = grub_file_open (args[0]); - if (file) + if (argc == 1) { struct note buf; grub_uint32_t tempo; + grub_file_t file; + + file = grub_file_open (args[0]); + + if (! file) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found"); if (grub_file_read (file, &tempo, sizeof (tempo)) != sizeof (tempo)) { diff --git a/commands/iorw.c b/commands/iorw.c new file mode 100644 index 000000000..474c8712e --- /dev/null +++ b/commands/iorw.c @@ -0,0 +1,150 @@ +/* memrw.c - command to read / write physical memory */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static grub_extcmd_t cmd_read_byte, cmd_read_word, cmd_read_dword; +static grub_command_t cmd_write_byte, cmd_write_word, cmd_write_dword; + +static const struct grub_arg_option options[] = + { + {0, 'v', 0, N_("Save read value into variable VARNAME."), + N_("VARNAME"), ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + + +static grub_err_t +grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv) +{ + grub_target_addr_t addr; + grub_uint32_t value = 0; + char buf[sizeof ("XXXXXXXX")]; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); + + addr = grub_strtoul (argv[0], 0, 0); + switch (cmd->cmd->name[sizeof ("in") - 1]) + { + case 'l': + value = grub_inl (addr); + break; + + case 'w': + value = grub_inw (addr); + break; + + case 'b': + value = grub_inb (addr); + break; + } + + if (cmd->state[0].set) + { + grub_snprintf (buf, sizeof (buf), "%x", value); + grub_env_set (cmd->state[0].arg, buf); + } + else + grub_printf ("0x%x\n", value); + + return 0; +} + +static grub_err_t +grub_cmd_write (grub_command_t cmd, int argc, char **argv) +{ + grub_target_addr_t addr; + grub_uint32_t value; + grub_uint32_t mask = 0xffffffff; + + if (argc != 2 && argc != 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); + + addr = grub_strtoul (argv[0], 0, 0); + value = grub_strtoul (argv[1], 0, 0); + if (argc == 3) + mask = grub_strtoul (argv[2], 0, 0); + value &= mask; + switch (cmd->name[sizeof ("out") - 1]) + { + case 'l': + if (mask != 0xffffffff) + grub_outl ((grub_inl (addr) & ~mask) | value, addr); + else + grub_outl (value, addr); + break; + + case 'w': + if ((mask & 0xffff) != 0xffff) + grub_outw ((grub_inw (addr) & ~mask) | value, addr); + else + grub_outw (value, addr); + break; + + case 'b': + if ((mask & 0xff) != 0xff) + grub_outb ((grub_inb (addr) & ~mask) | value, addr); + else + grub_outb (value, addr); + break; + } + + return 0; +} + +GRUB_MOD_INIT(memrw) +{ + cmd_read_byte = + grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + N_("PORT"), N_("Read byte from PORT."), options); + cmd_read_word = + grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + N_("PORT"), N_("Read word from PORT."), options); + cmd_read_dword = + grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH, + N_("PORT"), N_("Read dword from PORT."), options); + cmd_write_byte = + grub_register_command ("outb", grub_cmd_write, + N_("PORT VALUE [MASK]"), + N_("Write byte VALUE to PORT.")); + cmd_write_word = + grub_register_command ("outw", grub_cmd_write, + N_("PORT VALUE [MASK]"), + N_("Write word VALUE to PORT.")); + cmd_write_dword = + grub_register_command ("outl", grub_cmd_write, + N_("ADDR VALUE [MASK]"), + N_("Write dword VALUE to PORT.")); +} + +GRUB_MOD_FINI(memrw) +{ + grub_unregister_extcmd (cmd_read_byte); + grub_unregister_extcmd (cmd_read_word); + grub_unregister_extcmd (cmd_read_dword); + grub_unregister_command (cmd_write_byte); + grub_unregister_command (cmd_write_word); + grub_unregister_command (cmd_write_dword); +} diff --git a/commands/parttool.c b/commands/parttool.c index 0850c5e1d..528cf43d7 100644 --- a/commands/parttool.c +++ b/commands/parttool.c @@ -175,7 +175,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), } /* Load modules. */ -#if GRUB_NO_MODULES +#if !GRUB_NO_MODULES { const char *prefix; prefix = grub_env_get ("prefix"); diff --git a/commands/password_pbkdf2.c b/commands/password_pbkdf2.c index 51c8ea794..6886987da 100644 --- a/commands/password_pbkdf2.c +++ b/commands/password_pbkdf2.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -186,8 +187,8 @@ GRUB_MOD_INIT(password_pbkdf2) { my_mod = mod; cmd = grub_register_command ("password_pbkdf2", grub_cmd_password, - "password_pbkdf2 USER PBKDF2_PASSWORD", - "Set user password (PBKDF2). "); + N_("USER PBKDF2_PASSWORD"), + N_("Set user password (PBKDF2). ")); } GRUB_MOD_FINI(password_pbkdf2) diff --git a/commands/regexp.c b/commands/regexp.c index 910bb9082..e8e8243b5 100644 --- a/commands/regexp.c +++ b/commands/regexp.c @@ -21,6 +21,7 @@ #include #include #include +#include #include static grub_err_t @@ -69,8 +70,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(regexp) { cmd = grub_register_command ("regexp", grub_cmd_regexp, - "REGEXP STRING", - "Test if REGEXP matches STRING."); + N_("REGEXP STRING"), + N_("Test if REGEXP matches STRING.")); } GRUB_MOD_FINI(regexp) diff --git a/commands/setpci.c b/commands/setpci.c index f780547a2..fbc7c214e 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -23,6 +23,7 @@ #include #include #include +#include struct pci_register { @@ -329,9 +330,9 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(setpci) { cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH, - "setpci [-s POSITION] [-d DEVICE] [-v VAR] " - "[REGISTER][=VALUE[:MASK]]", - "Manipulate PCI devices.", options); + N_("[-s POSITION] [-d DEVICE] [-v VAR] " + "[REGISTER][=VALUE[:MASK]]"), + N_("Manipulate PCI devices."), options); } GRUB_MOD_FINI(setpci) diff --git a/commands/terminal.c b/commands/terminal.c index e725123b8..1129c39bd 100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@ -26,37 +26,48 @@ struct grub_term_autoload *grub_term_input_autoload = NULL; struct grub_term_autoload *grub_term_output_autoload = NULL; +struct abstract_terminal +{ + struct abstract_terminal *next; + const char *name; + grub_err_t (*init) (void); + grub_err_t (*fini) (void); +}; + static grub_err_t -grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) +handle_command (int argc, char **args, struct abstract_terminal **enabled, + struct abstract_terminal **disabled, + struct grub_term_autoload *autoloads, + const char *active_str, + const char *available_str) { int i; - grub_term_input_t term; + struct abstract_terminal *term; struct grub_term_autoload *aut; if (argc == 0) { - grub_puts_ (N_ ("Active input terminals:")); - FOR_ACTIVE_TERM_INPUTS(term) - grub_printf ("%s ", term->name); + grub_puts_ (active_str); + for (term = *enabled; term; term = term->next) + grub_printf ("%s ", term->name); grub_printf ("\n"); - grub_puts_ (N_ ("Available input terminals:")); - FOR_DISABLED_TERM_INPUTS(term) - grub_printf ("%s ", term->name); + grub_puts_ (available_str); + for (term = *disabled; term; term = term->next) + grub_printf ("%s ", term->name); /* This is quadratic but we don't expect mode than 30 terminal - modules ever. */ - for (aut = grub_term_input_autoload; aut; aut = aut->next) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - grub_printf ("%s ", aut->name); - } + modules ever. */ + for (aut = autoloads; aut; aut = aut->next) + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + for (term = *enabled; term; term = term->next) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + grub_printf ("%s ", aut->name); + } grub_printf ("\n"); return GRUB_ERR_NONE; } @@ -73,112 +84,108 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), { int again = 0; while (1) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term == 0) - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - break; - if (again) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - for (aut = grub_term_input_autoload; aut; aut = aut->next) - if (grub_strcmp (args[i], aut->name) == 0) - { - grub_dl_t mod; - mod = grub_dl_load (aut->modname); - if (mod) - grub_dl_ref (mod); - grub_errno = GRUB_ERR_NONE; - break; - } - if (!aut) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - again = 1; - } + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + for (term = *enabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + break; + if (again) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + for (aut = autoloads; aut; aut = aut->next) + if (grub_strcmp (args[i], aut->name) == 0) + { + grub_dl_t mod; + mod = grub_dl_load (aut->modname); + if (mod) + grub_dl_ref (mod); + grub_errno = GRUB_ERR_NONE; + break; + } + if (!aut) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + again = 1; + } } if (grub_strcmp (args[0], "--append") == 0) { for (i = 1; i < argc; i++) - { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { + { + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { if (term->init && term->init () != GRUB_ERR_NONE) return grub_errno; - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), - GRUB_AS_LIST (term)); - } - } + grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + } + } return GRUB_ERR_NONE; } if (grub_strcmp (args[0], "--remove") == 0) { for (i = 1; i < argc; i++) - { - FOR_ACTIVE_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (!term->next && term == grub_term_inputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), - GRUB_AS_LIST (term)); - } - } + { + for (term = *enabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == *enabled) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + } + } return GRUB_ERR_NONE; } for (i = 0; i < argc; i++) { - FOR_DISABLED_TERM_INPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; + for (term = *disabled; term; term = term->next) + if (grub_strcmp (args[i], term->name) == 0) + break; if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; + { + if (term->init && term->init () != GRUB_ERR_NONE) + return grub_errno; - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), - GRUB_AS_LIST (term)); - } + grub_list_remove (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + grub_list_push (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + } } - - FOR_ACTIVE_TERM_INPUTS(term) + { - for (i = 0; i < argc; i++) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (i == argc) + struct abstract_terminal *next; + for (term = *enabled; term; term = next) { - if (!term->next && term == grub_term_inputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), - GRUB_AS_LIST (term)); + next = term->next; + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == *enabled) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (enabled), GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (disabled), GRUB_AS_LIST (term)); + } } } @@ -186,163 +193,34 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), } static grub_err_t -grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), +grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { - int i; - grub_term_output_t term; - struct grub_term_autoload *aut; + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, next); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, name); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init); + (void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini); + return handle_command (argc, args, + (struct abstract_terminal **) &grub_term_inputs, + (struct abstract_terminal **) &grub_term_inputs_disabled, + grub_term_input_autoload, + N_ ("Active input terminals:"), + N_ ("Available input terminals:")); +} - if (argc == 0) - { - grub_puts_ (N_ ("Active output terminals:")); - FOR_ACTIVE_TERM_OUTPUTS(term) - grub_printf ("%s ", term->name); - grub_printf ("\n"); - grub_puts_ (N_ ("Available output terminals:")); - FOR_DISABLED_TERM_OUTPUTS(term) - grub_printf ("%s ", term->name); - /* This is quadratic but we don't expect mode than 30 terminal - modules ever. */ - for (aut = grub_term_output_autoload; aut; aut = aut->next) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (term->name, aut->name) == 0) - break; - if (!term) - grub_printf ("%s ", aut->name); - } - grub_printf ("\n"); - return GRUB_ERR_NONE; - } - i = 0; - - if (grub_strcmp (args[0], "--append") == 0 - || grub_strcmp (args[0], "--remove") == 0) - i++; - - if (i == argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified")); - - for (; i < argc; i++) - { - int again = 0; - while (1) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term == 0) - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - break; - if (again) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - for (aut = grub_term_output_autoload; aut; aut = aut->next) - if (grub_strcmp (args[i], aut->name) == 0) - { - grub_dl_t mod; - mod = grub_dl_load (aut->modname); - if (mod) - grub_dl_ref (mod); - grub_errno = GRUB_ERR_NONE; - break; - } - if (!aut) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", - args[i]); - again = 1; - } - } - - if (grub_strcmp (args[0], "--append") == 0) - { - for (i = 1; i < argc; i++) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), - GRUB_AS_LIST (term)); - } - } - return GRUB_ERR_NONE; - } - - if (grub_strcmp (args[0], "--remove") == 0) - { - for (i = 1; i < argc; i++) - { - FOR_ACTIVE_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (!term->next && term == grub_term_outputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), - GRUB_AS_LIST (term)); - } - } - return GRUB_ERR_NONE; - } - - for (i = 0; i < argc; i++) - { - FOR_DISABLED_TERM_OUTPUTS(term) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (term) - { - if (term->init && term->init () != GRUB_ERR_NONE) - return grub_errno; - - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), - GRUB_AS_LIST (term)); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), - GRUB_AS_LIST (term)); - } - } - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - for (i = 0; i < argc; i++) - if (grub_strcmp (args[i], term->name) == 0) - break; - if (i == argc) - { - if (!term->next && term == grub_term_outputs) - return grub_error (GRUB_ERR_BAD_ARGUMENT, - "can't remove the last terminal"); - grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), - GRUB_AS_LIST (term)); - if (term->fini) - term->fini (); - grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), - GRUB_AS_LIST (term)); - } - } - - return GRUB_ERR_NONE; +static grub_err_t +grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, next); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init); + (void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini); + return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs, + (struct abstract_terminal **) &grub_term_outputs_disabled, + grub_term_output_autoload, + N_ ("Active output terminals:"), + N_ ("Available output terminals:")); } static grub_command_t cmd_terminal_input, cmd_terminal_output; @@ -351,14 +229,14 @@ GRUB_MOD_INIT(terminal) { cmd_terminal_input = grub_register_command ("terminal_input", grub_cmd_terminal_input, - "[--append|--remove] " - "[TERMINAL1] [TERMINAL2] ...", - "List or select an input terminal."); + N_("[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ..."), + N_("List or select an input terminal.")); cmd_terminal_output = grub_register_command ("terminal_output", grub_cmd_terminal_output, - "[--append|--remove] " - "[TERMINAL1] [TERMINAL2] ...", - "List or select an output terminal."); + N_("[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ..."), + N_("List or select an output terminal.")); } GRUB_MOD_FINI(terminal) diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index d1e5754dc..3f0df06aa 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -9,13 +9,14 @@ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ - \ - util/console.c util/grub-emu.c util/misc.c \ - util/hostdisk.c util/getroot.c util/mm.c util/time.c \ - \ - gnulib/progname.c util/hostfs.c disk/host.c -kernel_img_HEADERS += datetime.h util/misc.h -kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-undef -I$(srcdir)/gnulib + \ + kern/emu/main.c kern/emu/mm.c kern/emu/misc.c \ + kern/emu/getroot.c kern/emu/time.c kern/emu/hostdisk.c \ + kern/emu/hostfs.c kern/emu/console.c \ + \ + gnulib/progname.c disk/host.c +kernel_img_HEADERS += datetime.h emu/misc.h +kernel_img_CFLAGS = $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Wno-char-subscripts -Wno-unused -Wno-deprecated-declarations -Wno-undef -I$(srcdir)/gnulib kernel_img_LDFLAGS = $(COMMON_LDFLAGS) TARGET_NO_STRIP = yes @@ -49,7 +50,7 @@ ifeq ($(enable_grub_emu_usb), yes) kernel_img_HEADERS += libusb.h pkglib_MODULES += libusb.mod -libusb_mod_SOURCES = util/usb.c +libusb_mod_SOURCES = bus/usb/emu/usb.c libusb_mod_CFLAGS = libusb_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -76,7 +77,7 @@ endif ifeq ($(enable_grub_emu_sdl), yes) pkglib_MODULES += sdl.mod -sdl_mod_SOURCES = util/sdl.c +sdl_mod_SOURCES = video/emu/sdl.c sdl_mod_CFLAGS = sdl_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBSDL) @@ -85,7 +86,7 @@ endif ifeq ($(enable_grub_emu_pci), yes) pkglib_MODULES += pci.mod -pci_mod_SOURCES = util/pci.c commands/lspci.c +pci_mod_SOURCES = bus/emu/pci.c commands/lspci.c pci_mod_LDFLAGS = $(COMMON_LDFLAGS) grub_emu_LDFLAGS += $(LIBPCIACCESS) kernel_img_HEADERS += libpciaccess.h @@ -104,10 +105,10 @@ DISTCLEANFILES += grub_emu_init.c CLEANFILES += grub-emu ifneq ($(TARGET_NO_MODULES), yes) grub-emu: $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) else grub-emu: $(pkglib_MODULES) $(pkglib_PROGRAMS) - $(CC) -o $@ $(pkglib_MODULES) $(pkglib_PROGRAMS) $(grub_emu_LDFLAGS) $(LDFLAGS) + $(CC) -o $@ $^ $(grub_emu_LDFLAGS) $(LDFLAGS) endif GRUB_EMU=grub-emu diff --git a/conf/common.rmk b/conf/common.rmk index 8df232a0b..3674cae07 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -6,7 +6,8 @@ script/lexer.c_DEPENDENCIES = grub_script.tab.h sbin_UTILITIES += grub-mkdevicemap grub_mkdevicemap_SOURCES = gnulib/progname.c util/grub-mkdevicemap.c \ util/deviceiter.c \ - util/misc.c + util/misc.c kern/emu/misc.c \ + kern/env.c kern/err.c kern/list.c kern/misc.c kern/emu/mm.c ifeq ($(target_cpu)-$(platform), sparc64-ieee1275) grub_mkdevicemap_SOURCES += util/ieee1275/ofpath.c util/ieee1275/devicemap.c @@ -14,26 +15,25 @@ else grub_mkdevicemap_SOURCES += util/devicemap.c endif -# For grub-mkelfimage. -bin_UTILITIES += grub-mkelfimage -grub_mkelfimage_SOURCES = gnulib/progname.c \ - util/elf/grub-mkimage.c util/misc.c \ - util/resolve.c -util/elf/grub-mkimage.c_DEPENDENCIES = Makefile +# For grub-mkimage. +bin_UTILITIES += grub-mkimage +grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkimage.c util/misc.c \ + util/resolve.c kern/emu/misc.c lib/LzmaEnc.c lib/LzFind.c +util/grub-mkimage.c_DEPENDENCIES = Makefile # For grub-probe. sbin_UTILITIES += grub-probe util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ - util/hostdisk.c util/misc.c util/getroot.c util/mm.c \ + kern/emu/hostdisk.c util/misc.c kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ kern/parser.c kern/partition.c kern/file.c kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ \ partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \ partmap/sun.c partmap/sunpc.c partmap/gpt.c \ @@ -44,24 +44,10 @@ ifeq ($(enable_grub_fstest), yes) bin_UTILITIES += grub-fstest endif -bin_UTILITIES += grub-mkisofs -grub_mkisofs_SOURCES = util/mkisofs/eltorito.c \ - util/mkisofs/hash.c util/mkisofs/joliet.c \ - util/mkisofs/match.c util/mkisofs/mkisofs.c \ - util/mkisofs/multi.c util/mkisofs/name.c \ - util/mkisofs/rock.c util/mkisofs/tree.c \ - util/mkisofs/write.c \ - \ - gnulib/fnmatch.c gnulib/getopt1.c gnulib/getopt.c \ - gnulib/error.c gnulib/progname.c -grub_mkisofs_CFLAGS = -D_FILE_OFFSET_BITS=64 \ - -I$(srcdir)/util/mkisofs/include \ - -Wno-all -Werror $(GNULIB_UTIL_CFLAGS) - # For grub-fstest. util/grub-fstest.c_DEPENDENCIES = grub_fstest_init.h -grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ - util/misc.c util/mm.c \ +grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c kern/emu/hostfs.c \ + util/misc.c kern/emu/misc.c kern/emu/mm.c \ kern/file.c kern/device.c kern/disk.c kern/err.c kern/misc.c \ disk/host.c disk/loopback.c kern/list.c kern/command.c \ lib/arg.c commands/extcmd.c normal/datetime.c normal/misc.c \ @@ -69,7 +55,7 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ fs/befs_be.c fs/tar.c \ \ @@ -83,14 +69,14 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \ # For grub-mkfont. ifeq ($(enable_grub_mkfont), yes) bin_UTILITIES += grub-mkfont -grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c +grub_mkfont_SOURCES = gnulib/progname.c util/grub-mkfont.c util/misc.c kern/emu/misc.c grub_mkfont_CFLAGS = $(freetype_cflags) grub_mkfont_LDFLAGS = $(freetype_libs) endif # For grub-mkrelpath. bin_UTILITIES += grub-mkrelpath -grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c +grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c kern/emu/misc.c bin_UTILITIES += grub-bin2h grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c @@ -104,7 +90,7 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h bin_UTILITIES += grub-script-check util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ - util/grub-script-check.c util/misc.c util/mm.c \ + util/grub-script-check.c util/misc.c kern/emu/misc.c kern/emu/mm.c \ script/main.c script/script.c script/function.c script/lexer.c \ kern/handler.c kern/err.c kern/parser.c kern/list.c \ kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ @@ -119,7 +105,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ list.h handler.h command.h i18n.h env_private.h libgcc.h ifneq ($(platform), emu) -kernel_img_HEADERS += machine/memory.h machine/loader.h machine/kernel.h +kernel_img_HEADERS += machine/memory.h machine/loader.h endif symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh @@ -187,7 +173,7 @@ DISTCLEANFILES += grub_fstest_init.c # for grub-editenv bin_UTILITIES += grub-editenv -grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c util/mm.c kern/misc.c kern/err.c +grub_editenv_SOURCES = gnulib/progname.c util/grub-editenv.c lib/envblk.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/misc.c kern/err.c CLEANFILES += grub-editenv # Needed for genmk.rb to work @@ -195,7 +181,7 @@ ifeq (0,1) bin_UTILITIES += grub-macho2img grub-pe2elf endif -grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c +grub_pe2elf_SOURCES = gnulib/progname.c util/grub-pe2elf.c util/misc.c kern/emu/misc.c CLEANFILES += grub-pe2elf grub_macho2img_SOURCES = util/grub-macho2img.c @@ -298,6 +284,12 @@ minix_mod_SOURCES = fs/minix.c minix_mod_CFLAGS = $(COMMON_CFLAGS) minix_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For nilfs2.mod. +pkglib_MODULES += nilfs2.mod +nilfs2_mod_SOURCES = fs/nilfs2.c +nilfs2_mod_CFLAGS = $(COMMON_CFLAGS) +nilfs2_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hfs.mod. hfs_mod_SOURCES = fs/hfs.c hfs_mod_CFLAGS = $(COMMON_CFLAGS) @@ -654,7 +646,7 @@ normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) # For sh.mod. -sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ +sh_mod_SOURCES = script/main.c script/script.c script/argv.c script/execute.c \ script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c sh_mod_CFLAGS = $(COMMON_CFLAGS) $(POSIX_CFLAGS) -Wno-error sh_mod_LDFLAGS = $(COMMON_LDFLAGS) @@ -855,7 +847,7 @@ boot_mod_CFLAGS = $(COMMON_CFLAGS) boot_mod_LDFLAGS = $(COMMON_LDFLAGS) bin_UTILITIES += grub-mkpasswd-pbkdf2 -grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c util/mm.c kern/err.c +grub_mkpasswd_pbkdf2_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c util/grub-mkpasswd-pbkdf2.c lib/crypto.c lib/libgcrypt-grub/cipher/sha512.c lib/pbkdf2.c util/misc.c kern/emu/misc.c kern/emu/mm.c kern/err.c grub_mkpasswd_pbkdf2_CFLAGS += -Wno-missing-field-initializers -Wno-error -I$(srcdir)/lib/libgcrypt_wrap -DGRUB_MKPASSWD=1 include $(srcdir)/conf/gcry.mk diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 69b8e9a48..b8713a7b0 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -4,13 +4,11 @@ COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ - kern/i386/multiboot_mmap.c \ + kern/i386/coreboot/mmap.c \ kern/i386/halt.c \ kern/main.c kern/device.c \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ @@ -26,7 +24,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x8200,-Bstatic sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/conf/i386-multiboot.rmk b/conf/i386-multiboot.rmk new file mode 100644 index 000000000..69b8e9a48 --- /dev/null +++ b/conf/i386-multiboot.rmk @@ -0,0 +1,74 @@ +# -*- makefile -*- + +COMMON_CFLAGS = -mrtd -mregparm=3 + +# Images. + +GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 + +pkglib_PROGRAMS += kernel.img +kernel_img_SOURCES = kern/i386/coreboot/startup.S \ + kern/i386/misc.S \ + kern/i386/coreboot/init.c \ + kern/i386/multiboot_mmap.c \ + kern/i386/halt.c \ + kern/main.c kern/device.c \ + kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ + kern/misc.c kern/mm.c kern/term.c \ + kern/rescue_parser.c kern/rescue_reader.c \ + kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ + kern/i386/tsc.c kern/i386/pit.c \ + kern/generic/rtc_get_time_ms.c \ + kern/generic/millisleep.c \ + kern/env.c \ + term/i386/pc/vga_text.c term/i386/vga_common.c \ + symlist.c +kernel_img_CFLAGS = $(COMMON_CFLAGS) +kernel_img_ASFLAGS = $(COMMON_ASFLAGS) +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR),-Bstatic + +sbin_SCRIPTS += grub-install +grub_install_SOURCES = util/grub-install.in + +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + +# Modules. +pkglib_MODULES = linux.mod aout.mod halt.mod datetime.mod mmap.mod + +# For mmap.mod. +mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c +mmap_mod_CFLAGS = $(COMMON_CFLAGS) +mmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +mmap_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For linux.mod. +linux_mod_SOURCES = loader/i386/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For halt.mod. +halt_mod_SOURCES = commands/halt.c +halt_mod_CFLAGS = $(COMMON_CFLAGS) +halt_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For aout.mod. +aout_mod_SOURCES = loader/aout.c +aout_mod_CFLAGS = $(COMMON_CFLAGS) +aout_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For bsd.mod +pkglib_MODULES += bsd.mod +bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd32.c loader/i386/bsd64.c loader/i386/bsd_helper.S loader/i386/bsd_trampoline.S +bsd_mod_CFLAGS = $(COMMON_CFLAGS) +bsd_mod_LDFLAGS = $(COMMON_LDFLAGS) +bsd_mod_ASFLAGS = $(COMMON_ASFLAGS) + +# For datetime.mod +datetime_mod_SOURCES = lib/cmos_datetime.c +datetime_mod_CFLAGS = $(COMMON_CFLAGS) +datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) + +include $(srcdir)/conf/i386.mk +include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index eace1e2da..8e50ee889 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -1,12 +1,9 @@ # -*- makefile -*- -GRUB_KERNEL_MACHINE_LINK_ADDR = 0x8200 - COMMON_CFLAGS = -mrtd -mregparm=3 # Images. -pkglib_IMAGES = boot.img cdboot.img diskboot.img kernel.img lnxboot.img \ - pxeboot.img +pkglib_IMAGES = boot.img cdboot.img diskboot.img lnxboot.img pxeboot.img # For boot.img. boot_img_SOURCES = boot/i386/pc/boot.S @@ -39,6 +36,7 @@ cdboot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x7C00 cdboot_img_FORMAT = binary # For kernel.img. +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/i386/misc.S \ kern/main.c kern/device.c \ @@ -55,42 +53,33 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ term/i386/pc/console.c term/i386/vga_common.c \ symlist.c kernel_img_HEADERS += machine/biosdisk.h machine/vga.h machine/vbe.h \ - machine/pxe.h i386/pit.h + machine/pxe.h i386/pit.h machine/kernel.h kernel_img_CFLAGS = $(COMMON_CFLAGS) $(TARGET_IMG_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) -kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_KERNEL_MACHINE_LINK_ADDR) $(COMMON_CFLAGS) -kernel_img_FORMAT = binary +kernel_img_LDFLAGS += $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)0x8200 $(COMMON_CFLAGS) # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile - # For grub-setup. util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = gnulib/progname.c \ - util/i386/pc/grub-setup.c util/hostdisk.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c kern/list.c \ - fs/fshelp.c \ - \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ - partmap/gpt.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c \ +grub_setup_SOURCES = gnulib/progname.c util/i386/pc/grub-setup.c \ + util/misc.c kern/emu/misc.c kern/emu/getroot.c \ + kern/emu/hostdisk.c kern/device.c kern/disk.c kern/err.c \ + kern/misc.c kern/parser.c kern/partition.c kern/file.c \ + kern/emu/mm.c kern/fs.c kern/env.c kern/list.c fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/msdos.c partmap/bsdlabel.c partmap/sunpc.c \ + partmap/gpt.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c \ + util/raid.c util/lvm.c \ grub_setup_init.c sbin_SCRIPTS += grub-install @@ -185,7 +174,7 @@ vbetest_mod_CFLAGS = $(COMMON_CFLAGS) vbetest_mod_LDFLAGS = $(COMMON_LDFLAGS) # For vga.mod. -vga_mod_SOURCES = term/i386/pc/vga.c +vga_mod_SOURCES = video/i386/pc/vga.c vga_mod_CFLAGS = $(COMMON_CFLAGS) vga_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 664bef12a..ff263245d 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -13,13 +13,7 @@ boot_img_ASFLAGS = $(COMMON_ASFLAGS) -DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_M boot_img_LDFLAGS = $(COMMON_LDFLAGS) $(TARGET_IMG_LDFLAGS)$(GRUB_BOOT_MACHINE_LINK_ADDR) boot_img_FORMAT = binary -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ - util/resolve.c gnulib/progname.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile - -pkglib_IMAGES += kernel.img +pkglib_PROGRAMS += kernel.img kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/i386/misc.S \ kern/i386/coreboot/init.c \ diff --git a/conf/i386.rmk b/conf/i386.rmk index 3d7f42804..02ce39817 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -68,3 +68,8 @@ play_mod_SOURCES = commands/i386/pc/play.c play_mod_CFLAGS = $(COMMON_CFLAGS) play_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For iorw.mod. +pkglib_MODULES += iorw.mod +iorw_mod_SOURCES = commands/iorw.c +iorw_mod_CFLAGS = $(COMMON_CFLAGS) +iorw_mod_LDFLAGS = $(COMMON_LDFLAGS) diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index af5b26bec..2f80ab2e3 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -5,7 +5,7 @@ COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 6a96ddfaf..5ce8ede9d 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -8,7 +8,7 @@ kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h buf include $(srcdir)/conf/mips.mk -pkglib_IMAGES = kernel.img +pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/main.c kern/device.c kern/$(target_cpu)/init.c \ kern/$(target_cpu)/$(target_machine)/init.c \ diff --git a/conf/mips.rmk b/conf/mips.rmk index 4603c219e..7d30f55f1 100644 --- a/conf/mips.rmk +++ b/conf/mips.rmk @@ -10,13 +10,6 @@ kernel_img_HEADERS += cpu/cache.h sbin_SCRIPTS = bin_SCRIPTS = -# For grub-mkimage. -bin_UTILITIES += grub-mkimage -grub_mkimage_SOURCES = gnulib/progname.c util/grub-mkrawimage.c util/misc.c \ - util/resolve.c lib/LzmaEnc.c lib/LzFind.c -grub_mkimage_CFLAGS = -DGRUB_KERNEL_MACHINE_LINK_ADDR=$(LINK_BASE) -util/grub-mkrawimage.c_DEPENDENCIES = Makefile - # For serial.mod. pkglib_MODULES += serial.mod serial_mod_SOURCES = term/serial.c diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index c82bd81f3..0aac67104 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -5,7 +5,8 @@ COMMON_CFLAGS = -mno-app-regs COMMON_LDFLAGS = -melf64_sparc -mno-relax # Images. -pkglib_IMAGES = boot.img diskboot.img kernel.img +pkglib_IMAGES = boot.img diskboot.img +pkglib_PROGRAMS = kernel.img # For boot.img. boot_img_SOURCES = boot/sparc64/ieee1275/boot.S @@ -40,38 +41,33 @@ kernel_img_LDFLAGS += -nostdlib -Wl,-N,-Ttext,0x4400,-Bstatic,-melf64_sparc kernel_img_FORMAT = binary # Utilities. -bin_UTILITIES = grub-mkimage sbin_UTILITIES = grub-setup grub-ofpathname -# For grub-mkimage. -grub_mkimage_SOURCES = util/grub-mkrawimage.c util/misc.c \ - util/resolve.c gnulib/progname.c - # For grub-setup. util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h -grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \ - util/ieee1275/ofpath.c \ - util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ - kern/file.c kern/fs.c kern/env.c kern/list.c \ - fs/fshelp.c \ - \ - fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ - fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ - fs/befs.c fs/befs_be.c fs/tar.c \ - \ - partmap/amiga.c partmap/apple.c partmap/msdos.c \ - partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ - \ - disk/raid.c disk/mdraid_linux.c disk/lvm.c \ - util/raid.c util/lvm.c util/mm.c gnulib/progname.c \ - grub_setup_init.c +grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/hostdisk.c \ + kern/emu/misc.c kern/emu/getroot.c kern/emu/mm.c kern/device.c \ + kern/disk.c kern/err.c kern/misc.c kern/parser.c \ + kern/partition.c kern/file.c kern/fs.c kern/env.c kern/list.c \ + fs/fshelp.c \ + \ + fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ + fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ + \ + partmap/amiga.c partmap/apple.c partmap/msdos.c \ + partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \ + \ + disk/raid.c disk/mdraid_linux.c disk/lvm.c util/raid.c \ + util/lvm.c gnulib/progname.c grub_setup_init.c # For grub-ofpathname. -grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ - util/ieee1275/ofpath.c util/misc.c gnulib/progname.c +grub_ofpathname_SOURCES = util/ieee1275/grub-ofpathname.c \ + util/ieee1275/ofpath.c util/misc.c kern/emu/misc.c \ + gnulib/progname.c # Scripts. sbin_SCRIPTS = grub-install diff --git a/conf/tests.rmk b/conf/tests.rmk index d48bc3dd9..9144e5528 100644 --- a/conf/tests.rmk +++ b/conf/tests.rmk @@ -68,6 +68,12 @@ grub_script_final_semicolon_SOURCES = tests/grub_script_final_semicolon.in check_SCRIPTS += grub_script_dollar grub_script_dollar_SOURCES = tests/grub_script_dollar.in +check_SCRIPTS += grub_script_comments +grub_script_comments_SOURCES = tests/grub_script_comments.in + +check_SCRIPTS += grub_script_functions +grub_script_functions_SOURCES = tests/grub_script_functions.in + # List of tests to execute on "make check" # SCRIPTED_TESTS = example_scripted_test # SCRIPTED_TESTS += example_grub_script_test @@ -83,6 +89,8 @@ SCRIPTED_TESTS += grub_script_if SCRIPTED_TESTS += grub_script_blanklines SCRIPTED_TESTS += grub_script_final_semicolon SCRIPTED_TESTS += grub_script_dollar +SCRIPTED_TESTS += grub_script_comments +SCRIPTED_TESTS += grub_script_functions # dependencies between tests and testing-tools $(SCRIPTED_TESTS): grub-shell grub-shell-tester diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 46957d933..1011a3e64 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -1,19 +1,14 @@ # -*- makefile -*- -# Utilities. -bin_UTILITIES = grub-mkimage - -# For grub-mkimage. -grub_mkimage_SOURCES = gnulib/progname.c util/i386/efi/grub-mkimage.c \ - util/misc.c util/resolve.c -util/i386/efi/grub-mkimage.c_DEPENDENCIES = Makefile - # Scripts. sbin_SCRIPTS = grub-install # For grub-install. grub_install_SOURCES = util/i386/efi/grub-install.in +bin_SCRIPTS += grub-mkrescue +grub_mkrescue_SOURCES = util/grub-mkrescue.in + # Modules. pkglib_PROGRAMS = kernel.img pkglib_MODULES = chain.mod appleldr.mod \ @@ -64,13 +59,17 @@ appleldr_mod_CFLAGS = $(COMMON_CFLAGS) appleldr_mod_LDFLAGS = $(COMMON_LDFLAGS) # For linux.mod. -linux_mod_SOURCES = loader/i386/efi/linux.c ifeq ($(target_cpu), x86_64) -linux_mod_SOURCES += loader/i386/linux_trampoline.S -endif +linux_mod_SOURCES = loader/i386/efi/linux.c loader/i386/linux_trampoline.S linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +else +linux_mod_SOURCES = loader/i386/efi/linux.c +linux_mod_CFLAGS = $(COMMON_CFLAGS) +linux_mod_ASFLAGS = $(COMMON_ASFLAGS) +linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +endif # For halt.mod. halt_mod_SOURCES = commands/halt.c diff --git a/configure.ac b/configure.ac index 28b3c1d95..ace6bd81d 100644 --- a/configure.ac +++ b/configure.ac @@ -102,6 +102,7 @@ case "$target_cpu"-"$platform" in i386-efi) ;; x86_64-efi) ;; i386-pc) ;; + i386-multiboot) ;; i386-coreboot) ;; i386-linuxbios) platform=coreboot ;; i386-ieee1275) ;; @@ -136,6 +137,7 @@ esac case "$platform" in coreboot) machine_CFLAGS="-DGRUB_MACHINE_COREBOOT=1" ;; + multiboot) machine_CFLAGS="-DGRUB_MACHINE_MULTIBOOT=1" ;; efi) machine_CFLAGS="-DGRUB_MACHINE_EFI=1" ;; ieee1275) machine_CFLAGS="-DGRUB_MACHINE_IEEE1275=1" ;; qemu) machine_CFLAGS="-DGRUB_MACHINE_QEMU=1" ;; @@ -148,6 +150,7 @@ case "$target_cpu" in mips) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_MIPS=1" ;; sparc64) machine_CFLAGS="$machine_CFLAGS -DGRUB_MACHINE_SPARC64=1" ;; esac +machine_CFLAGS="$machine_CFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" CFLAGS="$CFLAGS $machine_CFLAGS" TARGET_ASFLAGS="$TARGET_ASFLAGS $machine_CFLAGS" @@ -511,11 +514,11 @@ grub_PROG_OBJCOPY_ABSOLUTE fi grub_PROG_LD_BUILD_ID_NONE if test "x$target_cpu" = xi386; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then - # Check symbols provided by linker script. - CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000,--defsym,___main=0x8100" - fi - if test "x$TARGET_APPLE_CC" != x1 ; then + if test "$platform" != emu && test "x$TARGET_APPLE_CC" != x1 ; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC}8000 -Wl,--defsym,___main=0x8100" + fi grub_CHECK_BSS_START_SYMBOL grub_CHECK_END_SYMBOL fi @@ -635,6 +638,12 @@ else fi AC_SUBST(TARGET_NO_MODULES) +if test "$TARGET_NO_MODULES" = yes ; then + # Do not convert modules, otherwise linkage may fail (Cygwin only). + # FIXME: Should be checked above before TARGET_OBJ2ELF is set first. + TARGET_OBJ2ELF= +fi + if test x"$enable_grub_emu_usb" = xno ; then grub_emu_usb_excuse="explicitly disabled" fi @@ -771,6 +780,22 @@ AC_SUBST([enable_grub_mkfont]) AC_SUBST([freetype_cflags]) AC_SUBST([freetype_libs]) +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], + [LDFLAGS="$LDFLAGS -ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.])], + [device_mapper_excuse="need devmapper library"]) +fi + AC_SUBST(ASFLAGS) # Output files. diff --git a/disk/lvm.c b/disk/lvm.c index c2ae82df2..7dde40920 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -25,7 +25,7 @@ #include #ifdef GRUB_UTIL -#include +#include #endif static struct grub_lvm_vg *vg_list; diff --git a/docs/grub.texi b/docs/grub.texi index f8a9bc414..704f8b2a3 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1379,7 +1379,8 @@ pitch and duration pairs. If the arguments are a series of numbers, play the inline tune. The tempo is the base for all note durations. 60 gives a 1-second base, 120 -gives a half-second base, etc. Pitches are Hz. +gives a half-second base, etc. Pitches are Hz. Set pitch to 0 to produce +a rest. @end deffn diff --git a/efiemu/main.c b/efiemu/main.c index 8a8a508fa..b197a8b2c 100644 --- a/efiemu/main.c +++ b/efiemu/main.c @@ -31,6 +31,7 @@ #include #include #include +#include /* System table. Two version depending on mode */ grub_efi_system_table32_t *grub_efiemu_system_table32 = 0; @@ -327,15 +328,15 @@ GRUB_MOD_INIT(efiemu) { cmd_loadcore = grub_register_command ("efiemu_loadcore", grub_cmd_efiemu_load, - "FILE", - "Load and initialize EFI emulator."); + N_("FILE"), + N_("Load and initialize EFI emulator.")); cmd_prepare = grub_register_command ("efiemu_prepare", grub_cmd_efiemu_prepare, 0, - "Finalize loading of EFI emulator."); + N_("Finalize loading of EFI emulator.")); cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload, 0, - "Unload EFI emulator."); + N_("Unload EFI emulator.")); } GRUB_MOD_FINI(efiemu) diff --git a/font/font_cmd.c b/font/font_cmd.c index 5515b2cdc..8b00dd8b9 100644 --- a/font/font_cmd.c +++ b/font/font_cmd.c @@ -21,6 +21,7 @@ #include #include #include +#include static grub_err_t loadfont_command (grub_command_t cmd __attribute__ ((unused)), @@ -62,11 +63,11 @@ GRUB_MOD_INIT(font) cmd_loadfont = grub_register_command ("loadfont", loadfont_command, - "FILE...", - "Specify one or more font files to load."); + N_("FILE..."), + N_("Specify one or more font files to load.")); cmd_lsfonts = grub_register_command ("lsfonts", lsfonts_command, - 0, "List the loaded fonts."); + 0, N_("List the loaded fonts.")); } GRUB_MOD_FINI(font) diff --git a/fs/nilfs2.c b/fs/nilfs2.c new file mode 100644 index 000000000..7e0415d12 --- /dev/null +++ b/fs/nilfs2.c @@ -0,0 +1,1133 @@ +/* + * nilfs2.c - New Implementation of Log filesystem + * + * Written by Jiro SEKIBA + * + * Copyright (C) 2003,2004,2005,2007,2008,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + + +/* Filetype information as used in inodes. */ +#define FILETYPE_INO_MASK 0170000 +#define FILETYPE_INO_REG 0100000 +#define FILETYPE_INO_DIRECTORY 0040000 +#define FILETYPE_INO_SYMLINK 0120000 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NILFS_INODE_BMAP_SIZE 7 + +#define NILFS_SUPORT_REV 2 + +/* Magic value used to identify an nilfs2 filesystem. */ +#define NILFS2_SUPER_MAGIC 0x3434 +/* nilfs btree node flag. */ +#define NILFS_BTREE_NODE_ROOT 0x01 + +/* nilfs btree node level. */ +#define NILFS_BTREE_LEVEL_DATA 0 +#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) +#define NILFS_BTREE_LEVEL_MAX 14 + +struct grub_nilfs2_inode +{ + grub_uint64_t i_blocks; + grub_uint64_t i_size; + grub_uint64_t i_ctime; + grub_uint64_t i_mtime; + grub_uint32_t i_ctime_nsec; + grub_uint32_t i_mtime_nsec; + grub_uint32_t i_uid; + grub_uint32_t i_gid; + grub_uint16_t i_mode; + grub_uint16_t i_links_count; + grub_uint32_t i_flags; + grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE]; +#define i_device_code i_bmap[0] + grub_uint64_t i_xattr; + grub_uint32_t i_generation; + grub_uint32_t i_pad; +}; + +struct grub_nilfs2_super_root +{ + grub_uint32_t sr_sum; + grub_uint16_t sr_bytes; + grub_uint16_t sr_flags; + grub_uint64_t sr_nongc_ctime; + struct grub_nilfs2_inode sr_dat; + struct grub_nilfs2_inode sr_cpfile; + struct grub_nilfs2_inode sr_sufile; +}; + +struct grub_nilfs2_super_block +{ + grub_uint32_t s_rev_level; + grub_uint16_t s_minor_rev_level; + grub_uint16_t s_magic; + grub_uint16_t s_bytes; + grub_uint16_t s_flags; + grub_uint32_t s_crc_seed; + grub_uint32_t s_sum; + grub_uint32_t s_log_block_size; + grub_uint64_t s_nsegments; + grub_uint64_t s_dev_size; + grub_uint64_t s_first_data_block; + grub_uint32_t s_blocks_per_segment; + grub_uint32_t s_r_segments_percentage; + grub_uint64_t s_last_cno; + grub_uint64_t s_last_pseg; + grub_uint64_t s_last_seq; + grub_uint64_t s_free_blocks_count; + grub_uint64_t s_ctime; + grub_uint64_t s_mtime; + grub_uint64_t s_wtime; + grub_uint16_t s_mnt_count; + grub_uint16_t s_max_mnt_count; + grub_uint16_t s_state; + grub_uint16_t s_errors; + grub_uint64_t s_lastcheck; + grub_uint32_t s_checkinterval; + grub_uint32_t s_creator_os; + grub_uint16_t s_def_resuid; + grub_uint16_t s_def_resgid; + grub_uint32_t s_first_ino; + grub_uint16_t s_inode_size; + grub_uint16_t s_dat_entry_size; + grub_uint16_t s_checkpoint_size; + grub_uint16_t s_segment_usage_size; + grub_uint8_t s_uuid[16]; + char s_volume_name[16]; + char s_last_mounted[64]; + grub_uint32_t s_c_interval; + grub_uint32_t s_c_block_max; + grub_uint32_t s_reserved[192]; +}; + +struct grub_nilfs2_dir_entry +{ + grub_uint64_t inode; + grub_uint16_t rec_len; + grub_uint8_t name_len; + grub_uint8_t file_type; +#if 0 /* followed by file name. */ + char name[NILFS_NAME_LEN]; + char pad; +#endif +} __attribute__ ((packed)); + +enum +{ + NILFS_FT_UNKNOWN, + NILFS_FT_REG_FILE, + NILFS_FT_DIR, + NILFS_FT_CHRDEV, + NILFS_FT_BLKDEV, + NILFS_FT_FIFO, + NILFS_FT_SOCK, + NILFS_FT_SYMLINK, + NILFS_FT_MAX +}; + +struct grub_nilfs2_finfo +{ + grub_uint64_t fi_ino; + grub_uint64_t fi_cno; + grub_uint32_t fi_nblocks; + grub_uint32_t fi_ndatablk; +}; + +struct grub_nilfs2_binfo_v +{ + grub_uint64_t bi_vblocknr; + grub_uint64_t bi_blkoff; +}; + +struct grub_nilfs2_binfo_dat +{ + grub_uint64_t bi_blkoff; + grub_uint8_t bi_level; + grub_uint8_t bi_pad[7]; +}; + +union grub_nilfs2_binfo +{ + struct grub_nilfs2_binfo_v bi_v; + struct grub_nilfs2_binfo_dat bi_dat; +}; + +struct grub_nilfs2_segment_summary +{ + grub_uint32_t ss_datasum; + grub_uint32_t ss_sumsum; + grub_uint32_t ss_magic; + grub_uint16_t ss_bytes; + grub_uint16_t ss_flags; + grub_uint64_t ss_seq; + grub_uint64_t ss_create; + grub_uint64_t ss_next; + grub_uint32_t ss_nblocks; + grub_uint32_t ss_nfinfo; + grub_uint32_t ss_sumbytes; + grub_uint32_t ss_pad; +}; + +struct grub_nilfs2_btree_node +{ + grub_uint8_t bn_flags; + grub_uint8_t bn_level; + grub_uint16_t bn_nchildren; + grub_uint32_t bn_pad; +}; + +struct grub_nilfs2_palloc_group_desc +{ + grub_uint32_t pg_nfrees; +}; + +struct grub_nilfs2_dat_entry +{ + grub_uint64_t de_blocknr; + grub_uint64_t de_start; + grub_uint64_t de_end; + grub_uint64_t de_rsv; +}; + +struct grub_nilfs2_snapshot_list +{ + grub_uint64_t ssl_next; + grub_uint64_t ssl_prev; +}; + +struct grub_nilfs2_cpfile_header +{ + grub_uint64_t ch_ncheckpoints; + grub_uint64_t ch_nsnapshots; + struct grub_nilfs2_snapshot_list ch_snapshot_list; +}; + +struct grub_nilfs2_checkpoint +{ + grub_uint32_t cp_flags; + grub_uint32_t cp_checkpoints_count; + struct grub_nilfs2_snapshot_list cp_snapshot_list; + grub_uint64_t cp_cno; + grub_uint64_t cp_create; + grub_uint64_t cp_nblk_inc; + grub_uint64_t cp_inodes_count; + grub_uint64_t cp_blocks_count; + struct grub_nilfs2_inode cp_ifile_inode; +}; + + +#define NILFS_BMAP_LARGE 0x1 +#define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t)) + +/* nilfs extra padding for nonroot btree node. */ +#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t)) +#define NILFS_BTREE_ROOT_SIZE NILFS_BMAP_SIZE +#define NILFS_BTREE_ROOT_NCHILDREN_MAX \ + ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \ + (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) ) + + +struct grub_fshelp_node +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_inode inode; + grub_uint64_t ino; + int inode_read; +}; + +struct grub_nilfs2_data +{ + struct grub_nilfs2_super_block sblock; + struct grub_nilfs2_super_root sroot; + struct grub_nilfs2_inode ifile; + grub_disk_t disk; + struct grub_nilfs2_inode *inode; + struct grub_fshelp_node diropen; +}; + +/* Log2 size of nilfs2 block in 512 blocks. */ +#define LOG2_NILFS2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1) + +/* Log2 size of nilfs2 block in bytes. */ +#define LOG2_BLOCK_SIZE(data) \ + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10) + +/* The size of an nilfs2 block in bytes. */ +#define NILFS2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE (data)) + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key); +static grub_dl_t my_mod; + + + +static inline unsigned long +grub_nilfs2_palloc_entries_per_group (struct grub_nilfs2_data *data) +{ + return 1UL << (LOG2_BLOCK_SIZE (data) + 3); +} + +static inline grub_uint64_t +grub_nilfs2_palloc_group (struct grub_nilfs2_data *data, + grub_uint64_t nr, grub_uint32_t * offset) +{ + return grub_divmod64 (nr, grub_nilfs2_palloc_entries_per_group (data), + offset); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_groups_per_desc_block (struct grub_nilfs2_data *data) +{ + return NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_palloc_group_desc); +} + +static inline grub_uint32_t +grub_nilfs2_entries_per_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return NILFS2_BLOCK_SIZE (data) / entry_size; +} + + +static inline grub_uint32_t +grub_nilfs2_blocks_per_group (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_div_roundup (grub_nilfs2_palloc_entries_per_group (data), + grub_nilfs2_entries_per_block (data, + entry_size)) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_blocks_per_desc_block (struct grub_nilfs2_data *data, + unsigned long entry_size) +{ + return grub_nilfs2_palloc_groups_per_desc_block (data) * + grub_nilfs2_blocks_per_group (data, entry_size) + 1; +} + +static inline grub_uint32_t +grub_nilfs2_palloc_desc_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + grub_uint32_t desc_block = + group / grub_nilfs2_palloc_groups_per_desc_block (data); + return desc_block * grub_nilfs2_blocks_per_desc_block (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_bitmap_block_offset (struct grub_nilfs2_data *data, + unsigned long group, + unsigned long entry_size) +{ + unsigned long desc_offset = group % + grub_nilfs2_palloc_groups_per_desc_block (data); + + return grub_nilfs2_palloc_desc_block_offset (data, group, entry_size) + 1 + + desc_offset * grub_nilfs2_blocks_per_group (data, entry_size); +} + +static inline grub_uint32_t +grub_nilfs2_palloc_entry_offset (struct grub_nilfs2_data *data, + grub_uint64_t nr, unsigned long entry_size) +{ + unsigned long group; + grub_uint32_t group_offset; + + group = grub_nilfs2_palloc_group (data, nr, &group_offset); + + return grub_nilfs2_palloc_bitmap_block_offset (data, group, + entry_size) + 1 + + group_offset / grub_nilfs2_entries_per_block (data, entry_size); + +} + +static inline struct grub_nilfs2_btree_node * +grub_nilfs2_btree_get_root (struct grub_nilfs2_inode *inode) +{ + return (struct grub_nilfs2_btree_node *) &inode->i_bmap[0]; +} + +static inline int +grub_nilfs2_btree_get_level (struct grub_nilfs2_btree_node *node) +{ + return node->bn_level; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dkeys (struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) ((char *) (node + 1) + + ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ? + 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node, + int index) +{ + return grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dkeys (node) + index)); +} + +static inline int +grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node, + grub_uint64_t key, int *indexp) +{ + grub_uint64_t nkey; + int index, low, high, s; + + low = 0; + high = grub_le_to_cpu16 (node->bn_nchildren) - 1; + index = 0; + s = 0; + while (low <= high) + { + index = (low + high) / 2; + nkey = grub_nilfs2_btree_node_get_key (node, index); + if (nkey == key) + { + *indexp = index; + return 1; + } + else if (nkey < key) + { + low = index + 1; + s = -1; + } + else + { + high = index - 1; + s = 1; + } + } + + if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN) + { + if (s > 0 && index > 0) + index--; + } + else if (s < 0) + index++; + + *indexp = index; + return s == 0; +} + +static inline int +grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + int node_children_max = ((NILFS2_BLOCK_SIZE (data) - + sizeof (struct grub_nilfs2_btree_node) - + NILFS_BTREE_NODE_EXTRA_PAD_SIZE) / + (sizeof (grub_uint64_t) + sizeof (grub_uint64_t))); + + return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max; +} + +static inline grub_uint64_t * +grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node) +{ + return (grub_uint64_t *) (grub_nilfs2_btree_node_dkeys (node) + + grub_nilfs2_btree_node_nchildren_max (data, + node)); +} + +static inline grub_uint64_t +grub_nilfs2_btree_node_get_ptr (struct grub_nilfs2_data *data, + struct grub_nilfs2_btree_node *node, + int index) +{ + return + grub_le_to_cpu64 (*(grub_nilfs2_btree_node_dptrs (data, node) + index)); +} + +static inline int +grub_nilfs2_btree_get_nonroot_node (struct grub_nilfs2_data *data, + grub_uint64_t ptr, void *block) +{ + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + return grub_disk_read (disk, ptr * nilfs2_block_count, 0, + NILFS2_BLOCK_SIZE (data), block); +} + +static grub_uint64_t +grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *node; + unsigned char block[NILFS2_BLOCK_SIZE (data)]; + grub_uint64_t ptr; + int level, found, index; + + node = grub_nilfs2_btree_get_root (inode); + level = grub_nilfs2_btree_get_level (node); + + found = grub_nilfs2_btree_node_lookup (node, key, &index); + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + + for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) + { + grub_nilfs2_btree_get_nonroot_node (data, ptr, block); + if (grub_errno) + { + return -1; + } + node = (struct grub_nilfs2_btree_node *) block; + + if (node->bn_level != level) + { + grub_error (GRUB_ERR_BAD_FS, "btree level mismatch\n"); + return -1; + } + + if (!found) + found = grub_nilfs2_btree_node_lookup (node, key, &index); + else + index = 0; + + if (index < grub_nilfs2_btree_node_nchildren_max (data, node)) + { + ptr = grub_nilfs2_btree_node_get_ptr (data, node, index); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + } + else + { + grub_error (GRUB_ERR_BAD_FS, "btree corruption\n"); + return -1; + } + } + + if (!found) + return -1; + + return ptr; +} + +static inline grub_uint64_t +grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key) +{ + return grub_le_to_cpu64 (inode->i_bmap[1 + key]); +} + +static inline grub_uint64_t +grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data, + struct grub_nilfs2_inode *inode, + grub_uint64_t key, int need_translate) +{ + struct grub_nilfs2_btree_node *root = grub_nilfs2_btree_get_root (inode); + if (root->bn_flags & NILFS_BMAP_LARGE) + return grub_nilfs2_btree_lookup (data, inode, key, need_translate); + else + { + grub_uint64_t ptr; + ptr = grub_nilfs2_direct_lookup (inode, key); + if (need_translate) + ptr = grub_nilfs2_dat_translate (data, ptr); + return ptr; + } +} + +static grub_uint64_t +grub_nilfs2_dat_translate (struct grub_nilfs2_data *data, grub_uint64_t key) +{ + struct grub_nilfs2_dat_entry entry; + grub_disk_t disk = data->disk; + grub_uint64_t pptr; + grub_uint32_t blockno, offset; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, key, + sizeof (struct + grub_nilfs2_dat_entry)); + + grub_divmod64 (key * sizeof (struct grub_nilfs2_dat_entry), + NILFS2_BLOCK_SIZE (data), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_dat, blockno, 0); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_dat_entry), &entry); + + return grub_le_to_cpu64 (entry.de_blocknr); +} + + +static grub_disk_addr_t +grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) +{ + struct grub_nilfs2_data *data = node->data; + struct grub_nilfs2_inode *inode = &node->inode; + grub_uint64_t pptr = -1; + + pptr = grub_nilfs2_bmap_lookup (data, inode, fileblock, 1); + if (pptr == (grub_uint64_t) - 1) + { + grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + return -1; + } + + return pptr; +} + +/* Read LEN bytes from the file described by DATA starting with byte + POS. Return the amount of read bytes in READ. */ +static grub_ssize_t +grub_nilfs2_read_file (grub_fshelp_node_t node, + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t + sector, + unsigned offset, + unsigned length), + int pos, grub_size_t len, char *buf) +{ + return grub_fshelp_read_file (node->data->disk, node, read_hook, + pos, len, buf, grub_nilfs2_read_block, + grub_le_to_cpu64 (node->inode.i_size), + LOG2_NILFS2_BLOCK_SIZE (node->data)); + +} + +static grub_err_t +grub_nilfs2_read_checkpoint (struct grub_nilfs2_data *data, + grub_uint64_t cpno, + struct grub_nilfs2_checkpoint *cpp) +{ + grub_uint64_t blockno; + grub_uint32_t offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Assume sizeof(struct grub_nilfs2_cpfile_header) < + sizeof(struct grub_nilfs2_checkpoint). + */ + blockno = grub_divmod64 (cpno, NILFS2_BLOCK_SIZE (data) / + sizeof (struct grub_nilfs2_checkpoint), &offset); + + pptr = grub_nilfs2_bmap_lookup (data, &data->sroot.sr_cpfile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, + offset * sizeof (struct grub_nilfs2_checkpoint), + sizeof (struct grub_nilfs2_checkpoint), cpp); +} + +static inline grub_err_t +grub_nilfs2_read_last_checkpoint (struct grub_nilfs2_data *data, + struct grub_nilfs2_checkpoint *cpp) +{ + return grub_nilfs2_read_checkpoint (data, + grub_le_to_cpu64 (data-> + sblock.s_last_cno), + cpp); +} + +/* Read the inode INO for the file described by DATA into INODE. */ +static grub_err_t +grub_nilfs2_read_inode (struct grub_nilfs2_data *data, + grub_uint64_t ino, struct grub_nilfs2_inode *inodep) +{ + grub_uint64_t blockno; + unsigned int offset; + grub_uint64_t pptr; + grub_disk_t disk = data->disk; + unsigned int nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + blockno = grub_nilfs2_palloc_entry_offset (data, ino, + sizeof (struct + grub_nilfs2_inode)); + + grub_divmod64 (sizeof (struct grub_nilfs2_inode) * ino, + NILFS2_BLOCK_SIZE (data), &offset); + pptr = grub_nilfs2_bmap_lookup (data, &data->ifile, blockno, 1); + if (pptr == (grub_uint64_t) - 1) + { + return grub_error (GRUB_ERR_BAD_FS, "btree lookup failure"); + } + + return grub_disk_read (disk, pptr * nilfs2_block_count, offset, + sizeof (struct grub_nilfs2_inode), inodep); +} + +static int +grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) +{ + if (grub_le_to_cpu16 (sbp->s_magic) != NILFS2_SUPER_MAGIC) + return 0; + + if (grub_le_to_cpu32 (sbp->s_rev_level) != NILFS_SUPORT_REV) + return 0; + + return 1; +} + +static struct grub_nilfs2_data * +grub_nilfs2_mount (grub_disk_t disk) +{ + struct grub_nilfs2_data *data; + struct grub_nilfs2_segment_summary ss; + struct grub_nilfs2_checkpoint last_checkpoint; + grub_uint64_t last_pseg; + grub_uint32_t nblocks; + unsigned int nilfs2_block_count; + + data = grub_malloc (sizeof (struct grub_nilfs2_data)); + if (!data) + return 0; + + /* Read the superblock. */ + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), + &data->sblock); + if (grub_errno) + goto fail; + + /* Make sure this is an nilfs2 filesystem. */ + if (!grub_nilfs2_valid_sb (&data->sblock)) + { + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + goto fail; + } + + nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); + + /* Read the last segment summary. */ + last_pseg = grub_le_to_cpu64 (data->sblock.s_last_pseg); + grub_disk_read (disk, last_pseg * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_segment_summary), &ss); + + if (grub_errno) + goto fail; + + /* Read the super root block. */ + nblocks = grub_le_to_cpu32 (ss.ss_nblocks); + grub_disk_read (disk, (last_pseg + (nblocks - 1)) * nilfs2_block_count, 0, + sizeof (struct grub_nilfs2_super_root), &data->sroot); + + if (grub_errno) + goto fail; + + data->disk = disk; + + grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); + + if (grub_errno) + goto fail; + + grub_memcpy (&data->ifile, &last_checkpoint.cp_ifile_inode, + sizeof (struct grub_nilfs2_inode)); + + data->diropen.data = data; + data->diropen.ino = 2; + data->diropen.inode_read = 1; + data->inode = &data->diropen.inode; + + grub_nilfs2_read_inode (data, 2, data->inode); + + return data; + +fail: + if (grub_errno == GRUB_ERR_OUT_OF_RANGE) + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + grub_free (data); + return 0; +} + +static char * +grub_nilfs2_read_symlink (grub_fshelp_node_t node) +{ + char *symlink; + struct grub_fshelp_node *diro = node; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + symlink = grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1); + if (!symlink) + return 0; + + grub_nilfs2_read_file (diro, 0, 0, + grub_le_to_cpu64 (diro->inode.i_size), symlink); + if (grub_errno) + { + grub_free (symlink); + return 0; + } + + symlink[grub_le_to_cpu64 (diro->inode.i_size)] = '\0'; + return symlink; +} + +static int +grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, + int NESTED_FUNC_ATTR + (*hook) (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node)) +{ + unsigned int fpos = 0; + struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir; + + if (!diro->inode_read) + { + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); + if (grub_errno) + return 0; + } + + /* Iterate files. */ + while (fpos < grub_le_to_cpu64 (diro->inode.i_size)) + { + struct grub_nilfs2_dir_entry dirent; + + grub_nilfs2_read_file (diro, 0, fpos, + sizeof (struct grub_nilfs2_dir_entry), + (char *) &dirent); + if (grub_errno) + return 0; + + if (dirent.rec_len == 0) + return 0; + + if (dirent.name_len != 0) + { + char filename[dirent.name_len + 1]; + struct grub_fshelp_node *fdiro; + enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN; + + grub_nilfs2_read_file (diro, 0, + fpos + sizeof (struct grub_nilfs2_dir_entry), + dirent.name_len, filename); + if (grub_errno) + return 0; + + fdiro = grub_malloc (sizeof (struct grub_fshelp_node)); + if (!fdiro) + return 0; + + fdiro->data = diro->data; + fdiro->ino = grub_le_to_cpu64 (dirent.inode); + + filename[dirent.name_len] = '\0'; + + if (dirent.file_type != NILFS_FT_UNKNOWN) + { + fdiro->inode_read = 0; + + if (dirent.file_type == NILFS_FT_DIR) + type = GRUB_FSHELP_DIR; + else if (dirent.file_type == NILFS_FT_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if (dirent.file_type == NILFS_FT_REG_FILE) + type = GRUB_FSHELP_REG; + } + else + { + /* The filetype can not be read from the dirent, read + the inode to get more information. */ + grub_nilfs2_read_inode (diro->data, + grub_le_to_cpu64 (dirent.inode), + &fdiro->inode); + if (grub_errno) + { + grub_free (fdiro); + return 0; + } + + fdiro->inode_read = 1; + + if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) + type = GRUB_FSHELP_DIR; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) + type = GRUB_FSHELP_SYMLINK; + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) + & FILETYPE_INO_MASK) == FILETYPE_INO_REG) + type = GRUB_FSHELP_REG; + } + + if (hook (filename, type, fdiro)) + return 1; + } + + fpos += grub_le_to_cpu16 (dirent.rec_len); + } + + return 0; +} + +/* Open a file named NAME and initialize FILE. */ +static grub_err_t +grub_nilfs2_open (struct grub_file *file, const char *name) +{ + struct grub_nilfs2_data *data = NULL; + struct grub_fshelp_node *fdiro = 0; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (file->device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (name, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_REG); + if (grub_errno) + goto fail; + + if (!fdiro->inode_read) + { + grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode); + if (grub_errno) + goto fail; + } + + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_inode)); + grub_free (fdiro); + + file->size = grub_le_to_cpu64 (data->inode->i_size); + file->data = data; + file->offset = 0; + + return 0; + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_close (grub_file_t file) +{ + grub_free (file->data); + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; +} + +/* Read LEN bytes data from FILE into BUF. */ +static grub_ssize_t +grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len) +{ + struct grub_nilfs2_data *data = (struct grub_nilfs2_data *) file->data; + + return grub_nilfs2_read_file (&data->diropen, file->read_hook, + file->offset, len, buf); +} + +static grub_err_t +grub_nilfs2_dir (grub_device_t device, const char *path, + int (*hook) (const char *filename, + const struct grub_dirhook_info * info)) +{ + struct grub_nilfs2_data *data = 0; + struct grub_fshelp_node *fdiro = 0; + + auto int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node); + + int NESTED_FUNC_ATTR iterate (const char *filename, + enum grub_fshelp_filetype filetype, + grub_fshelp_node_t node) + { + struct grub_dirhook_info info; + grub_memset (&info, 0, sizeof (info)); + if (!node->inode_read) + { + grub_nilfs2_read_inode (data, node->ino, &node->inode); + if (!grub_errno) + node->inode_read = 1; + grub_errno = GRUB_ERR_NONE; + } + if (node->inode_read) + { + info.mtimeset = 1; + info.mtime = grub_le_to_cpu64 (node->inode.i_mtime); + } + + info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR); + grub_free (node); + return hook (filename, &info); + } + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (device->disk); + if (!data) + goto fail; + + grub_fshelp_find_file (path, &data->diropen, &fdiro, + grub_nilfs2_iterate_dir, grub_nilfs2_read_symlink, + GRUB_FSHELP_DIR); + if (grub_errno) + goto fail; + + grub_nilfs2_iterate_dir (fdiro, iterate); + +fail: + if (fdiro != &data->diropen) + grub_free (fdiro); + grub_free (data); + + grub_dl_unref (my_mod); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_label (grub_device_t device, char **label) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + *label = grub_strndup (data->sblock.s_volume_name, 14); + else + *label = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +static grub_err_t +grub_nilfs2_uuid (grub_device_t device, char **uuid) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (data) + { + *uuid = + grub_xasprintf + ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%0x-%02x%02x%02x%02x%02x%02x", + data->sblock.s_uuid[0], data->sblock.s_uuid[1], + data->sblock.s_uuid[2], data->sblock.s_uuid[3], + data->sblock.s_uuid[4], data->sblock.s_uuid[5], + data->sblock.s_uuid[6], data->sblock.s_uuid[7], + data->sblock.s_uuid[8], data->sblock.s_uuid[9], + data->sblock.s_uuid[10], data->sblock.s_uuid[11], + data->sblock.s_uuid[12], data->sblock.s_uuid[13], + data->sblock.s_uuid[14], data->sblock.s_uuid[15]); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + +/* Get mtime. */ +static grub_err_t +grub_nilfs2_mtime (grub_device_t device, grub_int32_t * tm) +{ + struct grub_nilfs2_data *data; + grub_disk_t disk = device->disk; + + grub_dl_ref (my_mod); + + data = grub_nilfs2_mount (disk); + if (!data) + *tm = 0; + else + *tm = (grub_int32_t) grub_le_to_cpu64 (data->sblock.s_mtime); + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + + + +static struct grub_fs grub_nilfs2_fs = { + .name = "nilfs2", + .dir = grub_nilfs2_dir, + .open = grub_nilfs2_open, + .read = grub_nilfs2_read, + .close = grub_nilfs2_close, + .label = grub_nilfs2_label, + .uuid = grub_nilfs2_uuid, + .mtime = grub_nilfs2_mtime, +#ifdef GRUB_UTIL + .reserved_first_sector = 1, +#endif + .next = 0 +}; + +GRUB_MOD_INIT (nilfs2) +{ + grub_fs_register (&grub_nilfs2_fs); + my_mod = mod; +} + +GRUB_MOD_FINI (nilfs2) +{ + grub_fs_unregister (&grub_nilfs2_fs); +} diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index 9a859ee2e..098ae1c92 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -54,6 +54,7 @@ static void circprog_destroy (void *vself) { circular_progress_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds) *bounds = self->bounds; } +static void +circprog_set_state (void *vself, int visible, int start, + int current, int end) +{ + circular_progress_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; +} + static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { @@ -247,26 +259,20 @@ circprog_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + circprog_set_state); } return grub_errno; } -static void -circprog_set_state (void *vself, int visible, int start, - int current, int end) -{ - circular_progress_t self = vself; - self->visible = visible; - self->start = start; - self->value = current; - self->end = end; -} - static struct grub_gui_component_ops circprog_ops = { .destroy = circprog_destroy, diff --git a/gfxmenu/gui_label.c b/gfxmenu/gui_label.c index a9dd575ac..15a352f84 100644 --- a/gfxmenu/gui_label.c +++ b/gfxmenu/gui_label.c @@ -46,8 +46,10 @@ struct grub_gui_label char *id; int visible; char *text; + char *template; grub_font_t font; grub_gui_color_t color; + int value; enum align_mode align; }; @@ -57,7 +59,9 @@ static void label_destroy (void *vself) { grub_gui_label_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->text); + grub_free (self->template); grub_free (self); } @@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height) + grub_font_get_descent (self->font)); } +static void +label_set_state (void *vself, int visible, int start __attribute__ ((unused)), + int current, int end __attribute__ ((unused))) +{ + grub_gui_label_t self = vself; + self->value = -current; + self->visible = visible; + grub_free (self->text); + self->text = grub_xasprintf (self->template ? : "%d", self->value); +} + static grub_err_t label_set_property (void *vself, const char *name, const char *value) { @@ -153,9 +168,17 @@ label_set_property (void *vself, const char *name, const char *value) if (grub_strcmp (name, "text") == 0) { grub_free (self->text); + grub_free (self->template); if (! value) - value = ""; - self->text = grub_strdup (value); + { + self->template = NULL; + self->text = grub_strdup (""); + } + else + { + self->template = grub_strdup (value); + self->text = grub_xasprintf (value, self->value); + } } else if (grub_strcmp (name, "font") == 0) { @@ -183,11 +206,16 @@ label_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0) + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + label_set_state); } return GRUB_ERR_NONE; } diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index d786aae31..e1b31794f 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -60,6 +60,7 @@ static void progress_bar_destroy (void *vself) { grub_gui_progress_bar_t self = vself; + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self); } @@ -333,11 +334,16 @@ progress_bar_set_property (void *vself, const char *name, const char *value) } else if (grub_strcmp (name, "id") == 0) { + grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_free (self->id); if (value) self->id = grub_strdup (value); else self->id = 0; + /* if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID) + == 0)*/ + grub_gfxmenu_timeout_register ((grub_gui_component_t) self, + progress_bar_set_state); } return grub_errno; } @@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; + self->progress.ops = &progress_bar_pb_ops; self->progress.component.ops = &progress_bar_ops; self->visible = 1; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index bf637a96d..9a5671cdd 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -37,10 +37,6 @@ #include #include -/* The component ID identifying GUI components to be updated as the timeout - status changes. */ -#define TIMEOUT_COMPONENT_ID "__timeout__" - static void init_terminal (grub_gfxmenu_view_t view); static grub_video_rect_t term_rect; @@ -166,16 +162,28 @@ struct progress_value_data int value; }; -static void -update_timeout_visit (grub_gui_component_t component, - void *userdata) -{ - struct progress_value_data *pv; - pv = (struct progress_value_data *) userdata; +struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; - ((struct grub_gui_progress *) component)->ops - ->set_state ((struct grub_gui_progress *) component, - pv->visible, pv->start, pv->value, pv->end); +static void +update_timeouts (int visible, int start, int value, int end) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + cur->set_state (cur->self, visible, start, value, end); +} + +static void +redraw_timeouts (struct grub_gfxmenu_view *view) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + { + grub_video_rect_t bounds; + cur->self->ops->get_bounds (cur->self, &bounds); + grub_gfxmenu_view_redraw (view, &bounds); + } } void @@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data) { struct grub_gfxmenu_view *view = data; - struct progress_value_data pv; - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - if (view->first_timeout == -1) view->first_timeout = timeout; - pv.visible = 1; - pv.start = -(view->first_timeout + 1); - pv.end = 0; - pv.value = -timeout; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (1, -(view->first_timeout + 1), -timeout, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } void grub_gfxmenu_clear_timeout (void *data) { - struct progress_value_data pv; struct grub_gfxmenu_view *view = data; - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))); - - auto void redraw_timeout_visit (grub_gui_component_t component, - void *userdata __attribute__ ((unused))) - { - grub_video_rect_t bounds; - component->ops->get_bounds (component, &bounds); - grub_gfxmenu_view_redraw (view, &bounds); - } - - pv.visible = 0; - pv.start = 1; - pv.end = 0; - pv.value = 0; - - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + update_timeouts (0, 1, 0, 0); + redraw_timeouts (view); grub_video_swap_buffers (); if (view->double_repaint) - grub_gui_find_by_id ((grub_gui_component_t) view->canvas, - TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv); + redraw_timeouts (view); } static void diff --git a/include/grub/dl.h b/include/grub/dl.h index cfb7c2f99..cf5da7fd5 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -96,23 +96,8 @@ void grub_dl_unload_all (void); #else #define GRUB_NO_MODULES 0 #endif -#if GRUB_NO_MODULES -static inline int -grub_dl_ref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -static inline int -grub_dl_unref (grub_dl_t mod) -{ - (void) mod; - return 0; -} -#else int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); -#endif void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h index 21b56ae27..81a1a5797 100644 --- a/include/grub/efi/pe32.h +++ b/include/grub/efi/pe32.h @@ -99,12 +99,8 @@ struct grub_pe32_optional_header grub_uint32_t entry_addr; grub_uint32_t code_base; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 grub_uint32_t data_base; grub_uint32_t image_base; -#else - grub_uint64_t image_base; -#endif grub_uint32_t section_alignment; grub_uint32_t file_alignment; @@ -121,22 +117,11 @@ struct grub_pe32_optional_header grub_uint16_t subsystem; grub_uint16_t dll_characteristics; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - grub_uint32_t stack_reserve_size; grub_uint32_t stack_commit_size; grub_uint32_t heap_reserve_size; grub_uint32_t heap_commit_size; -#else - - grub_uint64_t stack_reserve_size; - grub_uint64_t stack_commit_size; - grub_uint64_t heap_reserve_size; - grub_uint64_t heap_commit_size; - -#endif - grub_uint32_t loader_flags; grub_uint32_t num_data_directories; @@ -159,15 +144,63 @@ struct grub_pe32_optional_header struct grub_pe32_data_directory reserved_entry; }; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 +struct grub_pe64_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint64_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + + grub_uint64_t stack_reserve_size; + grub_uint64_t stack_commit_size; + grub_uint64_t heap_reserve_size; + grub_uint64_t heap_commit_size; + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; #define GRUB_PE32_PE32_MAGIC 0x10b - -#else - -#define GRUB_PE32_PE32_MAGIC 0x20b - -#endif +#define GRUB_PE32_PE64_MAGIC 0x20b #define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 @@ -205,6 +238,7 @@ struct grub_pe32_section_table #define GRUB_PE32_SCN_ALIGN_SHIFT 20 #define GRUB_PE32_SCN_ALIGN_MASK 7 +#define GRUB_PE32_SIGNATURE_SIZE 4 struct grub_pe32_header { @@ -212,13 +246,18 @@ struct grub_pe32_header grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; /* This is always PE\0\0. */ - char signature[4]; + char signature[GRUB_PE32_SIGNATURE_SIZE]; /* The COFF file header. */ struct grub_pe32_coff_header coff_header; +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else /* The Optional header. */ struct grub_pe32_optional_header optional_header; +#endif }; struct grub_pe32_fixup_block diff --git a/include/grub/elf.h b/include/grub/elf.h index e54989cde..b9401f241 100644 --- a/include/grub/elf.h +++ b/include/grub/elf.h @@ -555,6 +555,7 @@ typedef struct #define PT_NUM 8 /* Number of defined types */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* GCC stack segment */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ diff --git a/include/grub/util/console.h b/include/grub/emu/console.h similarity index 100% rename from include/grub/util/console.h rename to include/grub/emu/console.h diff --git a/include/grub/util/getroot.h b/include/grub/emu/getroot.h similarity index 96% rename from include/grub/util/getroot.h rename to include/grub/emu/getroot.h index f9f7f9baa..dff7b4df7 100644 --- a/include/grub/util/getroot.h +++ b/include/grub/emu/getroot.h @@ -26,7 +26,6 @@ enum grub_dev_abstraction_types { }; char *grub_guess_root_device (const char *dir); -char *grub_get_prefix (const char *dir); int grub_util_get_dev_abstraction (const char *os_dev); char *grub_util_get_grub_dev (const char *os_dev); const char *grub_util_check_block_device (const char *blk_dev); diff --git a/include/grub/util/hostdisk.h b/include/grub/emu/hostdisk.h similarity index 100% rename from include/grub/util/hostdisk.h rename to include/grub/emu/hostdisk.h diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h new file mode 100644 index 000000000..e037e6be7 --- /dev/null +++ b/include/grub/emu/misc.h @@ -0,0 +1,50 @@ +#ifndef GRUB_EMU_MISC_H +#define GRUB_EMU_MISC_H 1 + +#include +#include + +#ifdef __CYGWIN__ +# include +# include +# include +# define DEV_CYGDRIVE_MAJOR 98 +#endif + +#ifdef __NetBSD__ +/* NetBSD uses /boot for its boot block. */ +# define DEFAULT_DIRECTORY "/grub" +#else +# define DEFAULT_DIRECTORY "/boot/grub" +#endif + +#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" + +extern int verbosity; +extern const char *program_name; + +void grub_init_all (void); +void grub_fini_all (void); + +char *grub_make_system_path_relative_to_its_root (const char *path); + +void * EXPORT_FUNC(xmalloc) (grub_size_t size); +void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size); +char * EXPORT_FUNC(xstrdup) (const char *str); +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + +void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); +void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); + +#ifndef HAVE_VASPRINTF +int EXPORT_FUNC(vasprintf) (char **buf, const char *fmt, va_list ap); +#endif + +#ifndef HAVE_ASPRINTF +int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); +#endif + +char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); + +#endif /* GRUB_EMU_MISC_H */ diff --git a/include/grub/gui.h b/include/grub/gui.h index 7bd71acd3..6e4a11cbe 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -22,10 +22,15 @@ #include #include #include +#include #ifndef GRUB_GUI_H #define GRUB_GUI_H 1 +/* The component ID identifying GUI components to be updated as the timeout + status changes. */ +#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" + /* A representation of a color. Unlike grub_video_color_t, this representation is independent of any video mode specifics. */ typedef struct grub_gui_color @@ -79,6 +84,46 @@ struct grub_gui_progress_ops void (*set_state) (void *self, int visible, int start, int current, int end); }; +typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start, + int current, int end); + +struct grub_gfxmenu_timeout_notify +{ + struct grub_gfxmenu_timeout_notify *next; + grub_gfxmenu_set_state_t set_state; + grub_gui_component_t self; +}; + +extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; + +static inline grub_err_t +grub_gfxmenu_timeout_register (grub_gui_component_t self, + grub_gfxmenu_set_state_t set_state) +{ + struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne)); + if (!ne) + return grub_errno; + ne->set_state = set_state; + ne->self = self; + ne->next = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = ne; + return GRUB_ERR_NONE; +} + +static inline void +grub_gfxmenu_timeout_unregister (grub_gui_component_t self) +{ + struct grub_gfxmenu_timeout_notify **p, *q; + + for (p = &grub_gfxmenu_timeout_notifications, q = *p; + q; p = &(q->next), q = q->next) + if (q->self == self) + { + *p = q->next; + break; + } +} + typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 9e7f52d45..57ca1c45b 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -42,17 +42,33 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ # ifdef GRUB_UTIL -# define gettext(Msgid) ((const char *) (Msgid)) +static inline const char * __attribute__ ((always_inline)) +gettext (const char *str) +{ + return str; +} # else -# define grub_gettext(str) ((const char *) (str)) +static inline const char * __attribute__ ((always_inline)) +grub_gettext (const char *str) +{ + return str; +} # endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #ifdef GRUB_UTIL -# define _(str) gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return gettext(str); +} #else -# define _(str) grub_gettext(str) +static inline const char * __attribute__ ((always_inline)) +_ (const char *str) +{ + return grub_gettext(str); +} #endif /* GRUB_UTIL */ #define N_(str) str diff --git a/include/grub/i386/coreboot/kernel.h b/include/grub/i386/coreboot/kernel.h deleted file mode 100644 index fb60668cc..000000000 --- a/include/grub/i386/coreboot/kernel.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE -extern char grub_prefix[]; -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/i386/coreboot/memory.h b/include/grub/i386/coreboot/memory.h index 434ae622e..664086a81 100644 --- a/include/grub/i386/coreboot/memory.h +++ b/include/grub/i386/coreboot/memory.h @@ -44,8 +44,9 @@ typedef struct grub_linuxbios_table_header *grub_linuxbios_table_header_t; struct grub_linuxbios_table_item { -#define GRUB_LINUXBIOS_MEMBER_UNUSED 0 -#define GRUB_LINUXBIOS_MEMBER_MEMORY 1 +#define GRUB_LINUXBIOS_MEMBER_UNUSED 0x00 +#define GRUB_LINUXBIOS_MEMBER_MEMORY 0x01 +#define GRUB_LINUXBIOS_MEMBER_LINK 0x11 grub_uint32_t tag; grub_uint32_t size; }; diff --git a/include/grub/i386/efi/kernel.h b/include/grub/i386/efi/kernel.h deleted file mode 100644 index c0549f41a..000000000 --- a/include/grub/i386/efi/kernel.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/i386/ieee1275/kernel.h b/include/grub/i386/ieee1275/kernel.h deleted file mode 100644 index dccf8cbe1..000000000 --- a/include/grub/i386/ieee1275/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/include/grub/i386/kernel.h b/include/grub/i386/kernel.h deleted file mode 100644 index 5514c8ccf..000000000 --- a/include/grub/i386/kernel.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - - -#ifdef GRUB_MACHINE_IEEE1275 -#define GRUB_MOD_ALIGN 0x1000 -#else -#define GRUB_MOD_ALIGN 0x1 -#endif - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - -#endif diff --git a/include/grub/i386/multiboot/boot.h b/include/grub/i386/multiboot/boot.h new file mode 100644 index 000000000..c33f9bac0 --- /dev/null +++ b/include/grub/i386/multiboot/boot.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/console.h b/include/grub/i386/multiboot/console.h new file mode 100644 index 000000000..774399a4e --- /dev/null +++ b/include/grub/i386/multiboot/console.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/init.h b/include/grub/i386/multiboot/init.h new file mode 100644 index 000000000..fd935c3a2 --- /dev/null +++ b/include/grub/i386/multiboot/init.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/kernel.h b/include/grub/i386/multiboot/kernel.h new file mode 100644 index 000000000..b41e86ebb --- /dev/null +++ b/include/grub/i386/multiboot/kernel.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/loader.h b/include/grub/i386/multiboot/loader.h new file mode 100644 index 000000000..1c725be19 --- /dev/null +++ b/include/grub/i386/multiboot/loader.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/memory.h b/include/grub/i386/multiboot/memory.h new file mode 100644 index 000000000..8dd6f7c8c --- /dev/null +++ b/include/grub/i386/multiboot/memory.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/serial.h b/include/grub/i386/multiboot/serial.h new file mode 100644 index 000000000..2d8563414 --- /dev/null +++ b/include/grub/i386/multiboot/serial.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/multiboot/time.h b/include/grub/i386/multiboot/time.h new file mode 100644 index 000000000..7177c7488 --- /dev/null +++ b/include/grub/i386/multiboot/time.h @@ -0,0 +1 @@ +#include diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index e88c62b71..a4d42ff3c 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -19,6 +19,8 @@ #ifndef GRUB_BOOT_MACHINE_HEADER #define GRUB_BOOT_MACHINE_HEADER 1 +#include + /* The signature for bootloader. */ #define GRUB_BOOT_MACHINE_SIGNATURE 0xaa55 @@ -57,9 +59,6 @@ floppy. */ #define GRUB_BOOT_MACHINE_BIOS_HD_FLAG 0x80 -/* The segment where the kernel is loaded. */ -#define GRUB_BOOT_MACHINE_KERNEL_SEG 0x800 - /* The address where the kernel is loaded. */ #define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4) @@ -68,16 +67,7 @@ #define GRUB_BOOT_MACHINE_PXE_DL 0x7f -#ifndef ASM_FILE - /* This is the blocklist used in the diskboot image. */ -struct grub_boot_blocklist -{ - grub_uint64_t start; - grub_uint16_t len; - grub_uint16_t segment; -} __attribute__ ((packed)); - -#endif /* ! ASM_FILE */ +#define grub_boot_blocklist grub_pc_bios_boot_blocklist #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index e830afae2..1de37a5d5 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -19,29 +19,7 @@ #ifndef KERNEL_MACHINE_HEADER #define KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 - -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_INSTALL_DOS_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART 0x14 - -/* The offset of GRUB_INSTALL_BSD_PART. */ -#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART 0x18 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x1c - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x5c - -/* The size of the first region which won't be compressed. */ -#define GRUB_KERNEL_MACHINE_RAW_SIZE (GRUB_KERNEL_MACHINE_DATA_END + 0x5F0) +#include /* Enable LZMA compression */ #define ENABLE_LZMA 1 @@ -63,10 +41,6 @@ extern grub_int32_t grub_install_dos_part; /* The BSD partition number of the installed partition. */ extern grub_int32_t grub_install_bsd_part; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - /* The boot BIOS drive number. */ extern grub_uint8_t EXPORT_VAR(grub_boot_drive); diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h index 841b06164..68f5e8bc9 100644 --- a/include/grub/i386/pc/memory.h +++ b/include/grub/i386/pc/memory.h @@ -29,6 +29,8 @@ #include +#include + /* The scratch buffer used in real mode code. */ #define GRUB_MEMORY_MACHINE_SCRATCH_ADDR 0x68000 #define GRUB_MEMORY_MACHINE_SCRATCH_SEG (GRUB_MEMORY_MACHINE_SCRATCH_ADDR >> 4) @@ -40,9 +42,6 @@ /* The size of the protect mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK_SIZE 0x8000 -/* The upper memory area (starting at 640 kiB). */ -#define GRUB_MEMORY_MACHINE_UPPER 0xa0000 - /* The protected mode stack. */ #define GRUB_MEMORY_MACHINE_PROT_STACK \ (GRUB_MEMORY_MACHINE_SCRATCH_ADDR + GRUB_MEMORY_MACHINE_SCRATCH_SIZE \ diff --git a/include/grub/i386/qemu/boot.h b/include/grub/i386/qemu/boot.h index 6fbb57750..5f53eabfb 100644 --- a/include/grub/i386/qemu/boot.h +++ b/include/grub/i386/qemu/boot.h @@ -22,7 +22,4 @@ /* The size of boot.img. */ #define GRUB_BOOT_MACHINE_SIZE (0x100000 - GRUB_BOOT_MACHINE_LINK_ADDR) -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR 0x4 - #endif diff --git a/include/grub/i386/qemu/kernel.h b/include/grub/i386/qemu/kernel.h index bc0b93d4f..0aa2b3d09 100644 --- a/include/grub/i386/qemu/kernel.h +++ b/include/grub/i386/qemu/kernel.h @@ -19,17 +19,7 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -/* The offset of GRUB_CORE_ENTRY_ADDR. */ -#define GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR 0x8 - -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x10 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 +#include #ifndef ASM_FILE @@ -44,10 +34,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h index 2b2c36f8f..b30909c68 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h @@ -100,6 +100,9 @@ enum grub_ieee1275_flag /* Open Hack'Ware don't support the ANSI sequence. */ GRUB_IEEE1275_FLAG_NO_ANSI, + + /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ + GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/include/grub/kernel.h b/include/grub/kernel.h index bf52ffcb4..fed875db1 100644 --- a/include/grub/kernel.h +++ b/include/grub/kernel.h @@ -42,19 +42,33 @@ struct grub_module_header /* "gmim" (GRUB Module Info Magic). */ #define GRUB_MODULE_MAGIC 0x676d696d -struct grub_module_info +struct grub_module_info32 { /* Magic number so we know we have modules present. */ grub_uint32_t magic; -#if GRUB_TARGET_SIZEOF_VOID_P == 8 - grub_uint32_t padding; -#endif /* The offset of the modules. */ - grub_target_off_t offset; + grub_uint32_t offset; /* The size of all modules plus this header. */ - grub_target_size_t size; + grub_uint32_t size; }; +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + extern grub_addr_t grub_arch_modules_addr (void); extern void EXPORT_FUNC(grub_module_iterate) (int (*hook) (struct grub_module_header *)); @@ -76,4 +90,8 @@ void grub_machine_set_prefix (void); /* Register all the exported symbols. This is automatically generated. */ void grub_register_exported_symbols (void); +#if ! defined (ASM_FILE) && !defined (GRUB_MACHINE_EMU) +extern char grub_prefix[]; +#endif + #endif /* ! GRUB_KERNEL_HEADER */ diff --git a/include/grub/menu.h b/include/grub/menu.h index 78f461b92..e5e5fb110 100644 --- a/include/grub/menu.h +++ b/include/grub/menu.h @@ -47,6 +47,8 @@ struct grub_menu_entry /* The sourcecode of the menu entry, used by the editor. */ const char *sourcecode; + int hotkey; + /* The next element. */ struct grub_menu_entry *next; }; diff --git a/include/grub/mips/kernel.h b/include/grub/mips/kernel.h deleted file mode 100644 index 8b68f7b6b..000000000 --- a/include/grub/mips/kernel.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x1 -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#define GRUB_KERNEL_MACHINE_LINK_ALIGN 32 - -#define GRUB_KERNEL_CPU_RAW_SIZE 0x200 -#define GRUB_KERNEL_CPU_COMPRESSED_SIZE 0x8 -#define GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE 0xc -#define GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE 0x10 - -#define GRUB_KERNEL_CPU_PREFIX GRUB_KERNEL_CPU_RAW_SIZE -#define GRUB_KERNEL_CPU_DATA_END GRUB_KERNEL_CPU_RAW_SIZE + 0x48 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_KERNEL_CPU_RAW_SIZE - -#define GRUB_KERNEL_MACHINE_PREFIX GRUB_KERNEL_CPU_PREFIX -#define GRUB_KERNEL_MACHINE_DATA_END GRUB_KERNEL_CPU_DATA_END -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_KERNEL_CPU_COMPRESSED_SIZE - -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, elf" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - -#ifndef ASM_FILE - -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_ELF -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_ELF GRUB_PLATFORM_IMAGE_ELF - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif diff --git a/include/grub/mips/qemu-mips/kernel.h b/include/grub/mips/qemu-mips/kernel.h index dbf74c1b2..230455dbf 100644 --- a/include/grub/mips/qemu-mips/kernel.h +++ b/include/grub/mips/qemu-mips/kernel.h @@ -27,10 +27,6 @@ void EXPORT_FUNC (grub_reboot) (void); void EXPORT_FUNC (grub_halt) (void); -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/mips/yeeloong/boot.h b/include/grub/mips/yeeloong/boot.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/include/grub/mips/yeeloong/kernel.h b/include/grub/mips/yeeloong/kernel.h index 230455dbf..c08405e83 100644 --- a/include/grub/mips/yeeloong/kernel.h +++ b/include/grub/mips/yeeloong/kernel.h @@ -20,7 +20,6 @@ #define GRUB_KERNEL_MACHINE_HEADER 1 #include -#include #ifndef ASM_FILE diff --git a/include/grub/multiboot.h b/include/grub/multiboot.h index 49d71fa09..63947d1bc 100644 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@ -49,7 +49,7 @@ void grub_multiboot_set_bootdev (void); grub_uint32_t grub_get_multiboot_mmap_count (void); grub_err_t grub_multiboot_set_video_mode (void); -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include #define GRUB_MACHINE_HAS_VGA_TEXT 1 #else diff --git a/include/grub/offsets.h b/include/grub/offsets.h new file mode 100644 index 000000000..ae0b2557e --- /dev/null +++ b/include/grub/offsets.h @@ -0,0 +1,173 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2007,2008 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef OFFSETS_HEADER +#define OFFSETS_HEADER 1 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_INSTALL_DOS_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x14 + +/* The offset of GRUB_INSTALL_BSD_PART. */ +#define GRUB_KERNEL_I386_PC_INSTALL_BSD_PART 0x18 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_PC_PREFIX 0x1c + +/* End of the data section. */ +#define GRUB_KERNEL_I386_PC_DATA_END 0x5c + +/* The size of the first region which won't be compressed. */ +#define GRUB_KERNEL_I386_PC_RAW_SIZE (GRUB_KERNEL_I386_PC_DATA_END + 0x5F0) + +/* The segment where the kernel is loaded. */ +#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 + +#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200 + +/* The upper memory area (starting at 640 kiB). */ +#define GRUB_MEMORY_I386_PC_UPPER 0xa0000 +#define GRUB_MEMORY_I386_QEMU_UPPER GRUB_MEMORY_I386_PC_UPPER + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR 0x4 + +/* The offset of GRUB_CORE_ENTRY_ADDR. */ +#define GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_QEMU_PREFIX 0x10 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_QEMU_DATA_END 0x50 + +#define GRUB_KERNEL_I386_QEMU_LINK_ADDR 0x8200 + +/* The offset of GRUB_TOTAL_MODULE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE 0x8 + +/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE 0xc + +/* The offset of GRUB_COMPRESSED_SIZE. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE 0x10 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_PREFIX 0x14 + +/* End of the data section. */ +#define GRUB_KERNEL_SPARC64_IEEE1275_DATA_END 0x114 + +#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12 + +#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400 +#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0 +#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 + +#define GRUB_KERNEL_POWERPC_IEEE1275_PREFIX 0x4 +#define GRUB_KERNEL_POWERPC_IEEE1275_DATA_END 0x44 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 +#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 + +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR 0x80200000 + +#define GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN 32 + +#define GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE 0x200 +#define GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE 0x8 +#define GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE 0xc +#define GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE 0x10 + +#define GRUB_KERNEL_MIPS_YEELOONG_PREFIX GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE +#define GRUB_KERNEL_MIPS_YEELOONG_DATA_END GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE + 0x48 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_I386_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_I386_EFI_DATA_END 0x50 + +/* The offset of GRUB_PREFIX. */ +#define GRUB_KERNEL_X86_64_EFI_PREFIX 0x8 + +/* End of the data section. */ +#define GRUB_KERNEL_X86_64_EFI_DATA_END 0x50 + +#define GRUB_KERNEL_I386_COREBOOT_PREFIX 0x2 +#define GRUB_KERNEL_I386_COREBOOT_DATA_END 0x42 +#define GRUB_KERNEL_I386_COREBOOT_LINK_ADDR 0x8200 + +#define GRUB_KERNEL_I386_IEEE1275_PREFIX 0x2 +#define GRUB_KERNEL_I386_IEEE1275_DATA_END 0x42 +#define GRUB_KERNEL_I386_IEEE1275_LINK_ADDR 0x10000 + +#define GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN 0x1000 +#define GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN 0x1 + +/* Non-zero value is only needed for PowerMacs. */ +#define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0 +#define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0 + +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000 + +#define GRUB_KERNEL_MIPS_YEELOONG_MOD_ALIGN 0x1 + +/* Minimal gap between _end and the start of the modules. It's a hack + for PowerMac to prevent "CLAIM failed" error. The real fix is to + rewrite grub-mkimage to generate valid ELF files. */ +#define GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP 0x8000 + +#ifdef MACHINE +#define GRUB_OFFSETS_CONCAT_(a,b,c) a ## b ## c +#define GRUB_OFFSETS_CONCAT(a,b,c) GRUB_OFFSETS_CONCAT_(a,b,c) +#define GRUB_KERNEL_MACHINE_MOD_ALIGN GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_ALIGN) +#define GRUB_KERNEL_MACHINE_MOD_GAP GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _MOD_GAP) +#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _TOTAL_MODULE_SIZE) +#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _KERNEL_IMAGE_SIZE) +#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _COMPRESSED_SIZE) + +#define GRUB_KERNEL_MACHINE_PREFIX GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _PREFIX) +#define GRUB_KERNEL_MACHINE_DATA_END GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _DATA_END) +#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, MACHINE, _KERNEL_SEG) +#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, MACHINE, _UPPER) +#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _RAW_SIZE) +#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_BSD_PART) +#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, MACHINE, _INSTALL_DOS_PART) +#endif + +#ifndef ASM_FILE +struct grub_pc_bios_boot_blocklist +{ + grub_uint64_t start; + grub_uint16_t len; + grub_uint16_t segment; +} __attribute__ ((packed)); +#endif + +#endif diff --git a/include/grub/powerpc/ieee1275/kernel.h b/include/grub/powerpc/ieee1275/kernel.h deleted file mode 100644 index a76c2a4df..000000000 --- a/include/grub/powerpc/ieee1275/kernel.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_MACHINE_HEADER -#define GRUB_KERNEL_MACHINE_HEADER 1 - -#include - -#ifndef ASM_FILE - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -#endif - -#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/powerpc/kernel.h b/include/grub/powerpc/kernel.h index b4687337f..3fc0b9e23 100644 --- a/include/grub/powerpc/kernel.h +++ b/include/grub/powerpc/kernel.h @@ -19,14 +19,4 @@ #ifndef GRUB_KERNEL_CPU_HEADER #define GRUB_KERNEL_CPU_HEADER 1 -#define GRUB_MOD_ALIGN 0x1000 - -/* Minimal gap between _end and the start of the modules. It's a hack - for PowerMac to prevent "CLAIM failed" error. The real fix is to - rewrite grub-mkimage to generate valid ELF files. */ -#define GRUB_MOD_GAP 0x8000 - -#define GRUB_KERNEL_CPU_PREFIX 0x4 -#define GRUB_KERNEL_CPU_DATA_END 0x44 - #endif diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 9eccb9028..87fb26f93 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -67,6 +67,13 @@ struct grub_script_arg struct grub_script_arg *next; }; +/* An argument vector. */ +struct grub_script_argv +{ + unsigned argc; + char **args; +}; + /* A complete argument. It consists of a list of one or more `struct grub_script_arg's. */ struct grub_script_arglist @@ -86,15 +93,6 @@ struct grub_script_cmdline struct grub_script_arglist *arglist; }; -/* A block of commands, this can be used to group commands. */ -struct grub_script_cmdblock -{ - struct grub_script_cmd cmd; - - /* A chain of commands. */ - struct grub_script_cmd *cmdlist; -}; - /* An if statement. */ struct grub_script_cmdif { @@ -228,6 +226,11 @@ struct grub_parser_param struct grub_lexer_param *lexerstate; }; +void grub_script_argv_free (struct grub_script_argv *argv); +int grub_script_argv_next (struct grub_script_argv *argv); +int grub_script_argv_append (struct grub_script_argv *argv, const char *s); +int grub_script_argv_split_append (struct grub_script_argv *argv, char *s); + struct grub_script_arglist * grub_script_create_arglist (struct grub_parser_param *state); @@ -238,8 +241,6 @@ grub_script_add_arglist (struct grub_parser_param *state, struct grub_script_cmd * grub_script_create_cmdline (struct grub_parser_param *state, struct grub_script_arglist *arglist); -struct grub_script_cmd * -grub_script_create_cmdblock (struct grub_parser_param *state); struct grub_script_cmd * grub_script_create_cmdif (struct grub_parser_param *state, @@ -266,9 +267,9 @@ grub_script_create_cmdmenu (struct grub_parser_param *state, int options); struct grub_script_cmd * -grub_script_add_cmd (struct grub_parser_param *state, - struct grub_script_cmdblock *cmdblock, - struct grub_script_cmd *cmd); +grub_script_append_cmd (struct grub_parser_param *state, + struct grub_script_cmd *list, + struct grub_script_cmd *last); struct grub_script_arg * grub_script_arg_add (struct grub_parser_param *state, struct grub_script_arg *arg, @@ -305,7 +306,7 @@ void grub_script_yyerror (struct grub_parser_param *, char const *); /* Commands to execute, don't use these directly. */ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd); -grub_err_t grub_script_execute_cmdblock (struct grub_script_cmd *cmd); +grub_err_t grub_script_execute_cmdlist (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdif (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd); grub_err_t grub_script_execute_cmdwhile (struct grub_script_cmd *cmd); @@ -344,8 +345,8 @@ grub_script_function_t grub_script_function_create (struct grub_script_arg *func void grub_script_function_remove (const char *name); grub_script_function_t grub_script_function_find (char *functionname); int grub_script_function_iterate (int (*iterate) (grub_script_function_t)); -int grub_script_function_call (grub_script_function_t func, - int argc, char **args); +grub_err_t grub_script_function_call (grub_script_function_t func, + int argc, char **args); char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); diff --git a/include/grub/sparc64/ieee1275/boot.h b/include/grub/sparc64/ieee1275/boot.h index 9671c6900..bd0a7bf3c 100644 --- a/include/grub/sparc64/ieee1275/boot.h +++ b/include/grub/sparc64/ieee1275/boot.h @@ -50,10 +50,6 @@ #define GRUB_BOOT_MACHINE_CODE_END \ (0x1fc - GRUB_BOOT_AOUT_HEADER_SIZE) -#define GRUB_BOOT_MACHINE_LIST_SIZE 12 - -#define GRUB_BOOT_MACHINE_IMAGE_ADDRESS 0x4400 - #define GRUB_BOOT_MACHINE_KERNEL_ADDR 0x4200 #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/sparc64/ieee1275/kernel.h b/include/grub/sparc64/ieee1275/kernel.h index a16fb88e7..5aa50b852 100644 --- a/include/grub/sparc64/ieee1275/kernel.h +++ b/include/grub/sparc64/ieee1275/kernel.h @@ -19,44 +19,10 @@ #ifndef GRUB_KERNEL_MACHINE_HEADER #define GRUB_KERNEL_MACHINE_HEADER 1 -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -/* The offset of GRUB_TOTAL_MODULE_SIZE. */ -#define GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE 0x8 - -/* The offset of GRUB_KERNEL_IMAGE_SIZE. */ -#define GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE 0xc - -/* The offset of GRUB_COMPRESSED_SIZE. */ -#define GRUB_KERNEL_MACHINE_COMPRESSED_SIZE 0x10 - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x14 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x114 - -#define GRUB_KERNEL_MACHINE_RAW_SIZE 0 #define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000 -#define GRUB_PLATFORM_IMAGE_FORMATS "raw, aout" -#define GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT "raw" - -#define GRUB_PLATFORM_IMAGE_DEFAULT GRUB_PLATFORM_IMAGE_RAW - #ifndef ASM_FILE -typedef enum { - GRUB_PLATFORM_IMAGE_RAW, - GRUB_PLATFORM_IMAGE_AOUT -} - grub_platform_image_format_t; -#define GRUB_PLATFORM_IMAGE_RAW GRUB_PLATFORM_IMAGE_RAW -#define GRUB_PLATFORM_IMAGE_AOUT GRUB_PLATFORM_IMAGE_AOUT - #include #include @@ -66,10 +32,6 @@ extern grub_int32_t grub_kernel_image_size; /* The total size of module images following the kernel. */ extern grub_int32_t grub_total_module_size; -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - #endif /* ! ASM_FILE */ #endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/include/grub/sparc64/kernel.h b/include/grub/sparc64/kernel.h deleted file mode 100644 index 9f404b05d..000000000 --- a/include/grub/sparc64/kernel.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_KERNEL_CPU_HEADER -#define GRUB_KERNEL_CPU_HEADER 1 - -#define GRUB_MOD_ALIGN 0x2000 - -/* Non-zero value is only needed for PowerMacs. */ -#define GRUB_MOD_GAP 0x0 - -#define GRUB_KERNEL_CPU_PREFIX 0x2 -#define GRUB_KERNEL_CPU_DATA_END 0x42 - -#endif diff --git a/include/grub/types.h b/include/grub/types.h index 9eaafd0c1..6e9461f1d 100644 --- a/include/grub/types.h +++ b/include/grub/types.h @@ -178,21 +178,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) ((grub_uint16_t) (x)) # define grub_be_to_cpu32(x) ((grub_uint32_t) (x)) # define grub_be_to_cpu64(x) ((grub_uint64_t) (x)) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# endif #else /* ! WORDS_BIGENDIAN */ # define grub_cpu_to_le16(x) ((grub_uint16_t) (x)) # define grub_cpu_to_le32(x) ((grub_uint32_t) (x)) @@ -206,27 +191,6 @@ static inline grub_uint64_t grub_swap_bytes64(grub_uint64_t x) # define grub_be_to_cpu16(x) grub_swap_bytes16(x) # define grub_be_to_cpu32(x) grub_swap_bytes32(x) # define grub_be_to_cpu64(x) grub_swap_bytes64(x) -# ifdef GRUB_TARGET_WORDS_BIGENDIAN -# define grub_target_to_host16(x) grub_swap_bytes16(x) -# define grub_target_to_host32(x) grub_swap_bytes32(x) -# define grub_target_to_host64(x) grub_swap_bytes64(x) -# define grub_host_to_target16(x) grub_swap_bytes16(x) -# define grub_host_to_target32(x) grub_swap_bytes32(x) -# define grub_host_to_target64(x) grub_swap_bytes64(x) -# else /* ! GRUB_TARGET_WORDS_BIGENDIAN */ -# define grub_target_to_host16(x) ((grub_uint16_t) (x)) -# define grub_target_to_host32(x) ((grub_uint32_t) (x)) -# define grub_target_to_host64(x) ((grub_uint64_t) (x)) -# define grub_host_to_target16(x) ((grub_uint16_t) (x)) -# define grub_host_to_target32(x) ((grub_uint32_t) (x)) -# define grub_host_to_target64(x) ((grub_uint64_t) (x)) -# endif #endif /* ! WORDS_BIGENDIAN */ -#if GRUB_TARGET_SIZEOF_VOID_P == 8 -# define grub_host_to_target_addr(x) grub_host_to_target64(x) -#else -# define grub_host_to_target_addr(x) grub_host_to_target32(x) -#endif - #endif /* ! GRUB_TYPES_HEADER */ diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index 8b78b92ea..48dfbb868 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -28,26 +28,7 @@ #include #include #include - -#ifdef __NetBSD__ -/* NetBSD uses /boot for its boot block. */ -# define DEFAULT_DIRECTORY "/grub" -#else -# define DEFAULT_DIRECTORY "/boot/grub" -#endif - -#define DEFAULT_DEVICE_MAP DEFAULT_DIRECTORY "/device.map" - -extern char *progname; -extern int verbosity; - -void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...); -void EXPORT_FUNC(grub_util_info) (const char *fmt, ...); -void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((noreturn)); - -void *xmalloc (size_t size); -void *xrealloc (void *ptr, size_t size); -char *xstrdup (const char *str); +#include char *grub_util_get_path (const char *dir, const char *file); size_t grub_util_get_fp_size (FILE *fp); @@ -59,20 +40,6 @@ void grub_util_write_image (const char *img, size_t size, FILE *out); void grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out); -#ifndef HAVE_VASPRINTF - -int vasprintf (char **buf, const char *fmt, va_list ap); - -#endif - -#ifndef HAVE_ASPRINTF - -int asprintf (char **buf, const char *fmt, ...); - -#endif - -char *xasprintf (const char *fmt, ...); - #ifdef __MINGW32__ #define fseeko fseeko64 diff --git a/include/grub/video.h b/include/grub/video.h index 782a5281b..5fd7e0c47 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -181,7 +181,8 @@ typedef enum grub_video_driver_id GRUB_VIDEO_DRIVER_VBE, GRUB_VIDEO_DRIVER_EFI_UGA, GRUB_VIDEO_DRIVER_EFI_GOP, - GRUB_VIDEO_DRIVER_SM712 + GRUB_VIDEO_DRIVER_SM712, + GRUB_VIDEO_DRIVER_VGA } grub_video_driver_id_t; struct grub_video_adapter diff --git a/include/grub/mips/qemu-mips/boot.h b/include/grub/x86_64/efi/boot.h similarity index 100% rename from include/grub/mips/qemu-mips/boot.h rename to include/grub/x86_64/efi/boot.h diff --git a/include/grub/x86_64/efi/kernel.h b/include/grub/x86_64/efi/kernel.h deleted file mode 100644 index c0549f41a..000000000 --- a/include/grub/x86_64/efi/kernel.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2007 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef GRUB_MACHINE_KERNEL_HEADER -#define GRUB_MACHINE_KERNEL_HEADER 1 - -/* The prefix which points to the directory where GRUB modules and its - configuration file are located. */ -extern char grub_prefix[]; - -/* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x8 - -/* End of the data section. */ -#define GRUB_KERNEL_MACHINE_DATA_END 0x50 - -#endif /* ! GRUB_MACHINE_KERNEL_HEADER */ - diff --git a/include/grub/x86_64/kernel.h b/include/grub/x86_64/kernel.h deleted file mode 100644 index 25ac57e40..000000000 --- a/include/grub/x86_64/kernel.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/kern/corecmd.c b/kern/corecmd.c index 8b8df63cb..9af706e94 100644 --- a/kern/corecmd.c +++ b/kern/corecmd.c @@ -26,6 +26,7 @@ #include #include #include +#include /* set ENVVAR=VALUE */ static grub_err_t @@ -178,11 +179,13 @@ void grub_register_core_commands (void) { grub_register_command ("set", grub_core_cmd_set, - "[ENVVAR=VALUE]", "Set an environment variable."); + N_("[ENVVAR=VALUE]"), + N_("Set an environment variable.")); grub_register_command ("unset", grub_core_cmd_unset, - "ENVVAR", "Remove an environment variable."); + N_("ENVVAR"), + N_("Remove an environment variable.")); grub_register_command ("ls", grub_core_cmd_ls, - "[ARG]", "List devices or files."); + N_("[ARG]"), N_("List devices or files.")); grub_register_command ("insmod", grub_core_cmd_insmod, - "MODULE", "Insert a module."); + N_("MODULE"), N_("Insert a module.")); } diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..c6a038cfa 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -469,12 +469,14 @@ grub_dl_resolve_dependencies (grub_dl_t mod, Elf_Ehdr *e) return GRUB_ERR_NONE; } -#if !GRUB_NO_MODULES int grub_dl_ref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_ref (dep->mod); @@ -486,12 +488,14 @@ grub_dl_unref (grub_dl_t mod) { grub_dl_dep_t dep; + if (!mod) + return 0; + for (dep = mod->dep; dep; dep = dep->next) grub_dl_unref (dep->mod); return --mod->ref_count; } -#endif static void grub_dl_flush_cache (grub_dl_t mod) diff --git a/kern/efi/init.c b/kern/efi/init.c index a0b4ff779..b79084a6a 100644 --- a/kern/efi/init.c +++ b/kern/efi/init.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include void grub_efi_init (void) @@ -42,39 +42,58 @@ grub_efi_init (void) void grub_efi_set_prefix (void) { - grub_efi_loaded_image_t *image; + grub_efi_loaded_image_t *image = NULL; + char *device = NULL; + char *path = NULL; - image = grub_efi_get_loaded_image (grub_efi_image_handle); - if (image) + { + char *pptr = NULL; + if (grub_prefix[0] == '(') + { + pptr = grub_strrchr (grub_prefix, ')'); + if (pptr) + { + device = grub_strndup (grub_prefix + 1, pptr - grub_prefix - 1); + pptr++; + } + } + if (!pptr) + pptr = grub_prefix; + if (pptr[0]) + path = grub_strdup (pptr); + } + + if (!device || !path) + image = grub_efi_get_loaded_image (grub_efi_image_handle); + if (image && !device) + device = grub_efidisk_get_device_name (image->device_handle); + + if (image && !path) { - char *device; - char *file; + char *p; - device = grub_efidisk_get_device_name (image->device_handle); - file = grub_efi_get_filename (image->file_path); + path = grub_efi_get_filename (image->file_path); - if (device && file) - { - char *p; - char *prefix; - - /* Get the directory. */ - p = grub_strrchr (file, '/'); - if (p) - *p = '\0'; - - prefix = grub_xasprintf ("(%s)%s", device, file); - if (prefix) - { - - grub_env_set ("prefix", prefix); - grub_free (prefix); - } - } - - grub_free (device); - grub_free (file); + /* Get the directory. */ + p = grub_strrchr (path, '/'); + if (p) + *p = '\0'; } + + if (device && path) + { + char *prefix; + + prefix = grub_xasprintf ("(%s)%s", device, path); + if (prefix) + { + grub_env_set ("prefix", prefix); + grub_free (prefix); + } + } + + grub_free (device); + grub_free (path); } void diff --git a/util/console.c b/kern/emu/console.c similarity index 99% rename from util/console.c rename to kern/emu/console.c index 382fd7f89..f7fbc899a 100644 --- a/util/console.c +++ b/kern/emu/console.c @@ -27,7 +27,7 @@ # define A_STANDOUT 0 #endif /* ! A_STANDOUT */ -#include +#include #include #include diff --git a/util/getroot.c b/kern/emu/getroot.c similarity index 83% rename from util/getroot.c rename to kern/emu/getroot.c index 94eadc5e1..6875044da 100644 --- a/util/getroot.c +++ b/kern/emu/getroot.c @@ -19,16 +19,15 @@ #include #include +#include +#include #include #include #include - -#ifdef __CYGWIN__ -# include -# include -# include -# define DEV_CYGDRIVE_MAJOR 98 -#endif +#include +#include +#include +#include #ifdef __GNU__ #include @@ -36,9 +35,11 @@ #include #endif -#include -#include -#include +#include +#include +#include +#include +#include static void strip_extra_slashes (char *dir) @@ -79,103 +80,6 @@ xgetcwd (void) return path; } -#ifdef __CYGWIN__ -/* Convert POSIX path to Win32 path, - remove drive letter, replace backslashes. */ -static char * -get_win32_path (const char *path) -{ - char winpath[PATH_MAX]; - cygwin_conv_to_full_win32_path (path, winpath); - - int len = strlen (winpath); - if (len > 2 && winpath[1] == ':') - { - len -= 2; - memmove (winpath, winpath + 2, len + 1); - } - - int i; - for (i = 0; i < len; i++) - if (winpath[i] == '\\') - winpath[i] = '/'; - return xstrdup (winpath); -} -#endif - -char * -grub_get_prefix (const char *dir) -{ - char *saved_cwd; - char *abs_dir, *prev_dir; - char *prefix; - struct stat st, prev_st; - - /* Save the current directory. */ - saved_cwd = xgetcwd (); - - if (chdir (dir) < 0) - grub_util_error ("cannot change directory to `%s'", dir); - - abs_dir = xgetcwd (); - strip_extra_slashes (abs_dir); - prev_dir = xstrdup (abs_dir); - - if (stat (".", &prev_st) < 0) - grub_util_error ("cannot stat `%s'", dir); - - if (! S_ISDIR (prev_st.st_mode)) - grub_util_error ("`%s' is not a directory", dir); - - while (1) - { - if (chdir ("..") < 0) - grub_util_error ("cannot change directory to the parent"); - - if (stat (".", &st) < 0) - grub_util_error ("cannot stat current directory"); - - if (! S_ISDIR (st.st_mode)) - grub_util_error ("current directory is not a directory???"); - - if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino) - break; - - free (prev_dir); - prev_dir = xgetcwd (); - prev_st = st; - } - - strip_extra_slashes (prev_dir); - prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2); - prefix[0] = '/'; - strcpy (prefix + 1, abs_dir + strlen (prev_dir)); - strip_extra_slashes (prefix); - - if (chdir (saved_cwd) < 0) - grub_util_error ("cannot change directory to `%s'", dir); - -#ifdef __CYGWIN__ - if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) - { - /* Reached some mount point not below /cygdrive. - GRUB does not know Cygwin's emulated mounts, - convert to Win32 path. */ - grub_util_info ("Cygwin prefix = %s", prefix); - char * wprefix = get_win32_path (prefix); - free (prefix); - prefix = wprefix; - } -#endif - - free (saved_cwd); - free (abs_dir); - free (prev_dir); - - grub_util_info ("prefix = %s", prefix); - return prefix; -} - #ifdef __MINGW32__ static char * @@ -637,4 +541,3 @@ grub_util_check_char_device (const char *blk_dev) else return 0; } - diff --git a/util/hostdisk.c b/kern/emu/hostdisk.c similarity index 83% rename from util/hostdisk.c rename to kern/emu/hostdisk.c index 8be487461..0ab25ec7d 100644 --- a/util/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -22,8 +22,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -98,6 +98,10 @@ struct hd_geometry # include #endif +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + #if defined(__NetBSD__) # include # include /* struct disklabel */ @@ -312,6 +316,140 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) return GRUB_ERR_NONE; } +#ifdef HAVE_DEVICE_MAPPER +static int +device_is_mapped (const char *dev) +{ + struct stat st; + + if (stat (dev, &st) < 0) + return 0; + + return dm_is_dm_major (major (st.st_rdev)); +} +#endif /* HAVE_DEVICE_MAPPER */ + +#if defined(__linux__) || defined(__CYGWIN__) || defined(__NetBSD__) +static grub_disk_addr_t +find_partition_start (const char *dev) +{ + int fd; +# if !defined(__NetBSD__) + struct hd_geometry hdg; +# else /* defined(__NetBSD__) */ + struct disklabel label; + int index; +# endif /* !defined(__NetBSD__) */ + +# ifdef HAVE_DEVICE_MAPPER + if (device_is_mapped (dev)) { + struct dm_task *task = NULL; + grub_uint64_t start, length; + char *target_type, *params, *space; + grub_disk_addr_t partition_start; + + /* If any device-mapper operation fails, we fall back silently to + HDIO_GETGEO. */ + task = dm_task_create (DM_DEVICE_TABLE); + if (! task) + { + grub_dprintf ("hostdisk", "dm_task_create failed\n"); + goto devmapper_fail; + } + + if (! dm_task_set_name (task, dev)) + { + grub_dprintf ("hostdisk", "dm_task_set_name failed\n"); + goto devmapper_fail; + } + + if (! dm_task_run (task)) + { + grub_dprintf ("hostdisk", "dm_task_run failed\n"); + goto devmapper_fail; + } + + dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms); + if (! target_type) + { + grub_dprintf ("hostdisk", "no dm target\n"); + goto devmapper_fail; + } + if (strcmp (target_type, "linear") != 0) + { + grub_dprintf ("hostdisk", "ignoring dm target %s (not linear)\n", + target_type); + goto devmapper_fail; + } + if (! params) + { + grub_dprintf ("hostdisk", "no dm params\n"); + goto devmapper_fail; + } + + /* The params string for a linear target looks like this: + DEVICE-NAME START-SECTOR + Parse this out. */ + space = strchr (params, ' '); + if (! space) + goto devmapper_fail; + errno = 0; + partition_start = strtoull (space + 1, NULL, 10); + if (errno == 0) + { + grub_dprintf ("hostdisk", "dm %s starts at %llu\n", + dev, (unsigned long long) partition_start); + dm_task_destroy (task); + return partition_start; + } + +devmapper_fail: + if (task) + dm_task_destroy (task); + } +# endif /* HAVE_DEVICE_MAPPER */ + + fd = open (dev, O_RDONLY); + if (fd == -1) + { + grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + return 0; + } + +# if !defined(__NetBSD__) + if (ioctl (fd, HDIO_GETGEO, &hdg)) +# else /* defined(__NetBSD__) */ + configure_device_driver (fd); + if (ioctl (fd, DIOCGDINFO, &label) == -1) +# endif /* !defined(__NetBSD__) */ + { + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot get disk geometry of `%s'", dev); + close (fd); + return 0; + } + + close (fd); + +# if !defined(__NetBSD__) + return hdg.start; +# else /* defined(__NetBSD__) */ + /* Since dev and convert_system_partition_to_system_disk (dev) are + * different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z] + * and in particular it cannot be a floppy device. */ + index = dev[strlen(dev) - 1] - 'a'; + + if (index >= label.d_npartitions) + { + grub_error (GRUB_ERR_BAD_DEVICE, + "no disk label entry for `%s'", dev); + return 0; + } + return (grub_disk_addr_t) label.d_partitions[index].p_offset; +# endif /* !defined(__NetBSD__) */ +} +#endif /* __linux__ || __CYGWIN__ */ + #ifdef __linux__ /* Cache of partition start sectors for each disk. */ struct linux_partition_cache @@ -365,28 +503,26 @@ linux_find_partition (char *dev, unsigned long sector) for (i = 1; i < 10000; i++) { int fd; - struct hd_geometry hdg; + grub_disk_addr_t start; sprintf (p, format, i); + fd = open (real_dev, O_RDONLY); if (fd == -1) return 0; - - if (ioctl (fd, HDIO_GETGEO, &hdg)) - { - close (fd); - return 0; - } - close (fd); - if (hdg.start == sector) + start = find_partition_start (real_dev); + /* We don't care about errors here. */ + grub_errno = GRUB_ERR_NONE; + + if (start == sector) { struct linux_partition_cache *new_cache_item; new_cache_item = xmalloc (sizeof *new_cache_item); new_cache_item->dev = xstrdup (dev); - new_cache_item->start = hdg.start; + new_cache_item->start = start; new_cache_item->partno = i; grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list), GRUB_AS_LIST (new_cache_item)); @@ -877,7 +1013,7 @@ make_device_name (int drive, int dos_part, int bsd_part) } static char * -convert_system_partition_to_system_disk (const char *os_dev) +convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) { #if defined(__linux__) char *path = xmalloc (PATH_MAX); @@ -995,6 +1131,96 @@ convert_system_partition_to_system_disk (const char *os_dev) p[4] = '\0'; return path; } + +#ifdef HAVE_DEVICE_MAPPER + /* If this is a DM-RAID device. */ + if ((strncmp ("mapper/", p, 7) == 0)) + { + static struct dm_tree *tree = NULL; + uint32_t maj, min; + struct dm_tree_node *node, *child; + void *handle; + const char *node_uuid, *mapper_name, *child_uuid, *child_name; + + if (! tree) + tree = dm_tree_create (); + + if (! tree) + { + grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + return NULL; + } + + maj = major (st->st_rdev); + min = minor (st->st_rdev); + if (! dm_tree_add_dev (tree, maj, min)) + { + grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); + return NULL; + } + + node = dm_tree_find_node (tree, maj, min); + if (! node) + { + grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); + return NULL; + } + node_uuid = dm_tree_node_get_uuid (node); + if (! node_uuid) + { + grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); + return NULL; + } + else if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); + return NULL; + } + + handle = NULL; + mapper_name = NULL; + /* Counter-intuitively, device-mapper refers to the disk-like + device containing a DM-RAID partition device as a "child" of + the partition device. */ + child = dm_tree_next_child (&handle, node, 0); + if (! child) + { + grub_dprintf ("hostdisk", "%s has no DM children\n", path); + goto devmapper_out; + } + child_uuid = dm_tree_node_get_uuid (child); + if (! child_uuid) + { + grub_dprintf ("hostdisk", "%s child has no DM uuid\n", path); + goto devmapper_out; + } + else if (strncmp (child_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); + goto devmapper_out; + } + child_name = dm_tree_node_get_name (child); + if (! child_name) + { + grub_dprintf ("hostdisk", "%s child has no DM name\n", path); + goto devmapper_out; + } + mapper_name = child_name; + +devmapper_out: + if (! mapper_name) + { + /* This is a DM-RAID disk, not a partition. */ + mapper_name = dm_tree_node_get_name (node); + if (! mapper_name) + { + grub_dprintf ("hostdisk", "%s has no DM name\n", path); + return NULL; + } + } + return xasprintf ("/dev/mapper/%s", mapper_name); + } +#endif /* HAVE_DEVICE_MAPPER */ } return path; @@ -1091,12 +1317,12 @@ device_is_wholedisk (const char *os_dev) #endif /* defined(__NetBSD__) */ static int -find_system_device (const char *os_dev) +find_system_device (const char *os_dev, struct stat *st) { unsigned int i; char *os_disk; - os_disk = convert_system_partition_to_system_disk (os_dev); + os_disk = convert_system_partition_to_system_disk (os_dev, st); if (! os_disk) return -1; @@ -1130,7 +1356,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - drive = find_system_device (os_dev); + drive = find_system_device (os_dev, &st); if (drive < 0) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, @@ -1138,8 +1364,8 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return 0; } - if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev)) - == 0) + if (grub_strcmp (os_dev, + convert_system_partition_to_system_disk (os_dev, &st)) == 0) return make_device_name (drive, -1, -1); #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__) @@ -1164,15 +1390,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) { char *name; grub_disk_t disk; - int fd; -# if !defined(__NetBSD__) - struct hd_geometry hdg; - typeof (hdg.start) p_offset; -# else /* defined(__NetBSD__) */ - struct disklabel label; - int index; - u_int32_t p_offset; -# endif /* !defined(__NetBSD__) */ + grub_disk_addr_t start; int dos_part = -1; int bsd_part = -1; auto int find_partition (grub_disk_t dsk, @@ -1187,7 +1405,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) part_start = grub_partition_get_start (partition); - if (p_offset == part_start) + if (start == part_start) { if (partition->parent) { @@ -1218,46 +1436,16 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) index = os_dev[strlen(os_dev) - 1] - 'a'; # endif /* !defined(__NetBSD__) */ - fd = open (os_dev, O_RDONLY); - if (fd == -1) + start = find_partition_start (os_dev); + if (grub_errno != GRUB_ERR_NONE) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", os_dev); free (name); return 0; } -# if !defined(__NetBSD__) - if (ioctl (fd, HDIO_GETGEO, &hdg)) -# else /* defined(__NetBSD__) */ - configure_device_driver (fd); - if (ioctl (fd, DIOCGDINFO, &label) == -1) -# endif /* !defined(__NetBSD__) */ - { - grub_error (GRUB_ERR_BAD_DEVICE, - "cannot get disk geometry of `%s'", os_dev); - close (fd); - free (name); - return 0; - } + grub_util_info ("%s starts from %lu", os_dev, start); - close (fd); - -# if !defined(__NetBSD__) - p_offset = hdg.start; -# else /* defined(__NetBSD__) */ - if (index >= label.d_npartitions) - { - grub_error (GRUB_ERR_BAD_DEVICE, - "no disk label entry for `%s'", os_dev); - free (name); - return 0; - } - p_offset = label.d_partitions[index].p_offset; -# endif /* !defined(__NetBSD__) */ - - grub_util_info ("%s starts from %lu", os_dev, p_offset); - - if (p_offset == 0 && device_is_wholedisk (os_dev)) + if (start == 0 && device_is_wholedisk (os_dev)) return name; grub_util_info ("opening the device %s", name); diff --git a/util/hostfs.c b/kern/emu/hostfs.c similarity index 100% rename from util/hostfs.c rename to kern/emu/hostfs.c diff --git a/util/grub-emu.c b/kern/emu/main.c similarity index 90% rename from util/grub-emu.c rename to kern/emu/main.c index 8660f0aa0..fb5dbf19f 100644 --- a/util/grub-emu.c +++ b/kern/emu/main.c @@ -16,7 +16,10 @@ * along with GRUB. If not, see . */ +#include +#include #include +#include #include #include #include @@ -24,16 +27,17 @@ #include #include +#include #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include -#include +#include #include #include #include @@ -242,7 +246,7 @@ main (int argc, char *argv[]) if (strcmp (root_dev, "host") == 0) dir = xstrdup (dir); else - dir = grub_get_prefix (dir); + dir = grub_make_system_path_relative_to_its_root (dir); prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1); sprintf (prefix, "(%s)%s", root_dev, dir); free (dir); @@ -261,3 +265,32 @@ main (int argc, char *argv[]) return 0; } + +#ifdef __MINGW32__ + +void +grub_millisleep (grub_uint32_t ms) +{ + Sleep (ms); +} + +#else + +void +grub_millisleep (grub_uint32_t ms) +{ + struct timespec ts; + + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; + nanosleep (&ts, NULL); +} + +#endif + +#if GRUB_NO_MODULES +void +grub_register_exported_symbols (void) +{ +} +#endif diff --git a/kern/emu/misc.c b/kern/emu/misc.c new file mode 100644 index 000000000..54c808a47 --- /dev/null +++ b/kern/emu/misc.c @@ -0,0 +1,309 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int verbosity; + +void +grub_util_warn (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: warn:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); +} + +void +grub_util_info (const char *fmt, ...) +{ + if (verbosity > 0) + { + va_list ap; + + fprintf (stderr, _("%s: info:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + fflush (stderr); + } +} + +void +grub_util_error (const char *fmt, ...) +{ + va_list ap; + + fprintf (stderr, _("%s: error:"), program_name); + fprintf (stderr, " "); + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + va_end (ap); + fprintf (stderr, ".\n"); + exit (1); +} + +void * +xmalloc (grub_size_t size) +{ + void *p; + + p = malloc (size); + if (! p) + grub_util_error ("out of memory"); + + return p; +} + +void * +xrealloc (void *ptr, grub_size_t size) +{ + ptr = realloc (ptr, size); + if (! ptr) + grub_util_error ("out of memory"); + + return ptr; +} + +char * +xstrdup (const char *str) +{ + size_t len; + char *newstr; + + len = strlen (str); + newstr = (char *) xmalloc (len + 1); + memcpy (newstr, str, len + 1); + + return newstr; +} + +#ifndef HAVE_VASPRINTF + +int +vasprintf (char **buf, const char *fmt, va_list ap) +{ + /* Should be large enough. */ + *buf = xmalloc (512); + + return vsprintf (*buf, fmt, ap); +} + +#endif + +#ifndef HAVE_ASPRINTF + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + va_start (ap, fmt); + status = vasprintf (*buf, fmt, ap); + va_end (ap); + + return status; +} + +#endif + +char * +xasprintf (const char *fmt, ...) +{ + va_list ap; + char *result; + + va_start (ap, fmt); + if (vasprintf (&result, fmt, ap) < 0) + { + if (errno == ENOMEM) + grub_util_error ("out of memory"); + return NULL; + } + + return result; +} + +void +grub_exit (void) +{ + exit (1); +} + +grub_uint64_t +grub_get_time_ms (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * 1000 + tv.tv_usec / 1000); +} + +grub_uint32_t +grub_get_rtc (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + + return (tv.tv_sec * GRUB_TICKS_PER_SECOND + + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec) + * GRUB_TICKS_PER_SECOND / 1000000)); +} + +char * +canonicalize_file_name (const char *path) +{ + char *ret; +#ifdef PATH_MAX + ret = xmalloc (PATH_MAX); + (void) realpath (path, ret); +#else + ret = realpath (path, NULL); +#endif + return ret; +} + +#ifdef __CYGWIN__ +/* Convert POSIX path to Win32 path, + remove drive letter, replace backslashes. */ +static char * +get_win32_path (const char *path) +{ + char winpath[PATH_MAX]; + if (cygwin_conv_path (CCP_POSIX_TO_WIN_A, path, winpath, sizeof(winpath))) + grub_util_error ("cygwin_conv_path() failed"); + + int len = strlen (winpath); + int offs = (len > 2 && winpath[1] == ':' ? 2 : 0); + + int i; + for (i = offs; i < len; i++) + if (winpath[i] == '\\') + winpath[i] = '/'; + return xstrdup (winpath + offs); +} +#endif + +/* This function never prints trailing slashes (so that its output + can be appended a slash unconditionally). */ +char * +grub_make_system_path_relative_to_its_root (const char *path) +{ + struct stat st; + char *p, *buf, *buf2, *buf3; + uintptr_t offset = 0; + dev_t num; + size_t len; + + /* canonicalize. */ + p = canonicalize_file_name (path); + + if (p == NULL) + grub_util_error ("failed to get canonical path of %s", path); + + len = strlen (p) + 1; + buf = xstrdup (p); + free (p); + + if (stat (buf, &st) < 0) + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + + buf2 = xstrdup (buf); + num = st.st_dev; + + /* This loop sets offset to the number of chars of the root + directory we're inspecting. */ + while (1) + { + p = strrchr (buf, '/'); + if (p == NULL) + /* This should never happen. */ + grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); + if (p != buf) + *p = 0; + else + *++p = 0; + + if (stat (buf, &st) < 0) + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); + + /* buf is another filesystem; we found it. */ + if (st.st_dev != num) + { + /* offset == 0 means path given is the mount point. + This works around special-casing of "/" in Un*x. This function never + prints trailing slashes (so that its output can be appended a slash + unconditionally). Each slash in is considered a preceding slash, and + therefore the root directory is an empty string. */ + if (offset == 0) + { + free (buf); + free (buf2); + return xstrdup (""); + } + else + break; + } + + offset = p - buf; + /* offset == 1 means root directory. */ + if (offset == 1) + { + /* Include leading slash. */ + offset = 0; + break; + } + } + free (buf); + buf3 = xstrdup (buf2 + offset); + free (buf2); + +#ifdef __CYGWIN__ + if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16)) + { + /* Reached some mount point not below /cygdrive. + GRUB does not know Cygwin's emulated mounts, + convert to Win32 path. */ + grub_util_info ("Cygwin path = %s\n", buf3); + char * temp = get_win32_path (buf3); + free (buf3); + buf3 = temp; + } +#endif + + /* Remove trailing slashes, return empty string if root directory. */ + len = strlen (buf3); + while (len > 0 && buf3[len - 1] == '/') + { + buf3[len - 1] = '\0'; + len--; + } + + return buf3; +} diff --git a/util/mm.c b/kern/emu/mm.c similarity index 100% rename from util/mm.c rename to kern/emu/mm.c diff --git a/util/time.c b/kern/emu/time.c similarity index 100% rename from util/time.c rename to kern/emu/time.c diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c index 5f80f28c1..8defc9589 100644 --- a/kern/i386/coreboot/init.c +++ b/kern/i386/coreboot/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -33,8 +32,10 @@ #include #include #include -#include #include +#ifdef GRUB_MACHINE_QEMU +#include +#endif #define GRUB_FLOPPY_REG_DIGITAL_OUTPUT 0x3f2 @@ -117,7 +118,9 @@ grub_machine_init (void) return 0; } +#if defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) grub_machine_mmap_init (); +#endif grub_machine_mmap_iterate (heap_init); grub_tsc_init (); @@ -144,6 +147,6 @@ grub_arch_modules_addr (void) #ifdef GRUB_MACHINE_QEMU return grub_core_entry_addr + grub_kernel_image_size; #else - return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end, GRUB_KERNEL_MACHINE_MOD_ALIGN); #endif } diff --git a/kern/i386/coreboot/mmap.c b/kern/i386/coreboot/mmap.c index b15369ee5..d06627a08 100644 --- a/kern/i386/coreboot/mmap.c +++ b/kern/i386/coreboot/mmap.c @@ -57,13 +57,23 @@ signature_found: (long) table_header->size); for (; table_item->size; table_item = (grub_linuxbios_table_item_t) ((long) table_item + (long) table_item->size)) - if (hook (table_item)) - return 1; + { + if (table_item->tag == GRUB_LINUXBIOS_MEMBER_LINK + && check_signature ((grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1))) + { + table_header = (grub_linuxbios_table_header_t) (grub_addr_t) + *(grub_uint64_t *) (table_item + 1); + goto signature_found; + } + if (hook (table_item)) + return 1; + } return 0; } -void +grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) { mem_region_t mem_region; diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index e94950aae..bcc0d14ab 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -42,7 +42,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -51,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END /* * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself). @@ -66,10 +66,12 @@ multiboot_header: .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO codestart: +#ifdef GRUB_MACHINE_MULTIBOOT cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax jne 0f movl %ebx, EXT_C(startup_multiboot_info) 0: +#endif /* initialize the stack */ movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp diff --git a/kern/i386/ieee1275/startup.S b/kern/i386/ieee1275/startup.S index 35258adb6..c0a08a954 100644 --- a/kern/i386/ieee1275/startup.S +++ b/kern/i386/ieee1275/startup.S @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -43,7 +42,7 @@ _start: * This is a special data area at a fixed offset from the beginning. */ - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ @@ -52,7 +51,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: movl %eax, EXT_C(grub_ieee1275_entry_fn) diff --git a/kern/i386/qemu/startup.S b/kern/i386/qemu/startup.S index 7484650b2..dc40cc4a2 100644 --- a/kern/i386/qemu/startup.S +++ b/kern/i386/qemu/startup.S @@ -27,7 +27,7 @@ _start: jmp codestart - . = _start + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR + . = _start + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR VARIABLE(grub_core_entry_addr) .long 0 VARIABLE(grub_kernel_image_size) diff --git a/kern/ieee1275/cmain.c b/kern/ieee1275/cmain.c index c1185f82c..d3c3a8d88 100644 --- a/kern/ieee1275/cmain.c +++ b/kern/ieee1275/cmain.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int (*grub_ieee1275_entry_fn) (void *); @@ -59,6 +58,7 @@ grub_ieee1275_find_options (void) char tmp[32]; int is_smartfirmware = 0; int is_olpc = 0; + int is_qemu = 0; grub_ieee1275_finddevice ("/", &root); grub_ieee1275_finddevice ("/options", &options); @@ -79,6 +79,11 @@ grub_ieee1275_find_options (void) if (rc >= 0 && !grub_strcmp (tmp, "OLPC")) is_olpc = 1; + rc = grub_ieee1275_get_property (root, "model", + tmp, sizeof (tmp), 0); + if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC")) + is_qemu = 1; + if (is_smartfirmware) { /* Broken in all versions */ @@ -135,6 +140,10 @@ grub_ieee1275_find_options (void) grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY); } + if (is_qemu) + /* OpenFirmware hangs on qemu if one requests any memory below 1.5 MiB. */ + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM); + if (! grub_ieee1275_finddevice ("/rom/boot-rom", &bootrom)) { rc = grub_ieee1275_get_property (bootrom, "model", tmp, sizeof (tmp), 0); diff --git a/kern/ieee1275/init.c b/kern/ieee1275/init.c index 75f261a71..b7e5c337e 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -29,10 +29,9 @@ #include #include #include -#include -#include #include #include +#include /* The minimal heap size we can live with. */ #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) @@ -133,6 +132,17 @@ static void grub_claim_heap (void) if (type != 1) return 0; + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) + { + if (addr + len <= 0x180000) + return 0; + + if (addr < 0x180000) + { + len = addr + len - 0x180000; + addr = 0x180000; + } + } len -= 1; /* Required for some firmware. */ /* Never exceed HEAP_MAX_SIZE */ @@ -284,5 +294,5 @@ grub_get_rtc (void) grub_addr_t grub_arch_modules_addr (void) { - return ALIGN_UP((grub_addr_t) _end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); + return ALIGN_UP((grub_addr_t) _end + GRUB_KERNEL_MACHINE_MOD_GAP, GRUB_KERNEL_MACHINE_MOD_ALIGN); } diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index cf9e1a870..5693f3be0 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -21,7 +21,6 @@ #include #include #include -#include #include enum grub_ieee1275_parse_type diff --git a/kern/main.c b/kern/main.c index 2f2c951ab..1fdf4ab07 100644 --- a/kern/main.c +++ b/kern/main.c @@ -102,7 +102,7 @@ grub_load_config (void) auto int hook (struct grub_module_header *); int hook (struct grub_module_header *header) { - /* Not an ELF module, skip. */ + /* Not an embedded config, skip. */ if (header->type != OBJ_TYPE_CONFIG) return 0; diff --git a/kern/mips/init.c b/kern/mips/init.c index 5adcedcbb..f220108d4 100644 --- a/kern/mips/init.c +++ b/kern/mips/init.c @@ -18,7 +18,6 @@ #include #include -#include void grub_machine_set_prefix (void) diff --git a/kern/mips/startup.S b/kern/mips/startup.S index 5e3fb7ad5..1d18131be 100644 --- a/kern/mips/startup.S +++ b/kern/mips/startup.S @@ -18,8 +18,9 @@ */ #include -#include +#include #include +#include #define BASE_ADDR 8 @@ -32,13 +33,13 @@ _start: start: bal codestart base: - . = _start + GRUB_KERNEL_CPU_COMPRESSED_SIZE + . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE compressed_size: .long 0 - . = _start + GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE + . = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE total_module_size: .long 0 - . = _start + GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE + . = _start + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE kernel_image_size: .long 0 codestart: @@ -105,10 +106,10 @@ argdone: #endif /* Decompress the payload. */ - addiu $a0, $s0, GRUB_KERNEL_CPU_RAW_SIZE - BASE_ADDR + addiu $a0, $s0, GRUB_KERNEL_MACHINE_RAW_SIZE - BASE_ADDR lui $a1, %hi(compressed) addiu $a1, %lo(compressed) - lw $a2, (GRUB_KERNEL_CPU_COMPRESSED_SIZE - BASE_ADDR)($s0) + lw $a2, (GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - BASE_ADDR)($s0) move $s1, $a1 /* $a0 contains source compressed address, $a1 is destination, @@ -134,9 +135,9 @@ reloccont: addiu $t1, %lo(cont) jr $t1 - . = _start + GRUB_KERNEL_CPU_RAW_SIZE + . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE compressed: - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) @@ -146,7 +147,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END #ifdef GRUB_MACHINE_MIPS_YEELOONG VARIABLE (grub_arch_busclock) .long 0 @@ -171,17 +172,17 @@ cont: /* Move the modules out of BSS. */ lui $t1, %hi(_start) addiu $t1, %lo(_start) - lw $t2, (GRUB_KERNEL_CPU_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) + lw $t2, (GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE - BASE_ADDR)($s0) addu $t2, $t1, $t2 lui $t1, %hi(_end) addiu $t1, %lo(_end) - addiu $t1, (GRUB_MOD_ALIGN-1) - li $t3, (GRUB_MOD_ALIGN-1) + addiu $t1, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) + li $t3, (GRUB_KERNEL_MACHINE_MOD_ALIGN-1) nor $t3, $t3, $0 and $t1, $t1, $t3 - lw $t3, (GRUB_KERNEL_CPU_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) + lw $t3, (GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - BASE_ADDR)($s0) /* Backward copy. */ add $t1, $t1, $t3 diff --git a/kern/mips/yeeloong/init.c b/kern/mips/yeeloong/init.c index 6bba27b51..47aa774a0 100644 --- a/kern/mips/yeeloong/init.c +++ b/kern/mips/yeeloong/init.c @@ -26,7 +26,6 @@ #include #include #include -#include extern void grub_video_sm712_init (void); extern void grub_video_init (void); diff --git a/kern/mm.c b/kern/mm.c index 3237b040c..47324a662 100644 --- a/kern/mm.c +++ b/kern/mm.c @@ -148,15 +148,14 @@ grub_mm_init_region (void *addr, grub_size_t size) grub_printf ("Using memory for heap: start=%p, end=%p\n", addr, addr + (unsigned int) size); #endif - /* If this region is too small, ignore it. */ - if (size < GRUB_MM_ALIGN * 2) - return; - /* Allocate a region from the head. */ - r = (grub_mm_region_t) (((grub_addr_t) addr + GRUB_MM_ALIGN - 1) - & (~(GRUB_MM_ALIGN - 1))); + r = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) addr, GRUB_MM_ALIGN); size -= (char *) r - (char *) addr + sizeof (*r); + /* If this region is too small, ignore it. */ + if (size < GRUB_MM_ALIGN) + return; + h = (grub_mm_header_t) ((char *) r + GRUB_MM_ALIGN); h->next = h; h->magic = GRUB_MM_FREE_MAGIC; @@ -221,9 +220,8 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) +---------------+ v */ q->next = p->next; - p->magic = GRUB_MM_ALLOC_MAGIC; } - else if (extra == 0 || p->size == n + extra) + else if (align == 1 || p->size == n + extra) { /* There might be alignment requirement, when taking it into account memory block fits in. @@ -240,10 +238,25 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) | alloc, size=n | | +---------------+ v */ + p->size -= n; p += p->size; - p->size = n; - p->magic = GRUB_MM_ALLOC_MAGIC; + } + else if (extra == 0) + { + grub_mm_header_t r; + + r = p + extra + n; + r->magic = GRUB_MM_FREE_MAGIC; + r->size = p->size - extra - n; + r->next = p->next; + q->next = r; + + if (q == p) + { + q = r; + r->next = r; + } } else { @@ -276,10 +289,11 @@ grub_real_malloc (grub_mm_header_t *first, grub_size_t n, grub_size_t align) p->size = extra; p->next = r; p += extra; - p->size = n; - p->magic = GRUB_MM_ALLOC_MAGIC; } + p->magic = GRUB_MM_ALLOC_MAGIC; + p->size = n; + /* Mark find as a start marker for next allocation to fasten it. This will have side effect of fragmenting memory as small pieces before this will be un-used. */ diff --git a/kern/parser.c b/kern/parser.c index 80312b9b4..07597a1a8 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -249,12 +249,11 @@ grub_parser_execute (char *source) } p = grub_strchr (source, '\n'); - if (p) - *p = 0; - *line = grub_strdup (source); if (p) - *p = '\n'; + *line = grub_strndup (source, p - source); + else + *line = grub_strdup (source); source = p ? p + 1 : 0; return 0; } diff --git a/kern/powerpc/ieee1275/startup.S b/kern/powerpc/ieee1275/startup.S index 75e1ed852..96d153778 100644 --- a/kern/powerpc/ieee1275/startup.S +++ b/kern/powerpc/ieee1275/startup.S @@ -18,7 +18,7 @@ */ #include -#include +#include .extern __bss_start .extern _end @@ -30,7 +30,7 @@ start: _start: b codestart - . = _start + GRUB_KERNEL_CPU_PREFIX + . = _start + GRUB_KERNEL_MACHINE_PREFIX VARIABLE(grub_prefix) /* to be filled by grub-mkelfimage */ @@ -39,7 +39,7 @@ VARIABLE(grub_prefix) * Leave some breathing room for the prefix. */ - . = _start + GRUB_KERNEL_CPU_DATA_END + . = _start + GRUB_KERNEL_MACHINE_DATA_END codestart: li 2, 0 diff --git a/kern/sparc64/ieee1275/crt0.S b/kern/sparc64/ieee1275/crt0.S index d5a172296..f0f47416d 100644 --- a/kern/sparc64/ieee1275/crt0.S +++ b/kern/sparc64/ieee1275/crt0.S @@ -18,6 +18,7 @@ */ #include #include +#include .text .align 4 diff --git a/loader/multiboot.c b/loader/multiboot.c index ce1e75dda..592289c45 100644 --- a/loader/multiboot.c +++ b/loader/multiboot.c @@ -50,7 +50,7 @@ #include #endif -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) #define DEFAULT_VIDEO_MODE "text" #else #define DEFAULT_VIDEO_MODE "auto" diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 8b67f9383..7e9cebe49 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -32,7 +32,7 @@ #include #include -#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) #include #define HAS_VGA_TEXT 1 #else diff --git a/mmap/mmap.c b/mmap/mmap.c index c22be0a56..a1afc8b06 100644 --- a/mmap/mmap.c +++ b/mmap/mmap.c @@ -24,6 +24,7 @@ #include #include #include +#include #ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE @@ -414,8 +415,8 @@ static grub_command_t cmd; GRUB_MOD_INIT(mmap) { cmd = grub_register_command ("badram", grub_cmd_badram, - "ADDR1,MASK1[,ADDR2,MASK2[,...]]", - "Declare memory regions as badram."); + N_("ADDR1,MASK1[,ADDR2,MASK2[,...]]"), + N_("Declare memory regions as badram.")); } GRUB_MOD_FINI(mmap) diff --git a/normal/context.c b/normal/context.c index 08a841699..27adf287a 100644 --- a/normal/context.c +++ b/normal/context.c @@ -23,6 +23,7 @@ #include #include #include +#include struct menu_pointer { @@ -172,7 +173,7 @@ grub_context_init (void) grub_env_export ("prefix"); export_cmd = grub_register_command ("export", grub_cmd_export, - "export ENVVAR", "Export a variable."); + N_("ENVVAR"), N_("Export a variable.")); } void diff --git a/normal/main.c b/normal/main.c index df92e622b..4ed17e82c 100644 --- a/normal/main.c +++ b/normal/main.c @@ -155,6 +155,17 @@ free_menu_entry_classes (struct grub_menu_entry_class *head) } } +static struct +{ + char *name; + int key; +} hotkey_aliases[] = + { + {"backspace", '\b'}, + {"tab", '\t'}, + {"delete", GRUB_TERM_DC} + }; + /* Add a menu entry to the current menu context (as given by the environment variable data slot `menu'). As the configuration file is read, the script parser calls this when a menu entry is to be created. */ @@ -171,6 +182,7 @@ grub_normal_add_menu_entry (int argc, const char **args, struct grub_menu_entry_class *classes_head; /* Dummy head node for list. */ struct grub_menu_entry_class *classes_tail; char *users = NULL; + int hotkey = 0; /* Allocate dummy head node for class list. */ classes_head = grub_zalloc (sizeof (struct grub_menu_entry_class)); @@ -237,6 +249,32 @@ grub_normal_add_menu_entry (int argc, const char **args, continue; } + else if (grub_strcmp(arg, "hotkey") == 0) + { + unsigned j; + + i++; + if (args[i][1] == 0) + { + hotkey = args[i][0]; + continue; + } + + for (j = 0; j < ARRAY_SIZE (hotkey_aliases); j++) + if (grub_strcmp (args[i], hotkey_aliases[j].name) == 0) + { + hotkey = hotkey_aliases[j].key; + break; + } + + if (j < ARRAY_SIZE (hotkey_aliases)) + continue; + + failed = 1; + grub_error (GRUB_ERR_MENU, + "Invalid hotkey: '%s'.", args[i]); + break; + } else { /* Handle invalid argument. */ @@ -293,6 +331,7 @@ grub_normal_add_menu_entry (int argc, const char **args, } (*last)->title = menutitle; + (*last)->hotkey = hotkey; (*last)->classes = classes_head; if (users) (*last)->restricted = 1; @@ -666,9 +705,9 @@ GRUB_MOD_INIT(normal) /* Register a command "normal" for the rescue mode. */ grub_register_command ("normal", grub_cmd_normal, - 0, "Enter normal mode."); + 0, N_("Enter normal mode.")); grub_register_command ("normal_exit", grub_cmd_normal_exit, - 0, "Exit from normal mode."); + 0, N_("Exit from normal mode.")); /* Reload terminal colors when these variables are written to. */ grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); diff --git a/normal/menu.c b/normal/menu.c index 07951dacc..09c5fd1eb 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -478,6 +478,18 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) goto refresh; default: + { + grub_menu_entry_t entry; + int i; + for (i = 0, entry = menu->entry_list; i < menu->size; + i++, entry = entry->next) + if (entry->hotkey == c) + { + menu_fini (); + *auto_boot = 0; + return i; + } + } break; } } diff --git a/po/POTFILES b/po/POTFILES index 0dfc3c041..d2c579edb 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -77,5 +77,5 @@ normal/misc.c term/serial.c -util/grub-mkrawimage.c +util/grub-mkimage.c util/i386/pc/grub-setup.c diff --git a/script/argv.c b/script/argv.c new file mode 100644 index 000000000..69322779d --- /dev/null +++ b/script/argv.c @@ -0,0 +1,132 @@ +/* argv.c - methods for constructing argument vector */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +static unsigned +round_up_exp (unsigned v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + if (sizeof (v) > 4) + v |= v >> 32; + + v++; + v += (v == 0); + + return v; +} + +void +grub_script_argv_free (struct grub_script_argv *argv) +{ + unsigned i; + + if (argv->args) + { + for (i = 0; i < argv->argc; i++) + grub_free (argv->args[i]); + + grub_free (argv->args); + } + + argv->argc = 0; + argv->args = 0; +} + +/* Prepare for next argc. */ +int +grub_script_argv_next (struct grub_script_argv *argv) +{ + char **p = argv->args; + + if (argv->args && argv->args[argv->argc - 1] == 0) + return 0; + + p = grub_realloc (p, round_up_exp ((argv->argc + 2) * sizeof (char *))); + if (! p) + return 1; + + argv->argc++; + argv->args = p; + + if (argv->argc == 1) + argv->args[0] = 0; + argv->args[argv->argc] = 0; + return 0; +} + +/* Append `s' to the last argument. */ +int +grub_script_argv_append (struct grub_script_argv *argv, const char *s) +{ + int a, b; + char *p = argv->args[argv->argc - 1]; + + if (! s) + return 0; + + a = p ? grub_strlen (p) : 0; + b = grub_strlen (s); + + p = grub_realloc (p, round_up_exp ((a + b + 1) * sizeof (char))); + if (! p) + return 1; + + grub_strcpy (p + a, s); + argv->args[argv->argc - 1] = p; + return 0; +} + +/* Split `s' and append words as multiple arguments. */ +int +grub_script_argv_split_append (struct grub_script_argv *argv, char *s) +{ + char ch; + char *p; + int errors = 0; + + if (! s) + return 0; + + while (! errors && *s) + { + p = s; + while (*s && ! grub_isspace (*s)) + s++; + + ch = *s; + *s = '\0'; + errors += grub_script_argv_append (argv, p); + *s = ch; + + while (*s && grub_isspace (*s)) + s++; + + if (*s) + errors += grub_script_argv_next (argv); + } + return errors; +} diff --git a/script/execute.c b/script/execute.c index 31fce554c..691b3c893 100644 --- a/script/execute.c +++ b/script/execute.c @@ -30,6 +30,200 @@ is sizeof (int) * 3, and one extra for a possible -ve sign. */ #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1) +/* Scope for grub script functions. */ +struct grub_script_scope +{ + struct grub_script_argv argv; +}; +static struct grub_script_scope *scope = 0; + +static int +grub_env_special (const char *name) +{ + if (grub_isdigit (name[0]) || + grub_strcmp (name, "#") == 0 || + grub_strcmp (name, "*") == 0 || + grub_strcmp (name, "@") == 0) + return 1; + return 0; +} + +static char ** +grub_script_env_get (const char *name, grub_script_arg_type_t type) +{ + struct grub_script_argv result = { 0, 0 }; + + if (grub_script_argv_next (&result)) + goto fail; + + if (! grub_env_special (name)) + { + char *v = grub_env_get (name); + if (v && v[0]) + { + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + { + if (grub_script_argv_split_append (&result, v)) + goto fail; + } + else + if (grub_script_argv_append (&result, v)) + goto fail; + } + } + else if (! scope) + { + if (grub_script_argv_append (&result, 0)) + goto fail; + } + else if (grub_strcmp (name, "#") == 0) + { + char buffer[ERRNO_DIGITS_MAX + 1]; + grub_snprintf (buffer, sizeof (buffer), "%u", scope->argv.argc); + if (grub_script_argv_append (&result, buffer)) + goto fail; + } + else if (grub_strcmp (name, "*") == 0) + { + unsigned i; + + for (i = 0; i < scope->argv.argc; i++) + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + { + if (i != 0 && grub_script_argv_next (&result)) + goto fail; + + if (grub_script_argv_split_append (&result, scope->argv.args[i])) + goto fail; + } + else + { + if (i != 0 && grub_script_argv_append (&result, " ")) + goto fail; + + if (grub_script_argv_append (&result, scope->argv.args[i])) + goto fail; + } + } + else if (grub_strcmp (name, "@") == 0) + { + unsigned i; + + for (i = 0; i < scope->argv.argc; i++) + { + if (i != 0 && grub_script_argv_next (&result)) + goto fail; + + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + { + if (grub_script_argv_split_append (&result, scope->argv.args[i])) + goto fail; + } + else + if (grub_script_argv_append (&result, scope->argv.args[i])) + goto fail; + } + } + else + { + unsigned long num = grub_strtoul (name, 0, 10); + if (num == 0) + ; /* XXX no file name, for now. */ + + else if (num <= scope->argv.argc) + { + if (type == GRUB_SCRIPT_ARG_TYPE_VAR) + { + if (grub_script_argv_split_append (&result, + scope->argv.args[num - 1])) + goto fail; + } + else + if (grub_script_argv_append (&result, scope->argv.args[num - 1])) + goto fail; + } + } + + return result.args; + + fail: + + grub_script_argv_free (&result); + return 0; +} + +static grub_err_t +grub_script_env_set (const char *name, const char *val) +{ + if (grub_env_special (name)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad variable name"); + + return grub_env_set (name, val); +} + +/* Expand arguments in ARGLIST into multiple arguments. */ +static int +grub_script_arglist_to_argv (struct grub_script_arglist *arglist, + struct grub_script_argv *argv) +{ + int i; + char **values = 0; + struct grub_script_arg *arg = 0; + struct grub_script_argv result = { 0, 0 }; + + for (; arglist && arglist->arg; arglist = arglist->next) + { + if (grub_script_argv_next (&result)) + goto fail; + + arg = arglist->arg; + while (arg) + { + switch (arg->type) + { + case GRUB_SCRIPT_ARG_TYPE_VAR: + case GRUB_SCRIPT_ARG_TYPE_DQVAR: + values = grub_script_env_get (arg->str, arg->type); + for (i = 0; values && values[i]; i++) + { + if (i != 0 && grub_script_argv_next (&result)) + goto fail; + + if (grub_script_argv_append (&result, values[i])) + goto fail; + } + grub_free (values); + break; + + case GRUB_SCRIPT_ARG_TYPE_BLOCK: + case GRUB_SCRIPT_ARG_TYPE_TEXT: + if (grub_strlen (arg->str) && + grub_script_argv_append (&result, arg->str)) + goto fail; + break; + + case GRUB_SCRIPT_ARG_TYPE_DQSTR: + case GRUB_SCRIPT_ARG_TYPE_SQSTR: + if (grub_script_argv_append (&result, arg->str)) + goto fail; + break; + } + arg = arg->next; + } + } + + if (! result.args[result.argc - 1]) + result.argc--; + + *argv = result; + return 0; + + fail: + + grub_script_argv_free (&result); + return 1; +} + static grub_err_t grub_script_execute_cmd (struct grub_script_cmd *cmd) { @@ -46,150 +240,24 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd) return ret; } -#define ARG_ALLOCATION_UNIT (32 * sizeof (char)) -#define ARGV_ALLOCATION_UNIT (8 * sizeof (void*)) - -/* Expand arguments in ARGLIST into multiple arguments. */ -char ** -grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count) +/* Execute a function call. */ +grub_err_t +grub_script_function_call (grub_script_function_t func, int argc, char **args) { - int i; - int oom; - int argc; - int empty; - char *ptr; - char **argv; - char *value; - struct grub_script_arg *arg; + grub_err_t ret = 0; + struct grub_script_scope *old_scope; + struct grub_script_scope new_scope; - auto void push (char *str); - void push (char *str) - { - char **p; + new_scope.argv.argc = argc; + new_scope.argv.args = args; - if (oom) - return; + old_scope = scope; + scope = &new_scope; - p = grub_realloc (argv, ALIGN_UP (sizeof(char*) * (argc + 1), ARGV_ALLOCATION_UNIT)); - if (!p) - oom = 1; - else - { - p[argc++] = str; - argv = p; - } - } + ret = grub_script_execute (func->func); - auto char* append (const char *str, grub_size_t nchar); - char* append (const char *str, grub_size_t nchar) - { - int len; - int old; - char *p; - - if (oom || !str) - return 0; - - len = nchar ?: grub_strlen (str); - old = argv[argc - 1] ? grub_strlen (argv[argc - 1]) : 0; - p = grub_realloc (argv[argc - 1], ALIGN_UP(old + len + 1, ARG_ALLOCATION_UNIT)); - - if (p) - { - grub_strncpy (p + old, str, len); - p[old + len] = '\0'; - } - else - { - oom = 1; - grub_free (argv[argc - 1]); - } - argv[argc - 1] = p; - return argv[argc - 1]; - } - - /* Move *STR to the begining of next word, but return current word. */ - auto char* move_to_next (char **str); - char* move_to_next (char **str) - { - char *end; - char *start; - - if (oom || !str || !*str) - return 0; - - start = *str; - while (*start && grub_isspace (*start)) start++; - if (*start == '\0') - return 0; - - end = start + 1; - while (*end && !grub_isspace (*end)) end++; - - *str = end; - return start; - } - - oom = 0; - argv = 0; - argc = 0; - push (0); - for (; arglist; arglist = arglist->next) - { - empty = 1; - arg = arglist->arg; - while (arg) - { - switch (arg->type) - { - case GRUB_SCRIPT_ARG_TYPE_VAR: - value = grub_env_get (arg->str); - while (value && *value && (ptr = move_to_next(&value))) - { - empty = 0; - append (ptr, value - ptr); - if (*value) push(0); - } - break; - - case GRUB_SCRIPT_ARG_TYPE_BLOCK: - case GRUB_SCRIPT_ARG_TYPE_TEXT: - if (grub_strlen (arg->str) > 0) - { - empty = 0; - append (arg->str, 0); - } - break; - - case GRUB_SCRIPT_ARG_TYPE_DQSTR: - case GRUB_SCRIPT_ARG_TYPE_SQSTR: - empty = 0; - append (arg->str, 0); - break; - - case GRUB_SCRIPT_ARG_TYPE_DQVAR: - empty = 0; - append (grub_env_get (arg->str), 0); - break; - } - arg = arg->next; - } - if (!empty) - push (0); - } - - if (oom) - { - for (i = 0; i < argc; i++) - grub_free (argv[i]); - grub_free (argv); - argv = 0; - } - - if (argv) - *count = argc - 1; - - return argv; + scope = old_scope; + return ret; } /* Execute a single command line. */ @@ -197,21 +265,18 @@ grub_err_t grub_script_execute_cmdline (struct grub_script_cmd *cmd) { struct grub_script_cmdline *cmdline = (struct grub_script_cmdline *) cmd; - char **args = 0; - int i = 0; grub_command_t grubcmd; grub_err_t ret = 0; - int argcount = 0; grub_script_function_t func = 0; char errnobuf[18]; char *cmdname; + struct grub_script_argv argv = { 0, 0 }; /* Lookup the command. */ - args = grub_script_execute_arglist_to_argv (cmdline->arglist, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmdline->arglist, &argv)) return grub_errno; - cmdname = args[0]; + cmdname = argv.args[0]; grubcmd = grub_command_find (cmdname); if (! grubcmd) { @@ -233,13 +298,14 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Create two strings and set the variable. */ *eq = '\0'; eq++; - grub_env_set (assign, eq); + grub_script_env_set (assign, eq); } grub_free (assign); grub_snprintf (errnobuf, sizeof (errnobuf), "%d", grub_errno); grub_env_set ("?", errnobuf); + grub_script_argv_free (&argv); grub_print_error (); return 0; @@ -248,14 +314,12 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute the GRUB command or function. */ if (grubcmd) - ret = (grubcmd->func) (grubcmd, argcount - 1, args + 1); + ret = (grubcmd->func) (grubcmd, argv.argc - 1, argv.args + 1); else - ret = grub_script_function_call (func, argcount - 1, args + 1); + ret = grub_script_function_call (func, argv.argc - 1, argv.args + 1); /* Free arguments. */ - for (i = 0; i < argcount; i++) - grub_free (args[i]); - grub_free (args); + grub_script_argv_free (&argv); if (grub_errno == GRUB_ERR_TEST_FAILURE) grub_errno = GRUB_ERR_NONE; @@ -270,13 +334,13 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd) /* Execute a block of one or more commands. */ grub_err_t -grub_script_execute_cmdblock (struct grub_script_cmd *cmd) +grub_script_execute_cmdlist (struct grub_script_cmd *list) { int ret = 0; - struct grub_script_cmdblock *cmdblock = (struct grub_script_cmdblock *) cmd; + struct grub_script_cmd *cmd; /* Loop over every command and execute it. */ - for (cmd = cmdblock->cmdlist; cmd; cmd = cmd->next) + for (cmd = list->next; cmd; cmd = cmd->next) ret = grub_script_execute_cmd (cmd); return ret; @@ -308,25 +372,22 @@ grub_script_execute_cmdif (struct grub_script_cmd *cmd) grub_err_t grub_script_execute_cmdfor (struct grub_script_cmd *cmd) { - int i; - int result; - char **args; - int argcount; + unsigned i; + grub_err_t result; + struct grub_script_argv argv = { 0, 0 }; struct grub_script_cmdfor *cmdfor = (struct grub_script_cmdfor *) cmd; - args = grub_script_execute_arglist_to_argv (cmdfor->words, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmdfor->words, &argv)) return grub_errno; result = 0; - for (i = 0; i < argcount; i++) + for (i = 0; i < argv.argc; i++) { - grub_env_set (cmdfor->name->str, args[i]); + grub_script_env_set (cmdfor->name->str, argv.args[i]); result = grub_script_execute_cmd (cmdfor->list); - grub_free (args[i]); } - grub_free (args); + grub_script_argv_free (&argv); return result; } @@ -355,26 +416,20 @@ grub_err_t grub_script_execute_menuentry (struct grub_script_cmd *cmd) { struct grub_script_cmd_menuentry *cmd_menuentry; - char **args = 0; - int argcount = 0; - int i = 0; + struct grub_script_argv argv = { 0, 0 }; cmd_menuentry = (struct grub_script_cmd_menuentry *) cmd; if (cmd_menuentry->arglist) { - args = grub_script_execute_arglist_to_argv (cmd_menuentry->arglist, &argcount); - if (!args) + if (grub_script_arglist_to_argv (cmd_menuentry->arglist, &argv)) return grub_errno; } - grub_normal_add_menu_entry (argcount, (const char **) args, + grub_normal_add_menu_entry (argv.argc, (const char **) argv.args, cmd_menuentry->sourcecode); - /* Free arguments. */ - for (i = 0; i < argcount; i++) - grub_free (args[i]); - grub_free (args); + grub_script_argv_free (&argv); return grub_errno; } diff --git a/script/function.c b/script/function.c index ded470c4e..82c753bcd 100644 --- a/script/function.c +++ b/script/function.c @@ -115,12 +115,3 @@ grub_script_function_iterate (int (*iterate) (grub_script_function_t)) return 0; } - -int -grub_script_function_call (grub_script_function_t func, - int argc __attribute__((unused)), - char **args __attribute__((unused))) -{ - /* XXX: Arguments are not supported yet. */ - return grub_script_execute (func->func); -} diff --git a/script/parser.y b/script/parser.y index 6669b783c..653e2bc84 100644 --- a/script/parser.y +++ b/script/parser.y @@ -100,9 +100,7 @@ script: newlines0 } | script statement delimiter newlines0 { - struct grub_script_cmdblock *cmdblock; - cmdblock = (struct grub_script_cmdblock *) $1; - $$ = grub_script_add_cmd (state, cmdblock, $2); + $$ = grub_script_append_cmd (state, $1, $2); } | error { @@ -239,13 +237,11 @@ command: grubcmd { $$ = $1; } /* A list of commands. */ commands1: newlines0 command { - $$ = grub_script_add_cmd (state, 0, $2); + $$ = grub_script_append_cmd (state, 0, $2); } | commands1 delimiters1 command { - struct grub_script_cmdblock *cmdblock; - cmdblock = (struct grub_script_cmdblock *) $1; - $$ = grub_script_add_cmd (state, cmdblock, $3); + $$ = grub_script_append_cmd (state, $1, $3); } ; diff --git a/script/script.c b/script/script.c index 4c87d9491..9cee40dcb 100644 --- a/script/script.c +++ b/script/script.c @@ -291,46 +291,40 @@ grub_script_create_cmdmenu (struct grub_parser_param *state, return (struct grub_script_cmd *) cmd; } -/* Create a block of commands. CMD contains the command that should - be added at the end of CMDBLOCK's list. If CMDBLOCK is zero, a new - cmdblock will be created. */ +/* Create a chain of commands. LAST contains the command that should + be added at the end of LIST's list. If LIST is zero, a new list + will be created. */ struct grub_script_cmd * -grub_script_add_cmd (struct grub_parser_param *state, - struct grub_script_cmdblock *cmdblock, - struct grub_script_cmd *cmd) +grub_script_append_cmd (struct grub_parser_param *state, + struct grub_script_cmd *list, + struct grub_script_cmd *last) { struct grub_script_cmd *ptr; - grub_dprintf ("scripting", "cmdblock\n"); + grub_dprintf ("scripting", "append command\n"); - if (!cmd) - return (struct grub_script_cmd *) cmdblock; + if (! last) + return list; - if (!cmdblock) + if (! list) { - cmdblock = grub_script_malloc (state, sizeof (*cmdblock)); - if (!cmdblock) + list = grub_script_malloc (state, sizeof (*list)); + if (! list) return 0; - cmdblock->cmd.exec = grub_script_execute_cmdblock; - cmdblock->cmd.next = 0; - cmdblock->cmdlist = cmd; - cmd->next = 0; + list->exec = grub_script_execute_cmdlist; + list->next = last; } else { - if (!cmdblock->cmdlist) - cmdblock->cmdlist = cmd; - else - { - ptr = cmdblock->cmdlist; - while (ptr->next) - ptr = ptr->next; - ptr->next = cmd; - } + ptr = list; + while (ptr->next) + ptr = ptr->next; + + ptr->next = last; } - return (struct grub_script_cmd *) cmdblock; + return list; } diff --git a/script/yylex.l b/script/yylex.l index 585f818cb..bfc53a6ff 100644 --- a/script/yylex.l +++ b/script/yylex.l @@ -112,14 +112,15 @@ typedef size_t yy_size_t; %option extra-type="struct grub_parser_param*" BLANK [ \t] -COMMENT ^[ \t]*#.*$ +COMMENT #.*$ CHAR [^{}|&$;<> \t\n\'\"\\] DIGITS [[:digit:]]+ NAME [[:alpha:]_][[:alnum:][:digit:]_]* ESC \\. -VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|$\?|$\{\?\} +SPECIAL \?|\#|\*|\@ +VARIABLE ${NAME}|$\{{NAME}\}|${DIGITS}|$\{{DIGITS}\}|${SPECIAL}|$\{{SPECIAL}\} DQSTR \"([^\\\"]|{ESC})*\" SQSTR \'[^\']*\' WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ @@ -221,7 +222,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ } { - \? | + {SPECIAL} | {DIGITS} | {NAME} { COPY (yytext, yyleng); @@ -231,7 +232,7 @@ WORD ({CHAR}|{DQSTR}|{SQSTR}|{ESC}|{VARIABLE})+ else ARG (GRUB_SCRIPT_ARG_TYPE_DQVAR); } - \{\?\} | + \{{SPECIAL}\} | \{{DIGITS}\} | \{{NAME}\} { yytext[yyleng - 1] = '\0'; diff --git a/term/gfxterm.c b/term/gfxterm.c index a1409980b..ecfe4ff3b 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -29,6 +29,7 @@ #include #include #include +#include #define DEFAULT_VIDEO_MODE "auto" #define DEFAULT_BORDER_WIDTH 10 @@ -1187,8 +1188,8 @@ GRUB_MOD_INIT(gfxterm) grub_register_extcmd ("background_image", grub_gfxterm_background_image_cmd, GRUB_COMMAND_FLAG_BOTH, - "[-m (stretch|normal)] FILE", - "Load background image for active terminal.", + N_("[-m (stretch|normal)] FILE"), + N_("Load background image for active terminal."), background_image_cmd_options); } diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c deleted file mode 100644 index 402b30fe6..000000000 --- a/term/i386/pc/vga.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -// TODO: Deprecated and broken. Needs to be converted to Video Driver! - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEBUG_VGA 0 - -#define VGA_WIDTH 640 -#define VGA_HEIGHT 350 -#define CHAR_WIDTH 8 -#define CHAR_HEIGHT 16 -#define TEXT_WIDTH (VGA_WIDTH / CHAR_WIDTH) -#define TEXT_HEIGHT (VGA_HEIGHT / CHAR_HEIGHT) -#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) -#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) - -#define DEFAULT_FG_COLOR 0xa -#define DEFAULT_BG_COLOR 0x0 - -struct colored_char -{ - /* An Unicode codepoint. */ - grub_uint32_t code; - - /* Color indexes. */ - unsigned char fg_color; - unsigned char bg_color; - - /* The width of this character minus one. */ - unsigned char width; - - /* The column index of this character. */ - unsigned char index; -}; - -static unsigned char text_mode; -static unsigned xpos, ypos; -static int cursor_state; -static unsigned char fg_color, bg_color; -static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT]; -static unsigned char saved_map_mask; -static int page = 0; -static grub_font_t font = 0; - -#define SEQUENCER_ADDR_PORT 0x3C4 -#define SEQUENCER_DATA_PORT 0x3C5 -#define MAP_MASK_REGISTER 0x02 - -#define CRTC_ADDR_PORT 0x3D4 -#define CRTC_DATA_PORT 0x3D5 -#define START_ADDR_HIGH_REGISTER 0x0C -#define START_ADDR_LOW_REGISTER 0x0D - -#define GRAPHICS_ADDR_PORT 0x3CE -#define GRAPHICS_DATA_PORT 0x3CF -#define READ_MAP_REGISTER 0x04 - -#define INPUT_STATUS1_REGISTER 0x3DA -#define INPUT_STATUS1_VERTR_BIT 0x08 - -static inline void -wait_vretrace (void) -{ - /* Wait until there is a vertical retrace. */ - while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT)); -} - -/* Get Map Mask Register. */ -static unsigned char -get_map_mask (void) -{ - unsigned char old_addr; - unsigned char old_data; - - old_addr = grub_inb (SEQUENCER_ADDR_PORT); - grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); - - old_data = grub_inb (SEQUENCER_DATA_PORT); - - grub_outb (old_addr, SEQUENCER_ADDR_PORT); - - return old_data; -} - -/* Set Map Mask Register. */ -static void -set_map_mask (unsigned char mask) -{ - unsigned char old_addr; - - old_addr = grub_inb (SEQUENCER_ADDR_PORT); - grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); - - grub_outb (mask, SEQUENCER_DATA_PORT); - - grub_outb (old_addr, SEQUENCER_ADDR_PORT); -} - -/* Set Read Map Register. */ -static void -set_read_map (unsigned char map) -{ - unsigned char old_addr; - - old_addr = grub_inb (GRAPHICS_ADDR_PORT); - - grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT); - grub_outb (map, GRAPHICS_DATA_PORT); - - grub_outb (old_addr, GRAPHICS_ADDR_PORT); -} - -/* Set start address. */ -static void -set_start_address (unsigned int start) -{ - unsigned char old_addr; - - old_addr = grub_inb (CRTC_ADDR_PORT); - - grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT); - grub_outb (start & 0xFF, CRTC_DATA_PORT); - - grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT); - grub_outb (start >> 8, CRTC_DATA_PORT); - - grub_outb (old_addr, CRTC_ADDR_PORT); -} - -static grub_err_t -grub_vga_mod_init (void) -{ - text_mode = grub_vga_set_mode (0x10); - cursor_state = 1; - fg_color = DEFAULT_FG_COLOR; - bg_color = DEFAULT_BG_COLOR; - saved_map_mask = get_map_mask (); - set_map_mask (0x0f); - set_start_address (PAGE_OFFSET (page)); - font = grub_font_get (""); /* Choose any font, for now. */ - if (!font) - return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); - - return GRUB_ERR_NONE; -} - -static grub_err_t -grub_vga_mod_fini (void) -{ - set_map_mask (saved_map_mask); - grub_vga_set_mode (text_mode); - return GRUB_ERR_NONE; -} - -static int -check_vga_mem (void *p) -{ - return (p >= (void *) (VGA_MEM + PAGE_OFFSET (page)) - && p <= (void *) (VGA_MEM + PAGE_OFFSET (page) - + VGA_WIDTH * VGA_HEIGHT / 8)); -} - -static void -write_char (void) -{ - struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH; - struct grub_font_glyph *glyph; - unsigned char *mem_base; - unsigned plane; - - mem_base = (VGA_MEM + xpos + - ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index; - p -= p->index; - - /* Get glyph for character. */ - glyph = grub_font_get_glyph (font, p->code); - - for (plane = 0x01; plane <= 0x08; plane <<= 1) - { - unsigned y; - unsigned offset; - unsigned char *mem; - - set_map_mask (plane); - - for (y = 0, offset = 0, mem = mem_base; - y < CHAR_HEIGHT; - y++, mem += TEXT_WIDTH) - { - /* TODO Re-implement glyph drawing for vga module. */ -#if 0 - unsigned i; - - unsigned char_width = 1; /* TODO Figure out wide characters. */ - for (i = 0; i < char_width && offset < 32; i++) - { - unsigned char fg_mask, bg_mask; - - fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0; - bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0; - offset++; - - if (check_vga_mem (mem + i)) - mem[i] = (fg_mask | bg_mask); - } -#endif /* 0 */ - } - } - - set_map_mask (0x0f); -} - -static void -write_cursor (void) -{ - unsigned char *mem = (VGA_MEM + PAGE_OFFSET (page) + xpos - + (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH); - if (check_vga_mem (mem)) - *mem = 0xff; - - mem += TEXT_WIDTH; - if (check_vga_mem (mem)) - *mem = 0xff; -} - -static void -scroll_up (void) -{ - unsigned i; - unsigned plane; - - /* Do all the work in the other page. */ - grub_memmove (text_buf, text_buf + TEXT_WIDTH, - sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1)); - - for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++) - { - text_buf[i].code = ' '; - text_buf[i].fg_color = 0; - text_buf[i].bg_color = 0; - text_buf[i].width = 0; - text_buf[i].index = 0; - } - - for (plane = 1; plane <= 4; plane++) - { - set_read_map (plane); - set_map_mask (1 << plane); - grub_memmove (VGA_MEM + PAGE_OFFSET (1 - page), VGA_MEM - + PAGE_OFFSET (page) + VGA_WIDTH * CHAR_HEIGHT / 8, - VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8); - } - - set_map_mask (0x0f); - grub_memset (VGA_MEM + PAGE_OFFSET (1 - page) - + VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0, - VGA_WIDTH * CHAR_HEIGHT / 8); - - /* Activate the other page. */ - page = 1 - page; - wait_vretrace (); - set_start_address (PAGE_OFFSET (page)); -} - -static void -grub_vga_putchar (grub_uint32_t c) -{ -#if DEBUG_VGA - static int show = 1; -#endif - - if (c == '\a') - /* FIXME */ - return; - - if (c == '\b' || c == '\n' || c == '\r') - { - /* Erase current cursor, if any. */ - if (cursor_state) - write_char (); - - switch (c) - { - case '\b': - if (xpos > 0) - xpos--; - break; - - case '\n': - if (ypos >= TEXT_HEIGHT - 1) - scroll_up (); - else - ypos++; - break; - - case '\r': - xpos = 0; - break; - } - - if (cursor_state) - write_cursor (); - } - else - { - struct grub_font_glyph *glyph; - struct colored_char *p; - unsigned char_width = 1; - - glyph = grub_font_get_glyph(font, c); - - if (xpos + char_width > TEXT_WIDTH) - grub_putchar ('\n'); - - p = text_buf + xpos + ypos * TEXT_WIDTH; - p->code = c; - p->fg_color = fg_color; - p->bg_color = bg_color; - p->width = char_width - 1; - p->index = 0; - - if (char_width > 1) - { - unsigned i; - - for (i = 1; i < char_width; i++) - { - p[i].code = ' '; - p[i].width = char_width - 1; - p[i].index = i; - } - } - - write_char (); - - xpos += char_width; - if (xpos >= TEXT_WIDTH) - { - xpos = 0; - - if (ypos >= TEXT_HEIGHT - 1) - scroll_up (); - else - ypos++; - } - - if (cursor_state) - write_cursor (); - } - -#if DEBUG_VGA - if (show) - { - grub_uint16_t pos = grub_getxy (); - - show = 0; - grub_gotoxy (0, 0); - grub_printf ("[%u:%u]", (unsigned) (pos >> 8), (unsigned) (pos & 0xff)); - grub_gotoxy (pos >> 8, pos & 0xff); - show = 1; - } -#endif -} - -static grub_ssize_t -grub_vga_getcharwidth (grub_uint32_t c) -{ -#if 0 - struct grub_font_glyph glyph; - - glyph = grub_font_get_glyph (c); - - return glyph.char_width; -#else - (void) c; /* Prevent warning. */ - return 1; /* TODO Fix wide characters? */ -#endif -} - -static grub_uint16_t -grub_vga_getwh (void) -{ - return (TEXT_WIDTH << 8) | TEXT_HEIGHT; -} - -static grub_uint16_t -grub_vga_getxy (void) -{ - return ((xpos << 8) | ypos); -} - -static void -grub_vga_gotoxy (grub_uint8_t x, grub_uint8_t y) -{ - if (x >= TEXT_WIDTH || y >= TEXT_HEIGHT) - { - grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)", - (unsigned) x, (unsigned) y); - return; - } - - if (cursor_state) - write_char (); - - xpos = x; - ypos = y; - - if (cursor_state) - write_cursor (); -} - -static void -grub_vga_cls (void) -{ - unsigned i; - - wait_vretrace (); - for (i = 0; i < TEXT_WIDTH * TEXT_HEIGHT; i++) - { - text_buf[i].code = ' '; - text_buf[i].fg_color = 0; - text_buf[i].bg_color = 0; - text_buf[i].width = 0; - text_buf[i].index = 0; - } - - grub_memset (VGA_MEM + PAGE_OFFSET (page), 0, VGA_WIDTH * VGA_HEIGHT / 8); - - xpos = ypos = 0; -} - -static void -grub_vga_setcolorstate (grub_term_color_state state) -{ - switch (state) - { - case GRUB_TERM_COLOR_STANDARD: - case GRUB_TERM_COLOR_NORMAL: - fg_color = DEFAULT_FG_COLOR; - bg_color = DEFAULT_BG_COLOR; - break; - case GRUB_TERM_COLOR_HIGHLIGHT: - fg_color = DEFAULT_BG_COLOR; - bg_color = DEFAULT_FG_COLOR; - break; - default: - break; - } -} - -static void -grub_vga_setcursor (int on) -{ - if (cursor_state != on) - { - if (cursor_state) - write_char (); - else - write_cursor (); - - cursor_state = on; - } -} - -static struct grub_term_output grub_vga_term = - { - .name = "vga", - .init = grub_vga_mod_init, - .fini = grub_vga_mod_fini, - .putchar = grub_vga_putchar, - .getcharwidth = grub_vga_getcharwidth, - .getwh = grub_vga_getwh, - .getxy = grub_vga_getxy, - .gotoxy = grub_vga_gotoxy, - .cls = grub_vga_cls, - .setcolorstate = grub_vga_setcolorstate, - .setcursor = grub_vga_setcursor, - .flags = 0, - }; - -GRUB_MOD_INIT(vga) -{ - grub_term_register_output ("vga", &grub_vga_term); -} - -GRUB_MOD_FINI(vga) -{ - grub_term_unregister_output (&grub_vga_term); -} diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index c0f895a15..898f9ceab 100644 --- a/term/ieee1275/ofconsole.c +++ b/term/ieee1275/ofconsole.c @@ -194,14 +194,15 @@ grub_ofconsole_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_col *highlight_color = grub_ofconsole_highlight_color; } +#define ANSI_C0 0x9b + static int grub_ofconsole_readkey (int *key) { - char c; + grub_uint8_t c; grub_ssize_t actual = 0; grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - if (actual > 0) switch(c) { @@ -209,25 +210,30 @@ grub_ofconsole_readkey (int *key) /* Backspace: Ctrl-h. */ c = '\b'; break; + case ANSI_C0: case '\e': { grub_uint64_t start; - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - /* On 9600 we have to wait up to 12 milliseconds. */ - start = grub_get_time_ms (); - while (actual <= 0 && grub_get_time_ms () - start < 12) - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); - - if (actual <= 0) + if (c == '\e') { - *key = '\e'; - return 1; + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + /* On 9600 we have to wait up to 12 milliseconds. */ + start = grub_get_time_ms (); + while (actual <= 0 && grub_get_time_ms () - start < 12) + grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); + + if (actual <= 0) + { + *key = '\e'; + return 1; + } + + if (c != '[') + return 0; } - if (c != '[') - return 0; - grub_ieee1275_read (stdin_ihandle, &c, 1, &actual); /* On 9600 we have to wait up to 12 milliseconds. */ @@ -321,7 +327,7 @@ grub_ofconsole_getkey (void) static grub_uint16_t grub_ofconsole_getxy (void) { - return ((grub_curr_x - 1) << 8) | grub_curr_y; + return (grub_curr_x << 8) | grub_curr_y; } static void diff --git a/term/serial.c b/term/serial.c index 05497ce40..2347bb3ee 100644 --- a/term/serial.c +++ b/term/serial.c @@ -616,8 +616,8 @@ GRUB_MOD_INIT(serial) { cmd = grub_register_extcmd ("serial", grub_cmd_serial, GRUB_COMMAND_FLAG_BOTH, - "serial [OPTIONS...]", - "Configure serial port.", options); + N_("[OPTIONS...]"), + N_("Configure serial port."), options); /* Set default settings. */ serial_settings.port = serial_hw_get_port (0); diff --git a/term/terminfo.c b/term/terminfo.c index 9a5979b1c..7402d23db 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -31,6 +31,7 @@ #include #include #include +#include struct terminfo { @@ -178,7 +179,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(terminfo) { cmd = grub_register_command ("terminfo", grub_cmd_terminfo, - "[TERM]", "Set terminfo type."); + N_("[TERM]"), N_("Set terminfo type.")); grub_terminfo_set_current ("vt100"); } diff --git a/tests/grub_script_comments.in b/tests/grub_script_comments.in new file mode 100644 index 000000000..f212cc1e1 --- /dev/null +++ b/tests/grub_script_comments.in @@ -0,0 +1,28 @@ +#! @builddir@/grub-shell-tester +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB 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. +# +# GRUB 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 GRUB. If not, see . + +echo a###b +echo a# #b + +echo # +echo \# + +echo '#' +echo "#" + +echo '\#' +echo "\#" diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in index 048907a76..554dd68ed 100644 --- a/tests/grub_script_echo1.in +++ b/tests/grub_script_echo1.in @@ -16,6 +16,33 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . +# simple arguments +echo one two three +echo "one two three" +echo 'one two three' + +# empty arguments +echo a "" b +echo a '' b + +echo a $foo b +echo a ${foo} b + +echo a "$foo" b +echo a "${foo}" b + +# multi-part arguments +echo one"two"three +echo one${two}three +echo one"two"$three + +echo one'two'three +echo one${two}three +echo one'two'$three + +echo one'two'three"four"five${six}seven$eight + + foo=bar echo $foo ${foo} echo "$foo" "${foo}" diff --git a/tests/grub_script_functions.in b/tests/grub_script_functions.in new file mode 100644 index 000000000..3e69014d6 --- /dev/null +++ b/tests/grub_script_functions.in @@ -0,0 +1,147 @@ +#! @builddir@/grub-shell-tester + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB 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. +# +# GRUB 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 GRUB. If not, see . + +echo parameter count +function fcount { + echo fcount "$#" +} + +fcount +fcount a +fcount a b + +echo parameter count, with nesting +function ffcount { + echo ffcount "$#" + fcount + fcount a + fcount a b +} + +ffcount +ffcount 1 +ffcount 1 2 + +echo parameters +function fparam { + echo fparam 1 $1 + echo fparam 2 $2 + echo fparam 3 $3 +} + +fparam +fparam a +fparam a b + +echo parameters, with nesting +function ffparam { + echo ffparam 1 $1 + echo ffparam 2 $2 + echo ffparam 3 $3 + fparam + fparam a + fparam a b +} + +ffparam +ffparam 1 +ffparam 1 2 + +echo parameter expansion with specials +function fstar { + for f in $* + do + echo fstar $f + done + + for f in aaa$*bbb + do + echo fstar $f + done +} + +fstar +fstar a +fstar a "1 2" +fstar a "1 2" b + +function fdqstar { + for f in "$*" + do + echo fdqstar $f + done + + for f in aaa"$*"bbb + do + echo fdqstar $f + done + + for f in "aaa$*bbb" + do + echo fdqstar $f + done +} + +fdqstar +fdqstar a +fdqstar a "1 2" +fdqstar a "1 2" b + +function fat { + for f in $@ + do + echo fat $f + done + + for f in aaa$@bbb + do + echo fat $f + done +} + +fat +fat a +fat a "1 2" +fat a "1 2" b +fat a "1 2" b "c d" +fat a "1 2" b "c d" e + +function fdqat { + for f in "$@" + do + echo fdqat $f + done + + for f in aaa"$@"bbb + do + echo fdqat $f + done + + for f in "aaa$@bbb" + do + echo fdqat $f + done +} + +# fdqat # this case needs special handling, lets ignore till we really need it. +fdqat a +fdqat a "1 2" +fdqat a "1 2" b +fdqat a "1 2" b "c d" +fdqat a "1 2" b "c d" e + diff --git a/tests/grub_script_vars1.in b/tests/grub_script_vars1.in index 9ff897627..77b3cf298 100644 --- a/tests/grub_script_vars1.in +++ b/tests/grub_script_vars1.in @@ -28,7 +28,7 @@ foo=foo echo "" $foo echo $bar $foo - + bar="" echo $bar $foo diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index a41a6f6f4..17da6c8c0 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -124,7 +124,8 @@ halt EOF isofile=`mktemp` -grub-mkrescue --output=${isofile} --override-directory=${builddir} \ +grub-mkrescue --grub-mkimage=${builddir}/grub-mkimage --output=${isofile} \ + --override-directory=${builddir} \ /boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \ >/dev/null 2>&1 diff --git a/util/deviceiter.c b/util/deviceiter.c index b0a9e1388..03813bc7d 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -31,6 +31,8 @@ #include #include +#include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -62,12 +64,23 @@ struct hd_geometry | ((unsigned int) (__dev >> 32) & ~0xfff); \ }) # endif /* ! MAJOR */ +# ifndef MINOR +# define MINOR(dev) \ + ({ \ + unsigned long long __dev = (dev); \ + (unsigned) (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); \ + }) +# endif /* ! MINOR */ # ifndef CDROM_GET_CAPABILITY # define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */ # endif /* ! CDROM_GET_CAPABILITY */ # ifndef BLKGETSIZE # define BLKGETSIZE _IO(0x12,96) /* return device size */ # endif /* ! BLKGETSIZE */ + +#ifdef HAVE_DEVICE_MAPPER +# include +#endif #endif /* __linux__ */ /* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with @@ -411,6 +424,16 @@ check_device (const char *device) return 1; } +#ifdef __linux__ +# ifdef HAVE_DEVICE_MAPPER +struct dmraid_seen +{ + struct dmraid_seen *next; + const char *name; +}; +# endif /* HAVE_DEVICE_MAPPER */ +#endif /* __linux__ */ + void grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), int floppy_disks) @@ -643,6 +666,123 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), return; } } + +# ifdef HAVE_DEVICE_MAPPER +# define dmraid_check(cond, ...) \ + if (! (cond)) \ + { \ + grub_dprintf ("deviceiter", __VA_ARGS__); \ + goto dmraid_end; \ + } + + /* DM-RAID. */ + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; + + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); + + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; + + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } + + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } + + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); + + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + +dmraid_next_child: + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } + +dmraid_end: + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } +# endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } diff --git a/util/elf/grub-mkimage.c b/util/elf/grub-mkimage.c deleted file mode 100644 index 04a19bc4e..000000000 --- a/util/elf/grub-mkimage.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "progname.h" - -#define GRUB_IEEE1275_NOTE_NAME "PowerPC" -#define GRUB_IEEE1275_NOTE_TYPE 0x1275 - -/* These structures are defined according to the CHRP binding to IEEE1275, - "Client Program Format" section. */ - -struct grub_ieee1275_note_hdr -{ - grub_uint32_t namesz; - grub_uint32_t descsz; - grub_uint32_t type; - char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; -}; - -struct grub_ieee1275_note_desc -{ - grub_uint32_t real_mode; - grub_uint32_t real_base; - grub_uint32_t real_size; - grub_uint32_t virt_base; - grub_uint32_t virt_size; - grub_uint32_t load_base; -}; - -struct grub_ieee1275_note -{ - struct grub_ieee1275_note_hdr header; - struct grub_ieee1275_note_desc descriptor; -}; - -void -load_note (Elf32_Phdr *phdr, FILE *out) -{ - struct grub_ieee1275_note note; - int note_size = sizeof (struct grub_ieee1275_note); - - grub_util_info ("adding CHRP NOTE segment"); - - note.header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); - note.header.descsz = grub_host_to_target32 (note_size); - note.header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); - strcpy (note.header.name, GRUB_IEEE1275_NOTE_NAME); - note.descriptor.real_mode = grub_host_to_target32 (0xffffffff); - note.descriptor.real_base = grub_host_to_target32 (0x00c00000); - note.descriptor.real_size = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_base = grub_host_to_target32 (0xffffffff); - note.descriptor.virt_size = grub_host_to_target32 (0xffffffff); - note.descriptor.load_base = grub_host_to_target32 (0x00004000); - - /* Write the note data to the new segment. */ - grub_util_write_image_at (¬e, note_size, - grub_target_to_host32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_NOTE); - phdr->p_flags = grub_host_to_target32 (PF_R); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = 0; - phdr->p_paddr = 0; - phdr->p_filesz = grub_host_to_target32 (note_size); - phdr->p_memsz = 0; -} - -void -load_modules (grub_addr_t modbase, Elf32_Phdr *phdr, const char *dir, - char *mods[], FILE *out, char *memdisk_path, char *config_path) -{ - char *module_img; - struct grub_util_path_list *path_list; - struct grub_util_path_list *p; - struct grub_module_info *modinfo; - size_t offset; - size_t total_module_size; - size_t memdisk_size = 0; - size_t config_size = 0; - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - offset = sizeof (struct grub_module_info); - total_module_size = sizeof (struct grub_module_info); - - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); - grub_util_info ("the size of memory disk is 0x%x", memdisk_size); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - if (config_path) - { - config_size = ALIGN_UP(grub_util_get_image_size (config_path), 512); - grub_util_info ("the size of memory disk is 0x%x", config_size); - total_module_size += config_size + sizeof (struct grub_module_header); - } - - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - module_img = xmalloc (total_module_size); - modinfo = (struct grub_module_info *) module_img; - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target32 (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target32 (total_module_size); - - /* Load all the modules, with headers, into module_img. */ - for (p = path_list; p; p = p->next) - { - struct grub_module_header *header; - size_t mod_size; - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_ELF; - header->size = grub_host_to_target32 (mod_size + sizeof (*header)); - - grub_util_load_image (p->name, module_img + offset + sizeof (*header)); - - offset += sizeof (*header) + mod_size; - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_MEMDISK; - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, module_img + offset); - offset += memdisk_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (module_img + offset); - header->type = OBJ_TYPE_CONFIG; - header->size = grub_host_to_target32 (config_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (config_path, module_img + offset); - offset += config_size; - } - - - /* Write the module data to the new segment. */ - grub_util_write_image_at (module_img, total_module_size, - grub_host_to_target32 (phdr->p_offset), out); - - /* Fill in the rest of the segment header. */ - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - phdr->p_align = grub_host_to_target32 (GRUB_TARGET_SIZEOF_LONG); - phdr->p_vaddr = grub_host_to_target32 (modbase); - phdr->p_paddr = grub_host_to_target32 (modbase); - phdr->p_filesz = grub_host_to_target32 (total_module_size); - phdr->p_memsz = grub_host_to_target32 (total_module_size); -} - -void -add_segments (char *dir, char *prefix, FILE *out, int chrp, char *mods[], char *memdisk_path, char *config_path) -{ - Elf32_Ehdr ehdr; - Elf32_Phdr *phdrs = NULL; - Elf32_Phdr *phdr; - FILE *in; - char *kernel_path; - grub_addr_t grub_end = 0; - off_t offset, first_segment; - int i, phdr_size; - - /* Read ELF header. */ - kernel_path = grub_util_get_path (dir, "kernel.img"); - in = fopen (kernel_path, "rb"); - if (! in) - grub_util_error ("cannot open %s", kernel_path); - - grub_util_read_at (&ehdr, sizeof (ehdr), 0, in); - - offset = ALIGN_UP (sizeof (ehdr), GRUB_TARGET_SIZEOF_LONG); - ehdr.e_phoff = grub_host_to_target32 (offset); - - phdr_size = (grub_target_to_host16 (ehdr.e_phentsize) * - grub_target_to_host16 (ehdr.e_phnum)); - - if (mods[0] != NULL) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - if (chrp) - phdr_size += grub_target_to_host16 (ehdr.e_phentsize); - - phdrs = xmalloc (phdr_size); - offset += ALIGN_UP (phdr_size, GRUB_TARGET_SIZEOF_LONG); - - first_segment = offset; - - /* Copy all existing segments. */ - for (i = 0; i < grub_target_to_host16 (ehdr.e_phnum); i++) - { - char *segment_img; - grub_size_t segment_end; - - phdr = phdrs + i; - - /* Read segment header. */ - grub_util_read_at (phdr, sizeof (Elf32_Phdr), - (grub_target_to_host32 (ehdr.e_phoff) - + (i * grub_target_to_host16 (ehdr.e_phentsize))), - in); - grub_util_info ("copying segment %d, type %d", i, - grub_target_to_host32 (phdr->p_type)); - - /* Locate _end. */ - segment_end = grub_target_to_host32 (phdr->p_paddr) - + grub_target_to_host32 (phdr->p_memsz); - grub_util_info ("segment %u end 0x%lx", i, segment_end); - if (segment_end > grub_end) - grub_end = segment_end; - - /* Read segment data and write it to new file. */ - segment_img = xmalloc (grub_target_to_host32 (phdr->p_filesz)); - - grub_util_read_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - grub_target_to_host32 (phdr->p_offset), in); - - phdr->p_offset = grub_host_to_target32 (offset); - grub_util_write_image_at (segment_img, grub_target_to_host32 (phdr->p_filesz), - offset, out); - offset += ALIGN_UP (grub_target_to_host32 (phdr->p_filesz), - GRUB_TARGET_SIZEOF_LONG); - - free (segment_img); - } - - if (mods[0] != NULL) - { - grub_addr_t modbase; - - /* Place modules just after grub segment. */ - modbase = ALIGN_UP(grub_end + GRUB_MOD_GAP, GRUB_MOD_ALIGN); - - /* Construct new segment header for modules. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_modules (modbase, phdr, dir, mods, out, memdisk_path, config_path); - } - - if (chrp) - { - /* Construct new segment header for the CHRP note. */ - phdr = phdrs + grub_target_to_host16 (ehdr.e_phnum); - ehdr.e_phnum = grub_host_to_target16 (grub_target_to_host16 (ehdr.e_phnum) + 1); - - /* Fill in p_offset so the callees know where to write. */ - phdr->p_offset = grub_host_to_target32 (ALIGN_UP (grub_util_get_fp_size (out), - GRUB_TARGET_SIZEOF_LONG)); - - load_note (phdr, out); - } - - /* Don't bother preserving the section headers. */ - ehdr.e_shoff = 0; - ehdr.e_shnum = 0; - ehdr.e_shstrndx = 0; - - /* Write entire segment table to the file. */ - grub_util_write_image_at (phdrs, phdr_size, grub_target_to_host32 (ehdr.e_phoff), out); - - /* Write ELF header. */ - grub_util_write_image_at (&ehdr, sizeof (ehdr), 0, out); - - if (prefix) - { - if (GRUB_KERNEL_CPU_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_CPU_DATA_END) - grub_util_error ("prefix too long"); - grub_util_write_image_at (prefix, strlen (prefix) + 1, first_segment + GRUB_KERNEL_CPU_PREFIX, out); - } - - free (phdrs); - free (kernel_path); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"memdisk", required_argument, 0, 'm'}, - {"config", required_argument, 0, 'c'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"note", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 }, - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory\n\ - -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -c, --config=FILE embed FILE as boot config\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -n, --note add NOTE segment for CHRP Open Firmware\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - char *memdisk = NULL; - char *config = NULL; - int chrp = 0; - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:c:o:hVvn", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'm': - if (memdisk) - free (memdisk); - memdisk = xstrdup (optarg); - - if (prefix) - free (prefix); - prefix = xstrdup ("(memdisk)/boot/grub"); - - break; - case 'c': - if (config) - free (config); - config = xstrdup (optarg); - - break; - - case 'h': - usage (0); - break; - case 'n': - chrp = 1; - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (!output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - add_segments (dir ? : GRUB_LIBDIR, prefix, fp, chrp, argv + optind, memdisk, - config); - - fclose (fp); - - return 0; -} diff --git a/util/grub-install.in b/util/grub-install.in index 142d5792f..0db216fd5 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -35,11 +35,7 @@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${t localedir=@datadir@/locale grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` -if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` -else - grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` -fi +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -346,16 +342,23 @@ else prefix_drive=`$grub_probe --target=drive --device ${grub_device}` || exit 1 fi +case "${target_cpu}-${platform}" in + i386-pc) mkimage_target=i386-pc ;; + sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;; + mips-yeeloong) mkimage_target=mipsel-yeeloong-elf ;; + *) mkimage_target=i386-coreboot; +esac + if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then - $grub_mkimage ${config_opt} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -O ${mkimage_target} --output=${grubdir}/core.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 # Now perform the installation. $grub_setup ${setup_verbose} ${setup_force} --directory=${grubdir} --device-map=${device_map} \ ${install_device} || exit 1 elif [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then - $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O elf --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage ${config_opt} -f ${font} -d ${pkglibdir} -O ${mkimage_target} --output=/boot/grub.elf --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 else - $grub_mkimage ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 + $grub_mkimage -O ${mkimage_target} ${config_opt} -d ${pkglibdir} --output=/boot/multiboot.img --prefix=${prefix_drive}${relative_grubdir} $modules || exit 1 fi echo "Installation finished. No error reported." diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 831bef846..f4674b257 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -1,5 +1,5 @@ # Helper library for grub-mkconfig -# Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. +# Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -44,21 +44,7 @@ grub_warn () make_system_path_relative_to_its_root () { - path="`${grub_mkrelpath} $1`" - - case "`uname 2>/dev/null`" in - CYGWIN*) - # Cygwin: Check if regular or emulated mount. - if [ -z "$dir" ] || [ "`stat -c %D "$dir/.."`" != 620000 ] ; then - # Reached some mount point not below /cygdrive. - # GRUB does not know Cygwin's emulated mounts, - # convert to Win32 path and remove drive letter. - path=`cygpath -m "$path" | sed -n 's,^[A-Za-z]:,,p'` - test ! -z "$path" || return 1 - fi ;; - esac - - echo "$path" + ${grub_mkrelpath} $1 } is_path_readable_by_grub () diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index c68482af1..db37f99e6 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -31,6 +31,7 @@ #include #include +#include #include #define _GNU_SOURCE 1 @@ -38,6 +39,24 @@ #include "progname.h" +void +grub_putchar (int c) +{ + putchar (c); +} + +int +grub_getkey (void) +{ + return -1; +} + +void +grub_refresh (void) +{ + fflush (stdout); +} + static void make_device_map (const char *device_map, int floppy_disks) { @@ -158,6 +177,9 @@ main (int argc, char *argv[]) } } + if (verbosity > 1) + grub_env_set ("debug", "all"); + make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks); free (dev_map); diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c new file mode 100644 index 000000000..6366a9803 --- /dev/null +++ b/util/grub-mkimage.c @@ -0,0 +1,1364 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE 1 +#include + +#include "progname.h" + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#define TARGET_NO_FIELD 0xffffffff +struct image_target_desc +{ + const char *name; + grub_size_t voidp_sizeof; + int bigendian; + enum { + IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT, + IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275, + IMAGE_YEELOONG_ELF, IMAGE_QEMU, IMAGE_PPC + } id; + enum + { + PLATFORM_FLAGS_NONE = 0, + PLATFORM_FLAGS_LZMA = 1 + } flags; + unsigned prefix; + unsigned data_end; + unsigned raw_size; + unsigned total_module_size; + unsigned kernel_image_size; + unsigned compressed_size; + unsigned link_align; + grub_uint16_t elf_target; + unsigned section_align; + signed vaddr_offset; + unsigned install_dos_part, install_bsd_part; + grub_uint64_t link_addr; + unsigned mod_gap, mod_align; +}; + +struct image_target_desc image_targets[] = + { + { + .name = "i386-coreboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .name = "i386-multiboot", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_COREBOOT_PREFIX, + .data_end = GRUB_KERNEL_I386_COREBOOT_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .name = "i386-pc", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_LZMA, + .prefix = GRUB_KERNEL_I386_PC_PREFIX, + .data_end = GRUB_KERNEL_I386_PC_DATA_END, + .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE, + .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_I386_PC_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART, + .install_bsd_part = GRUB_KERNEL_I386_PC_INSTALL_BSD_PART, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR + }, + { + .name = "i386-efi", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_EFI_PREFIX, + .data_end = GRUB_KERNEL_I386_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + }, + { + .name = "i386-ieee1275", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_I386_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, + }, + { + .name = "i386-qemu", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_I386_QEMU_PREFIX, + .data_end = GRUB_KERNEL_I386_QEMU_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .kernel_image_size = GRUB_KERNEL_I386_QEMU_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .name = "x86_64-efi", + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_X86_64_EFI_PREFIX, + .data_end = GRUB_KERNEL_X86_64_EFI_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT), + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + }, + { + .name = "mipsel-yeeloong-elf", + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_ELF, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_MIPS_YEELOONG_PREFIX, + .data_end = GRUB_KERNEL_MIPS_YEELOONG_DATA_END, + .raw_size = GRUB_KERNEL_MIPS_YEELOONG_RAW_SIZE, + .total_module_size = GRUB_KERNEL_MIPS_YEELOONG_TOTAL_MODULE_SIZE, + .compressed_size = GRUB_KERNEL_MIPS_YEELOONG_COMPRESSED_SIZE, + .kernel_image_size = GRUB_KERNEL_MIPS_YEELOONG_KERNEL_IMAGE_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_MIPS_YEELOONG_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_YEELOONG_LINK_ALIGN + }, + { + .name = "powerpc-ieee1275", + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_POWERPC_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_POWERPC_IEEE1275_DATA_END, + .raw_size = 0, + .total_module_size = TARGET_NO_FIELD, + .kernel_image_size = TARGET_NO_FIELD, + .compressed_size = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 + }, + { + .name = "sparc64-ieee1275-raw", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + { + .name = "sparc64-ieee1275-aout", + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .prefix = GRUB_KERNEL_SPARC64_IEEE1275_PREFIX, + .data_end = GRUB_KERNEL_SPARC64_IEEE1275_DATA_END, + .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .kernel_image_size = GRUB_KERNEL_SPARC64_IEEE1275_KERNEL_IMAGE_SIZE, + .compressed_size = GRUB_KERNEL_SPARC64_IEEE1275_COMPRESSED_SIZE, + .section_align = 1, + .vaddr_offset = 0, + .install_dos_part = TARGET_NO_FIELD, + .install_bsd_part = TARGET_NO_FIELD, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR + }, + }; + +#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x))) + +static inline grub_uint32_t +grub_target_to_host32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint64_t +grub_host_to_target64_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be64 (in); + else + return grub_cpu_to_le64 (in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (struct image_target_desc *image_target, grub_uint32_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (struct image_target_desc *image_target, grub_uint16_t in) +{ + if (image_target->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} + +static inline grub_uint64_t +grub_host_to_target_addr_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_host_to_target64_real (image_target, in); + else + return grub_host_to_target32_real (image_target, in); +} + +static inline grub_uint64_t +grub_target_to_host_real (struct image_target_desc *image_target, grub_uint64_t in) +{ + if (image_target->voidp_sizeof == 8) + return grub_target_to_host64_real (image_target, in); + else + return grub_target_to_host32_real (image_target, in); +} + +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_hdr +{ + grub_uint32_t namesz; + grub_uint32_t descsz; + grub_uint32_t type; + char name[sizeof (GRUB_IEEE1275_NOTE_NAME)]; +}; + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +struct grub_ieee1275_note +{ + struct grub_ieee1275_note_hdr header; + struct grub_ieee1275_note_desc descriptor; +}; + +#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val)) + +#include + +static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } +static void SzFree(void *p, void *address) { p = p; free(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static void +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size, size_t raw_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size = 5; + + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + + if (kernel_size < raw_size) + grub_util_error (_("the core image is too small")); + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, raw_size); + + *core_size = kernel_size - raw_size; + if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size, + (unsigned char *) kernel_img + raw_size, + kernel_size - raw_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + grub_util_error (_("cannot compress the kernel image")); + + *core_size += raw_size; +} + +static void +compress_kernel (struct image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size) +{ + if (image_target->flags & PLATFORM_FLAGS_LZMA) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size, image_target->raw_size); + return; + } + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, kernel_size); + *core_size = kernel_size; +} + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +#define MKIMAGE_ELF32 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF32 + +#define MKIMAGE_ELF64 1 +#include "grub-mkimagexx.c" +#undef MKIMAGE_ELF64 + +static void +generate_image (const char *dir, char *prefix, FILE *out, char *mods[], + char *memdisk_path, char *font_path, char *config_path, + struct image_target_desc *image_target, int note) +{ + char *kernel_img, *core_img; + size_t kernel_size, total_module_size, core_size, exec_size; + size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; + char *kernel_path; + size_t offset; + struct grub_util_path_list *path_list, *p, *next; + grub_size_t bss_size; + grub_uint64_t start_address; + void *rel_section; + grub_size_t reloc_size, align; + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + kernel_path = grub_util_get_path (dir, "kernel.img"); + + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); + + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); + grub_util_info ("the size of memory disk is 0x%x", memdisk_size); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + if (font_path) + { + font_size = ALIGN_ADDR (grub_util_get_image_size (font_path)); + total_module_size += font_size + sizeof (struct grub_module_header); + } + + if (config_path) + { + config_size_pure = grub_util_get_image_size (config_path) + 1; + config_size = ALIGN_ADDR (config_size_pure); + grub_util_info ("the size of config file is 0x%x", config_size); + total_module_size += config_size + sizeof (struct grub_module_header); + } + + for (p = path_list; p; p = p->next) + total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + + sizeof (struct grub_module_header)); + + grub_util_info ("the total module size is 0x%x", total_module_size); + + if (image_target->voidp_sizeof == 4) + kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, &align, image_target); + else + kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size, + total_module_size, &start_address, &rel_section, + &reloc_size, &align, image_target); + + if (image_target->prefix + strlen (prefix) + 1 > image_target->data_end) + grub_util_error (_("prefix is too long")); + strcpy (kernel_img + image_target->prefix, prefix); + + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info64)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size); + memset (modinfo, 0, sizeof (struct grub_module_info32)); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + offset = kernel_size + sizeof (struct grub_module_info32); + } + + for (p = path_list; p; p = p->next) + { + struct grub_module_header *header; + size_t mod_size, orig_size; + + orig_size = grub_util_get_image_size (p->name); + mod_size = ALIGN_ADDR (orig_size); + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); + header->size = grub_host_to_target32 (mod_size + sizeof (*header)); + offset += sizeof (*header); + memset (kernel_img + offset + orig_size, 0, mod_size - orig_size); + + grub_util_load_image (p->name, kernel_img + offset); + offset += mod_size; + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK); + header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (memdisk_path, kernel_img + offset); + offset += memdisk_size; + } + + if (font_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_FONT); + header->size = grub_host_to_target32 (font_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (font_path, kernel_img + offset); + offset += font_size; + } + + if (config_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + memset (header, 0, sizeof (struct grub_module_header)); + header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG); + header->size = grub_host_to_target32 (config_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (config_path, kernel_img + offset); + *(kernel_img + offset + config_size_pure - 1) = 0; + offset += config_size; + } + + grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); + compress_kernel (image_target, kernel_img, kernel_size + total_module_size, + &core_img, &core_size); + + grub_util_info ("the core size is 0x%x", core_size); + + if (image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + if (image_target->kernel_image_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->kernel_image_size)) + = grub_host_to_target32 (kernel_size); + if (image_target->compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->compressed_size)) + = grub_host_to_target32 (core_size - image_target->raw_size); + + /* If we included a drive in our prefix, let GRUB know it doesn't have to + prepend the drive told by BIOS. */ + if (image_target->install_dos_part != TARGET_NO_FIELD + && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(') + { + *((grub_int32_t *) (core_img + image_target->install_dos_part)) + = grub_host_to_target32 (-2); + *((grub_int32_t *) (core_img + image_target->install_bsd_part)) + = grub_host_to_target32 (-2); + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; + + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > GRUB_MEMORY_I386_PC_UPPER) + grub_util_error (_("core image is too big (%p > %p)"), + GRUB_KERNEL_I386_PC_LINK_ADDR + core_size, + GRUB_MEMORY_I386_PC_UPPER); + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (num > 0xffff) + grub_util_error (_("the core image is too big")); + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img = grub_util_read_image (boot_path); + + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); + + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + grub_uint8_t *header; + void *sections; + size_t pe_size; + struct grub_pe32_coff_header *c; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size; + int reloc_addr; + + if (image_target->voidp_sizeof == 4) + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe32_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + else + header_size = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header) + + sizeof (struct grub_pe64_optional_header) + + 4 * sizeof (struct grub_pe32_section_table), + GRUB_PE32_SECTION_ALIGNMENT); + + reloc_addr = ALIGN_UP (header_size + core_size, + image_target->section_align); + + pe_size = ALIGN_UP (reloc_addr + reloc_size, + image_target->section_align); + pe_img = xmalloc (reloc_addr + reloc_size); + memset (pe_img, 0, header_size); + memcpy (pe_img + header_size, core_img, core_size); + memcpy (pe_img + reloc_addr, rel_section, reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); + + /* The COFF file header. */ + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); + if (image_target->voidp_sizeof == 4) + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_I386); + else + c->machine = grub_host_to_target16 (GRUB_PE32_MACHINE_X86_64); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (time (0)); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + if (image_target->voidp_sizeof == 4) + { + struct grub_pe32_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; + } + else + { + struct grub_pe64_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); + + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + o->code_size = grub_host_to_target32 (exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (bss_size); + o->entry_addr = grub_cpu_to_le32 (start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (image_target->section_align); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (reloc_size); + sections = o + 1; + } + /* The sections. */ + text_section = sections; + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size); + data_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size); + mods_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img, core_img, core_size); + + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; + + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy (aout_img + sizeof (*aout_head), core_img, core_size); + + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error ("diskboot.img is not one sector size"); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_YEELOONG_ELF: + case IMAGE_PPC: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + char *elf_img; + size_t program_size; + Elf32_Ehdr *ehdr; + Elf32_Phdr *phdr; + grub_uint32_t target_addr; + int header_size, footer_size = 0; + int phnum = 1; + + if (image_target->id != IMAGE_YEELOONG_ELF) + phnum += 2; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + header_size = ALIGN_ADDR (sizeof (*ehdr) + phnum * sizeof (*phdr)); + + program_size = ALIGN_ADDR (core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size); + memcpy (elf_img + header_size, core_img, core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASS32; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + /* No section headers. */ + ehdr->e_shoff = grub_host_to_target32 (0); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf32_Shdr)); + ehdr->e_shnum = grub_host_to_target16 (0); + ehdr->e_shstrndx = grub_host_to_target16 (0); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + if (image_target->id == IMAGE_YEELOONG_ELF) + target_addr = ALIGN_UP (image_target->link_addr + + kernel_size + total_module_size, 32); + else + target_addr = image_target->link_addr; + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (align > image_target->link_align ? align : image_target->link_align); + if (image_target->id == IMAGE_YEELOONG_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + if (image_target->id == IMAGE_YEELOONG_ELF) + { + phdr->p_filesz = grub_host_to_target32 (core_size); + phdr->p_memsz = grub_host_to_target32 (core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (kernel_size); + phdr->p_memsz = grub_host_to_target32 (kernel_size + bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (core_size - kernel_size); + + target_addr_mods = ALIGN_UP (target_addr + kernel_size + bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target32 (target_addr_mods); + phdr->p_paddr = grub_host_to_target32 (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note->header.namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note->header.descsz = grub_host_to_target32 (note_size); + note->header.type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note->header.name, GRUB_IEEE1275_NOTE_NAME); + note->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + free (core_img); + core_img = elf_img; + core_size = program_size + header_size + footer_size; + } + break; + } + + grub_util_write_image (core_img, core_size, out); + free (kernel_img); + free (core_img); + free (kernel_path); + + while (path_list) + { + next = path_list->next; + free ((void *) path_list->name); + free (path_list); + path_list = next; + } +} + + + +static struct option options[] = + { + {"directory", required_argument, 0, 'd'}, + {"prefix", required_argument, 0, 'p'}, + {"memdisk", required_argument, 0, 'm'}, + {"font", required_argument, 0, 'f'}, + {"config", required_argument, 0, 'c'}, + {"output", required_argument, 0, 'o'}, + {"note", no_argument, 0, 'n'}, + {"format", required_argument, 0, 'O'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {"verbose", no_argument, 0, 'v'}, + {0, 0, 0, 0} + }; + +static void +usage (int status) +{ + if (status) + fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); + else + { + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].name) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].name); + ptr += strlen (image_targets[i].name); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + printf (_("\ +Usage: %s [OPTION]... [MODULES]\n\ +\n\ +Make a bootable image of GRUB.\n\ +\n\ + -d, --directory=DIR use images and modules under DIR [default=%s/@platform@]\n\ + -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ + -m, --memdisk=FILE embed FILE as a memdisk image\n\ + -f, --font=FILE embed FILE as a boot font\n\ + -c, --config=FILE embed FILE as boot config\n\ + -n, --note add NOTE segment for CHRP Open Firmware\n\ + -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -O, --format=FORMAT generate an image in format\n\ + available formats: %s\n\ + -h, --help display this message and exit\n\ + -V, --version print version information and exit\n\ + -v, --verbose print verbose messages\n\ +\n\ +Report bugs to <%s>.\n\ +"), + program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY, + formats, + PACKAGE_BUGREPORT); + free (formats); + } + exit (status); +} + +int +main (int argc, char *argv[]) +{ + char *output = NULL; + char *dir = NULL; + char *prefix = NULL; + char *memdisk = NULL; + char *font = NULL; + char *config = NULL; + FILE *fp = stdout; + int note = 0; + struct image_target_desc *image_target = NULL; + + set_program_name (argv[0]); + + grub_util_init_nls (); + + while (1) + { + int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVvn", options, 0); + + if (c == -1) + break; + else + switch (c) + { + case 'o': + if (output) + free (output); + + output = xstrdup (optarg); + break; + + case 'O': + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + if (strcmp (optarg, image_targets[i].name) == 0) + image_target = &image_targets[i]; + if (!image_target) + { + printf ("unknown target %s\n", optarg); + usage (1); + } + break; + } + case 'd': + if (dir) + free (dir); + + dir = xstrdup (optarg); + break; + + case 'n': + note = 1; + break; + + case 'm': + if (memdisk) + free (memdisk); + + memdisk = xstrdup (optarg); + + if (prefix) + free (prefix); + + prefix = xstrdup ("(memdisk)/boot/grub"); + break; + + case 'f': + if (font) + free (font); + + font = xstrdup (optarg); + break; + + case 'c': + if (config) + free (config); + + config = xstrdup (optarg); + break; + + case 'h': + usage (0); + break; + + case 'p': + if (prefix) + free (prefix); + + prefix = xstrdup (optarg); + break; + + case 'V': + printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + return 0; + + case 'v': + verbosity++; + break; + + default: + usage (1); + break; + } + } + + if (!image_target) + { + printf ("Target not specified.\n"); + usage (1); + } + + if (output) + { + fp = fopen (output, "wb"); + if (! fp) + grub_util_error (_("cannot open %s"), output); + free (output); + } + + if (!dir) + { + const char *last; + last = strchr (image_target->name, '-'); + if (last) + last = strchr (last + 1, '-'); + if (!last) + last = image_target->name + strlen (image_target->name); + dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name) + + 1); + memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; + memcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->name, + last - image_target->name); + *(dir + sizeof (GRUB_PKGLIBROOTDIR) + (last - image_target->name)) = 0; + } + + generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp, + argv + optind, memdisk, font, config, + image_target, note); + + fclose (fp); + + if (dir) + free (dir); + + return 0; +} diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c new file mode 100644 index 000000000..4a257e329 --- /dev/null +++ b/util/grub-mkimagexx.c @@ -0,0 +1,756 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#undef ELF_R_SYM +#undef ELF_R_TYPE + +#if defined(MKIMAGE_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +#elif defined(MKIMAGE_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +#else +#error "I'm confused" +#endif + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Shdr *symtab_section, Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + struct image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = 0; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *strtab_section; + const char *strtab; + + strtab_section + = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (symtab_section->sh_link) + * section_entsize)); + strtab = (char *) e + grub_target_to_host (strtab_section->sh_offset); + + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section index; + const char *name; + + name = strtab + grub_target_to_host32 (sym->st_name); + + index = grub_target_to_host16 (sym->st_shndx); + if (index == STN_ABS) + { + continue; + } + else if ((index == STN_UNDEF)) + { + if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (index >= num_sections) + grub_util_error ("section %d does not exist", index); + + sym->st_value = (grub_target_to_host32 (sym->st_value) + + section_addresses[index]); + grub_util_info ("locating %s at 0x%x", name, sym->st_value); + + if (! start_address) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + struct image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host32 (s->sh_offset) + + i * grub_target_to_host32 (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + struct image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host32 (s->sh_offset) + offset); +} + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +SUFFIX (relocate_addresses) (Elf_Ehdr *e, Elf_Shdr *sections, + Elf_Addr *section_addresses, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = section_addresses[target_section_index]; + target_section = (Elf_Shdr *) ((char *) sections + + (target_section_index + * section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + strtab + grub_target_to_host32 (s->sh_name), + strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host32 (s->sh_size); + r_size = grub_target_to_host32 (s->sh_entsize); + rtab_offset = grub_target_to_host32 (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + r->r_addend : 0; + + if (image_target->voidp_sizeof == 4) + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", + *target, offset); + break; + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + else + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", + *target, offset); + break; + + case R_X86_64_PC32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", + *t32, offset); + break; + } + + default: + grub_util_error ("unknown relocation type %d", + ELF_R_TYPE (info)); + break; + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +SUFFIX (add_fixup_entry) (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + struct image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, image_target->section_align) + - next_address) + >> 1); + index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[index++] = 0; + b->block_size += 2; + } + } + else if (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t index; + + grub_util_info ("adding a padding fixup entry"); + index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); + b->entries[index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +/* Make a .reloc section. */ +static Elf_Addr +SUFFIX (make_reloc_section) (Elf_Ehdr *e, void **out, + Elf_Addr *section_addresses, Elf_Shdr *sections, + Elf_Half section_entsize, Elf_Half num_sections, + const char *strtab, struct image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address = 0; + + lst = lst0 = xmalloc (sizeof (*lst) + 2 * 0x1000); + memset (lst, 0, sizeof (*lst) + 2 * 0x1000); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || + (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) + { + Elf_Rel *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Addr section_address; + Elf_Word j; + + grub_util_info ("translating the relocation section %s", + strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_le_to_cpu32 (s->sh_size); + r_size = grub_le_to_cpu32 (s->sh_entsize); + rtab_offset = grub_le_to_cpu32 (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rel *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + + offset = grub_le_to_cpu32 (r->r_offset); + info = grub_le_to_cpu32 (r->r_info); + + /* Necessary to relocate only absolute addresses. */ + if (image_target->voidp_sizeof == 4) + { + if (ELF_R_TYPE (info) == R_386_32) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%x", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, current_address, + image_target); + } + } + else + { + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + Elf_Addr addr; + + addr = section_address + offset; + grub_util_info ("adding a relocation entry for 0x%llx", addr); + current_address + = SUFFIX (add_fixup_entry) (&lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, current_address, + image_target); + } + } + } + } + + current_address = SUFFIX (add_fixup_entry) (&lst, 0, 0, 1, current_address, image_target); + + { + grub_uint8_t *ptr; + ptr = *out = xmalloc (current_address); + for (lst = lst0; lst; lst = lst->next) + if (lst->state) + { + memcpy (ptr, &lst->b, grub_target_to_host32 (lst->b.block_size)); + ptr += grub_target_to_host32 (lst->b.block_size); + } + if (current_address + *out != ptr) + { + grub_util_error ("Bug detected %d != %d\n", ptr - (grub_uint8_t *) *out, + current_address); + } + } + + return current_address; +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. This assumes that + BSS is also a data section, since the converter initializes BSS + when producing PE32 to avoid a bug in EFI implementations. */ +static int +SUFFIX (is_data_section) (Elf_Shdr *s, struct image_target_desc *image_target) +{ + if (image_target->id != IMAGE_EFI + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC); +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, struct image_target_desc *image_target) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +/* Locate section addresses by merging code sections and data sections + into .text and .data, respectively. Return the array of section + addresses. */ +static Elf_Addr * +SUFFIX (locate_sections) (Elf_Shdr *sections, Elf_Half section_entsize, + Elf_Half num_sections, const char *strtab, + grub_size_t *exec_size, grub_size_t *kernel_sz, + grub_size_t *all_align, + struct image_target_desc *image_target) +{ + int i; + Elf_Addr current_address; + Elf_Addr *section_addresses; + Elf_Shdr *s; + + *all_align = 1; + + section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); + memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); + + current_address = 0; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > *all_align) + *all_align = grub_host_to_target32 (s->sh_addralign); + + + /* .text */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) - image_target->vaddr_offset; + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target_addr (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *exec_size = current_address; + + /* .data */ + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_addresses[i] = current_address; + current_address += grub_host_to_target_addr (s->sh_size); + } + + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + *kernel_sz = current_address; + return section_addresses; +} + +static char * +SUFFIX (load_image) (const char *kernel_path, grub_size_t *exec_size, + grub_size_t *kernel_sz, grub_size_t *bss_size, + grub_size_t total_module_size, grub_uint64_t *start, + void **reloc_section, grub_size_t *reloc_size, + grub_size_t *align, + struct image_target_desc *image_target) +{ + char *kernel_img, *out_img; + const char *strtab; + Elf_Ehdr *e; + Elf_Shdr *sections; + Elf_Addr *section_addresses; + Elf_Addr *section_vaddresses; + int i; + Elf_Shdr *s; + Elf_Half num_sections; + Elf_Off section_offset; + Elf_Half section_entsize; + grub_size_t kernel_size; + Elf_Shdr *symtab_section; + + *start = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host (e->e_shoff); + section_entsize = grub_target_to_host16 (e->e_shentsize); + num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + section_entsize * num_sections) + grub_util_error ("invalid ELF format"); + + sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) sections + + grub_host_to_target16 (e->e_shstrndx) * section_entsize); + strtab = (char *) e + grub_host_to_target32 (s->sh_offset); + + section_addresses = SUFFIX (locate_sections) (sections, section_entsize, + num_sections, strtab, + exec_size, kernel_sz, align, + image_target); + + section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections); + + for (i = 0; i < num_sections; i++) + section_vaddresses[i] = section_addresses[i] + image_target->vaddr_offset; + + if (image_target->id != IMAGE_EFI) + { + Elf_Addr current_address = *kernel_sz; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word align = grub_host_to_target32 (s->sh_addralign); + const char *name = strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%x", + name, current_address); + section_vaddresses[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + *bss_size = current_address - *kernel_sz; + } + else + *bss_size = 0; + + if (image_target->id == IMAGE_EFI) + { + symtab_section = NULL; + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + symtab_section = s; + break; + } + + if (! symtab_section) + grub_util_error ("no symbol table"); + + *start = SUFFIX (relocate_symbols) (e, sections, symtab_section, + section_vaddresses, section_entsize, + num_sections, image_target); + if (*start == 0) + grub_util_error ("start symbol is not defined"); + + /* Resolve addresses in the virtual address space. */ + SUFFIX (relocate_addresses) (e, sections, section_addresses, section_entsize, + num_sections, strtab, image_target); + + *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section, + section_vaddresses, sections, + section_entsize, num_sections, + strtab, image_target); + } + else + { + *reloc_size = 0; + *reloc_section = NULL; + } + + out_img = xmalloc (*kernel_sz + total_module_size); + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if (SUFFIX (is_data_section) (s, image_target) + || SUFFIX (is_text_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + section_addresses[i], 0, + grub_host_to_target_addr (s->sh_size)); + else + memcpy (out_img + section_addresses[i], + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); + } + free (kernel_img); + + return out_img; +} + + +#undef SUFFIX +#undef ELFCLASSXX +#undef Elf_Ehdr +#undef Elf_Phdr +#undef Elf_Shdr +#undef Elf_Addr +#undef Elf_Sym +#undef Elf_Off +#undef Elf_Rela +#undef Elf_Rel +#undef ELF_R_TYPE +#undef ELF_R_SYM diff --git a/util/grub-mkrawimage.c b/util/grub-mkrawimage.c deleted file mode 100644 index 20a344d04..000000000 --- a/util/grub-mkrawimage.c +++ /dev/null @@ -1,648 +0,0 @@ -/* grub-mkimage.c - make a bootable image */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define _GNU_SOURCE 1 -#include - -#include "progname.h" - -#define ALIGN_ADDR(x) (ALIGN_UP((x), GRUB_TARGET_SIZEOF_VOID_P)) - -#ifdef ENABLE_LZMA -#include - -static void *SzAlloc(void *p, size_t size) { p = p; return xmalloc(size); } -static void SzFree(void *p, void *address) { p = p; free(address); } -static ISzAlloc g_Alloc = { SzAlloc, SzFree }; - -static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) -{ - CLzmaEncProps props; - unsigned char out_props[5]; - size_t out_props_size = 5; - - LzmaEncProps_Init(&props); - props.dictSize = 1 << 16; - props.lc = 3; - props.lp = 0; - props.pb = 2; - props.numThreads = 1; - - if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE) - grub_util_error (_("the core image is too small")); - - *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE); - - *core_size = kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE; - if (LzmaEncode((unsigned char *) *core_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - core_size, - (unsigned char *) kernel_img + GRUB_KERNEL_MACHINE_RAW_SIZE, - kernel_size - GRUB_KERNEL_MACHINE_RAW_SIZE, - &props, out_props, &out_props_size, - 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) - grub_util_error (_("cannot compress the kernel image")); - - *core_size += GRUB_KERNEL_MACHINE_RAW_SIZE; -} - -#else /* No lzma compression */ - -static void -compress_kernel (char *kernel_img, size_t kernel_size, - char **core_img, size_t *core_size) -{ - *core_img = xmalloc (kernel_size); - memcpy (*core_img, kernel_img, kernel_size); - *core_size = kernel_size; -} - -#endif /* No lzma compression */ - -static void -generate_image (const char *dir, char *prefix, FILE *out, char *mods[], - char *memdisk_path, char *font_path, char *config_path, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format -#else - int dummy __attribute__ ((unused)) -#endif - -) -{ - char *kernel_img, *core_img; - size_t kernel_size, total_module_size, core_size; - size_t memdisk_size = 0, font_size = 0, config_size = 0, config_size_pure = 0; - char *kernel_path; - size_t offset; - struct grub_util_path_list *path_list, *p, *next; - struct grub_module_info *modinfo; - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - kernel_path = grub_util_get_path (dir, "kernel.img"); - kernel_size = grub_util_get_image_size (kernel_path); - - total_module_size = sizeof (struct grub_module_info); - - if (memdisk_path) - { - memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); - grub_util_info ("the size of memory disk is 0x%x", memdisk_size); - total_module_size += memdisk_size + sizeof (struct grub_module_header); - } - - if (font_path) - { - font_size = ALIGN_ADDR (grub_util_get_image_size (font_path)); - total_module_size += font_size + sizeof (struct grub_module_header); - } - - if (config_path) - { - config_size_pure = grub_util_get_image_size (config_path) + 1; - config_size = ALIGN_ADDR (config_size_pure); - grub_util_info ("the size of config file is 0x%x", config_size); - total_module_size += config_size + sizeof (struct grub_module_header); - } - - for (p = path_list; p; p = p->next) - total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) - + sizeof (struct grub_module_header)); - - grub_util_info ("the total module size is 0x%x", total_module_size); - - kernel_img = xmalloc (kernel_size + total_module_size); - grub_util_load_image (kernel_path, kernel_img); - - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error (_("prefix is too long")); - strcpy (kernel_img + GRUB_KERNEL_MACHINE_PREFIX, prefix); - - /* Fill in the grub_module_info structure. */ - modinfo = (struct grub_module_info *) (kernel_img + kernel_size); - memset (modinfo, 0, sizeof (struct grub_module_info)); - modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); - modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info)); - modinfo->size = grub_host_to_target_addr (total_module_size); - - offset = kernel_size + sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - { - struct grub_module_header *header; - size_t mod_size, orig_size; - - orig_size = grub_util_get_image_size (p->name); - mod_size = ALIGN_ADDR (orig_size); - - header = (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type = grub_host_to_target32 (OBJ_TYPE_ELF); - header->size = grub_host_to_target32 (mod_size + sizeof (*header)); - offset += sizeof (*header); - memset (kernel_img + offset + orig_size, 0, mod_size - orig_size); - - grub_util_load_image (p->name, kernel_img + offset); - offset += mod_size; - } - - if (memdisk_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK); - header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (memdisk_path, kernel_img + offset); - offset += memdisk_size; - } - - if (font_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type = grub_host_to_target32 (OBJ_TYPE_FONT); - header->size = grub_host_to_target32 (font_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (font_path, kernel_img + offset); - offset += font_size; - } - - if (config_path) - { - struct grub_module_header *header; - - header = (struct grub_module_header *) (kernel_img + offset); - memset (header, 0, sizeof (struct grub_module_header)); - header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG); - header->size = grub_host_to_target32 (config_size + sizeof (*header)); - offset += sizeof (*header); - - grub_util_load_image (config_path, kernel_img + offset); - *(kernel_img + offset + config_size_pure - 1) = 0; - offset += config_size; - } - - grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size); - compress_kernel (kernel_img, kernel_size + total_module_size, - &core_img, &core_size); - - grub_util_info ("the core size is 0x%x", core_size); - -#ifdef GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE)) - = grub_host_to_target32 (total_module_size); -#endif - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_KERNEL_IMAGE_SIZE)) - = grub_host_to_target32 (kernel_size); -#ifdef GRUB_KERNEL_MACHINE_COMPRESSED_SIZE - *((grub_uint32_t *) (core_img + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE)) - = grub_host_to_target32 (core_size - GRUB_KERNEL_MACHINE_RAW_SIZE); -#endif - -#if defined(GRUB_KERNEL_MACHINE_INSTALL_DOS_PART) && defined(GRUB_KERNEL_MACHINE_INSTALL_BSD_PART) - /* If we included a drive in our prefix, let GRUB know it doesn't have to - prepend the drive told by BIOS. */ - if (prefix[0] == '(') - { - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)) - = grub_host_to_target32 (-2); - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)) - = grub_host_to_target32 (-2); - } -#endif - -#ifdef GRUB_MACHINE_PCBIOS - if (GRUB_KERNEL_MACHINE_LINK_ADDR + core_size > GRUB_MEMORY_MACHINE_UPPER) - grub_util_error (_("core image is too big (%p > %p)"), - GRUB_KERNEL_MACHINE_LINK_ADDR + core_size, - GRUB_MEMORY_MACHINE_UPPER); -#endif - -#if defined(GRUB_MACHINE_PCBIOS) - { - unsigned num; - char *boot_path, *boot_img; - size_t boot_size; - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - if (num > 0xffff) - grub_util_error (_("the core image is too big")); - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error (_("diskboot.img size must be %u bytes"), - GRUB_DISK_SECTOR_SIZE); - - boot_img = grub_util_read_image (boot_path); - - { - struct grub_boot_blocklist *block; - block = (struct grub_boot_blocklist *) (boot_img - + GRUB_DISK_SECTOR_SIZE - - sizeof (*block)); - block->len = grub_host_to_target16 (num); - - /* This is filled elsewhere. Verify it just in case. */ - assert (block->segment - == grub_host_to_target16 (GRUB_BOOT_MACHINE_KERNEL_SEG - + (GRUB_DISK_SECTOR_SIZE >> 4))); - } - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_QEMU) - { - char *rom_img; - size_t rom_size; - char *boot_path, *boot_img; - size_t boot_size; - - boot_path = grub_util_get_path (dir, "boot.img"); - boot_size = grub_util_get_image_size (boot_path); - boot_img = grub_util_read_image (boot_path); - - /* Rom sizes must be 64k-aligned. */ - rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); - - rom_img = xmalloc (rom_size); - memset (rom_img, 0, rom_size); - - *((grub_int32_t *) (core_img + GRUB_KERNEL_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); - - memcpy (rom_img, core_img, core_size); - - *((grub_int32_t *) (boot_img + GRUB_BOOT_MACHINE_CORE_ENTRY_ADDR)) - = grub_host_to_target32 ((grub_uint32_t) -rom_size); - - memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); - - free (core_img); - core_img = rom_img; - core_size = rom_size; - - free (boot_img); - free (boot_path); - } -#elif defined (GRUB_MACHINE_SPARC64) - if (format == GRUB_PLATFORM_IMAGE_AOUT) - { - void *aout_img; - size_t aout_size; - struct grub_aout32_header *aout_head; - - aout_size = core_size + sizeof (*aout_head); - aout_img = xmalloc (aout_size); - aout_head = aout_img; - aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) - | AOUT32_OMAGIC); - aout_head->a_text = grub_host_to_target32 (core_size); - aout_head->a_entry - = grub_host_to_target32 (GRUB_BOOT_MACHINE_IMAGE_ADDRESS); - memcpy (aout_img + sizeof (*aout_head), core_img, core_size); - - free (core_img); - core_img = aout_img; - core_size = aout_size; - } - else - { - unsigned int num; - char *boot_path, *boot_img; - size_t boot_size; - - num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); - num <<= GRUB_DISK_SECTOR_BITS; - - boot_path = grub_util_get_path (dir, "diskboot.img"); - boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) - grub_util_error ("diskboot.img is not one sector size"); - - boot_img = grub_util_read_image (boot_path); - - *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_host_to_target32 (num); - - grub_util_write_image (boot_img, boot_size, out); - free (boot_img); - free (boot_path); - } -#elif defined(GRUB_MACHINE_MIPS) - if (format == GRUB_PLATFORM_IMAGE_ELF) - { - char *elf_img; - size_t program_size; - Elf32_Ehdr *ehdr; - Elf32_Phdr *phdr; - grub_uint32_t target_addr; - - program_size = ALIGN_ADDR (core_size); - - elf_img = xmalloc (program_size + sizeof (*ehdr) + sizeof (*phdr)); - memset (elf_img, 0, program_size + sizeof (*ehdr) + sizeof (*phdr)); - memcpy (elf_img + sizeof (*ehdr) + sizeof (*phdr), core_img, core_size); - ehdr = (void *) elf_img; - phdr = (void *) (elf_img + sizeof (*ehdr)); - memcpy (ehdr->e_ident, ELFMAG, SELFMAG); - ehdr->e_ident[EI_CLASS] = ELFCLASS32; -#ifdef GRUB_CPU_MIPSEL - ehdr->e_ident[EI_DATA] = ELFDATA2LSB; -#else - ehdr->e_ident[EI_DATA] = ELFDATA2MSB; -#endif - ehdr->e_ident[EI_VERSION] = EV_CURRENT; - ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; - ehdr->e_type = grub_host_to_target16 (ET_EXEC); - ehdr->e_machine = grub_host_to_target16 (EM_MIPS); - ehdr->e_version = grub_host_to_target32 (EV_CURRENT); - - ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); - ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); - ehdr->e_phnum = grub_host_to_target16 (1); - - /* No section headers. */ - ehdr->e_shoff = grub_host_to_target32 (0); - ehdr->e_shentsize = grub_host_to_target16 (0); - ehdr->e_shnum = grub_host_to_target16 (0); - ehdr->e_shstrndx = grub_host_to_target16 (0); - - ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - - phdr->p_type = grub_host_to_target32 (PT_LOAD); - phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); - phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - - target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR - + kernel_size + total_module_size, 32); - ehdr->e_entry = grub_host_to_target32 (target_addr); - phdr->p_vaddr = grub_host_to_target32 (target_addr); - phdr->p_paddr = grub_host_to_target32 (target_addr); - phdr->p_align = grub_host_to_target32 (GRUB_KERNEL_MACHINE_LINK_ALIGN); - ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER - | EF_MIPS_PIC | EF_MIPS_CPIC); - phdr->p_filesz = grub_host_to_target32 (core_size); - phdr->p_memsz = grub_host_to_target32 (core_size); - - free (core_img); - core_img = elf_img; - core_size = program_size + sizeof (*ehdr) + sizeof (*phdr); - } -#endif - - grub_util_write_image (core_img, core_size, out); - free (kernel_img); - free (core_img); - free (kernel_path); - - while (path_list) - { - next = path_list->next; - free ((void *) path_list->name); - free (path_list); - path_list = next; - } -} - - - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"memdisk", required_argument, 0, 'm'}, - {"font", required_argument, 0, 'f'}, - {"config", required_argument, 0, 'c'}, - {"output", required_argument, 0, 'o'}, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - {"format", required_argument, 0, 'O'}, -#endif - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - {0, 0, 0, 0} - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); - else - printf (_("\ -Usage: %s [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ - -m, --memdisk=FILE embed FILE as a memdisk image\n\ - -f, --font=FILE embed FILE as a boot font\n\ - -c, --config=FILE embed FILE as boot config\n\ - -o, --output=FILE output a generated image to FILE [default=stdout]\n" -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - "\ - -O, --format=FORMAT generate an image in format [default=%s]\n\ - available formats: %s\n" -#endif - "\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -"), -program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - GRUB_PLATFORM_IMAGE_DEFAULT_FORMAT, GRUB_PLATFORM_IMAGE_FORMATS, -#endif -PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - char *memdisk = NULL; - char *font = NULL; - char *config = NULL; - FILE *fp = stdout; -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - grub_platform_image_format_t format = GRUB_PLATFORM_IMAGE_DEFAULT; -#endif - - set_program_name (argv[0]); - - grub_util_init_nls (); - - while (1) - { - int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:hVv", options, 0); - - if (c == -1) - break; - else - switch (c) - { - case 'o': - if (output) - free (output); - - output = xstrdup (optarg); - break; - -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - case 'O': -#ifdef GRUB_PLATFORM_IMAGE_RAW - if (strcmp (optarg, "raw") == 0) - format = GRUB_PLATFORM_IMAGE_RAW; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_ELF - if (strcmp (optarg, "elf") == 0) - format = GRUB_PLATFORM_IMAGE_ELF; - else -#endif -#ifdef GRUB_PLATFORM_IMAGE_AOUT - if (strcmp (optarg, "aout") == 0) - format = GRUB_PLATFORM_IMAGE_AOUT; - else -#endif - usage (1); - break; -#endif - - case 'd': - if (dir) - free (dir); - - dir = xstrdup (optarg); - break; - - case 'm': - if (memdisk) - free (memdisk); - - memdisk = xstrdup (optarg); - - if (prefix) - free (prefix); - - prefix = xstrdup ("(memdisk)/boot/grub"); - break; - - case 'f': - if (font) - free (font); - - font = xstrdup (optarg); - break; - - case 'c': - if (config) - free (config); - - config = xstrdup (optarg); - break; - - case 'h': - usage (0); - break; - - case 'p': - if (prefix) - free (prefix); - - prefix = xstrdup (optarg); - break; - - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - - case 'v': - verbosity++; - break; - - default: - usage (1); - break; - } - } - - if (output) - { - fp = fopen (output, "wb"); - if (! fp) - grub_util_error (_("cannot open %s"), output); - free (output); - } - - generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, - argv + optind, memdisk, font, config, -#ifdef GRUB_PLATFORM_IMAGE_DEFAULT - format -#else - 0 -#endif - ); - - fclose (fp); - - if (dir) - free (dir); - - return 0; -} diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index 327f0c866..e771bd873 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -17,7 +17,9 @@ * along with GRUB. If not, see . */ +#include #include +#include #include #include @@ -97,7 +99,7 @@ main (int argc, char *argv[]) argument = argv[optind]; - relpath = make_system_path_relative_to_its_root (argument); + relpath = grub_make_system_path_relative_to_its_root (argument); printf ("%s\n", relpath); free (relpath); diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index aafdfb059..7e7253006 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,8 +30,14 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" -coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-coreboot -pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/${target_cpu}-pc +multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot +coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot +qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu +pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc +efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi +efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi +rom_directory= +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -42,8 +48,10 @@ Make GRUB rescue image. -h, --help print this message and exit -v, --version print the version information and exit - --modules=MODULES pre-load specified modules MODULES --output=FILE save output in FILE [required] + --modules=MODULES pre-load specified modules MODULES + --rom-directory=DIR save rom images in DIR [optional] + --grub-mkimage=FILE use FILE as grub-mkimage $0 generates a bootable rescue image with specified source files or directories. @@ -64,12 +72,16 @@ for option in "$@"; do modules=`echo "$option" | sed 's/--modules=//'` ;; --output=*) output_image=`echo "$option" | sed 's/--output=//'` ;; + --rom-directory=*) + rom_directory=`echo "$option" | sed 's/--rom-directory=//'` ;; # Intentionally undocumented --override-directory=*) override_dir=`echo "${option}/" | sed 's/--override-directory=//'` PATH=${override_dir}:$PATH export PATH ;; + --grub-mkimage=*) + grub_mkimage=`echo "$option" | sed 's/--grub-mkimage=//'` ;; -*) echo "Unrecognized option \`$option'" 1>&2 usage @@ -86,6 +98,14 @@ if [ "x${output_image}" = x ] ; then exit 1 fi +set $grub_mkimage dummy +if test -f "$1"; then + : +else + echo "$1: Not found." 1>&2 + exit 1 +fi + if test "x$TMP" != x; then MKTEMP_TEMPLATE="$TMP/grub-mkrescue.XXXXXXXXXX" elif test "x$TEMP" != x; then @@ -101,15 +121,15 @@ process_input_dir () { input_dir="$1" platform="$2" - mkdir -p ${iso9660_dir}/boot/grub/${target_cpu}-${platform} + mkdir -p ${iso9660_dir}/boot/grub/${platform} for file in ${input_dir}/*.mod; do if test -f "$file"; then - cp -f "$file" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "$file" ${iso9660_dir}/boot/grub/${platform}/ fi done for file in ${pkglib_DATA}; do if test -f "${input_dir}/${file}"; then - cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${target_cpu}-${platform}/ + cp -f "${input_dir}/${file}" ${iso9660_dir}/boot/grub/${platform}/ fi done @@ -121,57 +141,85 @@ process_input_dir () done } -if [ "${override_dir}" = "" ] ; then - if test -e "${coreboot_dir}" ; then - process_input_dir ${coreboot_dir} coreboot +make_image () +{ + source_directory="$1" + platform=$2 + if ! test -e "${source_directory}"; then + return; fi - if test -e "${pc_dir}" ; then - process_input_dir ${pc_dir} pc - fi -else - process_input_dir ${override_dir} ${native_platform} - coreboot_dir= - pc_dir= - case "${native_platform}" in - coreboot) coreboot_dir=${override_dir} ;; - pc) pc_dir=${override_dir} ;; - esac -fi -# build coreboot core.img -if test -e "${coreboot_dir}" ; then - echo "Enabling coreboot support ..." + echo "Enabling $2 support ..." + memdisk_img=`mktemp "$MKTEMP_TEMPLATE"` memdisk_dir=`mktemp -d "$MKTEMP_TEMPLATE"` mkdir -p ${memdisk_dir}/boot/grub - # obtain date-based UUID - iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) - modules="$(cat ${coreboot_dir}/partmap.lst) ${modules}" + modules="$(cat ${source_directory}/partmap.lst) ${modules}" cat << EOF > ${memdisk_dir}/boot/grub/grub.cfg search --fs-uuid --set ${iso_uuid} -set prefix=(\${root})/boot/grub/${target_cpu}-coreboot +set prefix=(\${root})/boot/grub/${platform} +source \$prefix/grub.cfg EOF (for i in ${modules} ; do echo "insmod $i" done ; \ echo "source /boot/grub/grub.cfg") \ - > ${iso9660_dir}/boot/grub/i386-coreboot/grub.cfg + > ${iso9660_dir}/boot/grub/${platform}/grub.cfg tar -C ${memdisk_dir} -cf ${memdisk_img} boot rm -rf ${memdisk_dir} - grub-mkelfimage -d ${coreboot_dir}/ -m ${memdisk_img} -o ${iso9660_dir}/boot/multiboot.img \ - memdisk tar search iso9660 configfile sh \ - ata at_keyboard - rm -f ${memdisk_img} - grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" + $grub_mkimage -O ${platform} -d "${source_directory}" -m "${memdisk_img}" -o "$3" --prefix='(memdisk)/boot/grub' \ + search iso9660 configfile normal sh memdisk tar $4 + rm -rf ${memdisk_img} +} + +if [ "${override_dir}" = "" ] ; then + if test -e "${multiboot_dir}" ; then + process_input_dir ${multiboot_dir} i386-multiboot + fi + if test -e "${coreboot_dir}" ; then + process_input_dir ${coreboot_dir} i386-coreboot + fi + if test -e "${qemu_dir}" ; then + process_input_dir ${qemu_dir} i386-qemu + fi + if test -e "${pc_dir}" ; then + process_input_dir ${pc_dir} i386-pc + fi + if test -e "${efi32_dir}" ; then + process_input_dir ${efi32_dir} i386-efi + fi + if test -e "${efi64_dir}" ; then + process_input_dir ${efi64_dir} x86_64-efi + fi +else + process_input_dir ${override_dir} ${target_cpu}-${native_platform} + multiboot_dir= + pc_dir= + efi32_dir= + efi64_dir= + coreboot_dir= + qemu_dir= + case "${target_cpu}-${native_platform}" in + i386-multiboot) multiboot_dir=${override_dir} ;; + i386-coreboot) coreboot_dir=${override_dir} ;; + i386-qemu) qemu_dir=${override_dir} ;; + i386-pc) pc_dir=${override_dir} ;; + i386-efi) efi32_dir=${override_dir} ;; + x86_64-efi) efi64_dir=${override_dir} ;; + esac fi +# obtain date-based UUID +iso_uuid=$(date -u +%Y-%m-%d-%H-%M-%S-00) +grub_mkisofs_arguments="${grub_mkisofs_arguments} --modification-date=$(echo ${iso_uuid} | sed -e s/-//g)" + # build BIOS core.img if test -e "${pc_dir}" ; then echo "Enabling BIOS support ..." core_img=`mktemp "$MKTEMP_TEMPLATE"` - grub-mkimage -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ + $grub_mkimage -O i386-pc -d ${pc_dir}/ -o ${core_img} --prefix=/boot/grub/i386-pc \ iso9660 biosdisk cat ${pc_dir}/cdboot.img ${core_img} > ${iso9660_dir}/boot/grub/i386-pc/eltorito.img @@ -191,8 +239,34 @@ if test -e "${pc_dir}" ; then --embedded-boot ${embed_img}" fi +# build multiboot core.img +make_image "${multiboot_dir}" i386-multiboot "${iso9660_dir}/boot/multiboot.img" "ata at_keyboard" + +if test -e "${efi64_dir}" || test -e "${efi32_dir}"; then + efi_dir=`mktemp -d "$MKTEMP_TEMPLATE"` + mkdir -p "${efi_dir}/efi/boot" + + # build bootx64.efi + make_image "${efi64_dir}" x86_64-efi "${efi_dir}"/efi/boot/bootx64.efi "" + # build bootia32.efi + make_image "${efi32_dir}" i386-efi "${efi_dir}"/efi/boot/bootia32.efi "" + + mformat -C -f 2880 -L 16 -i "${iso9660_dir}"/efi.img :: + mcopy -s -i "${iso9660_dir}"/efi.img ${efi_dir}/efi ::/ + grub_mkisofs_arguments="${grub_mkisofs_arguments} --efi-boot efi.img" +fi + +make_image "${qemu_dir}" i386-qemu "${iso9660_dir}/boot/qemu.img" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/qemu.img" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/qemu.img" "${rom_directory}/qemu.img" +fi +make_image "${coreboot_dir}" i386-coreboot "${iso9660_dir}/boot/coreboot.elf" "ata at_keyboard" +if [ -e "${iso9660_dir}/boot/coreboot.elf" ] && [ -d "${rom_directory}" ]; then + cp "${iso9660_dir}/boot/coreboot.elf" "${rom_directory}/coreboot.elf" +fi + # build iso image -grub-mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} +xorriso -pathspecs on -as mkisofs ${grub_mkisofs_arguments} --protective-msdos-label -o ${output_image} -r ${iso9660_dir} ${source} rm -rf ${iso9660_dir} rm -f ${embed_img} diff --git a/util/grub-probe.c b/util/grub-probe.c index bb41480e2..1f956efb7 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -20,14 +20,15 @@ #include #include #include +#include #include #include #include #include #include #include -#include -#include +#include +#include #include #include #include @@ -261,7 +262,7 @@ probe (const char *path, char *device_name) grub_util_info ("reading %s via OS facilities", path); filebuf_via_sys = grub_util_read_image (path); - rel_path = make_system_path_relative_to_its_root (path); + rel_path = grub_make_system_path_relative_to_its_root (path); grub_path = xasprintf ("(%s)%s", drive_name, rel_path); free (rel_path); grub_util_info ("reading %s via GRUB facilities", grub_path); diff --git a/util/grub-script-check.c b/util/grub-script-check.c index dc732aa01..3b7ab295d 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -70,7 +70,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd __attribute__ ((unused) } grub_err_t -grub_script_execute_cmdblock (struct grub_script_cmd *cmd __attribute__ ((unused))) +grub_script_execute_cmdlist (struct grub_script_cmd *cmd __attribute__ ((unused))) { return 0; } diff --git a/util/grub.d/10_hurd.in b/util/grub.d/10_hurd.in index 8e16e7d9f..e446f10e8 100644 --- a/util/grub.d/10_hurd.in +++ b/util/grub.d/10_hurd.in @@ -35,13 +35,13 @@ all_of_them=true # FIXME: add l4 here? kernel= -for i in /boot/gnumach.gz /boot/gnumach ; do +for i in /boot/gnumach* ; do if test -e $i ; then basename=`basename $i` dirname=`dirname $i` rel_dirname=`make_system_path_relative_to_its_root $dirname` echo "Found GNU Mach: $i" >&2 - kernel=${rel_dirname}/${basename} + kernels="${kernels} ${rel_dirname}/${basename}" at_least_one=true fi done @@ -71,17 +71,22 @@ if ${all_of_them} && test -e /lib/ld.so.1 ; then : ; else exit 1 fi -cat << EOF -menuentry "${OS}" ${CLASS} { +for kernel in ${kernels} +do + kernel_base="`basename "${kernel}"`" + KERNEL="using ${kernel_base}" + + cat << EOF +menuentry "${OS} ${KERNEL}" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -93,17 +98,17 @@ cat << EOF } EOF -cat << EOF -menuentry "${OS} (recovery mode)" { + cat << EOF +menuentry "${OS} ${KERNEL} (recovery mode)" ${CLASS} { EOF -prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" -cat << EOF + prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading GNU Mach ...")' multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} -s EOF -save_default_entry | sed -e "s/^/\t/" -prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" -cat << EOF + save_default_entry | sed -e "s/^/\t/" + prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" + cat << EOF echo '$(gettext_quoted "Loading the Hurd ...")' module /hurd/${hurd_fs}.static ${hurd_fs} \\ --multiboot-command-line='\${kernel-command-line}' \\ @@ -114,3 +119,5 @@ cat << EOF module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' } EOF + +done diff --git a/util/grub.d/10_windows.in b/util/grub.d/10_windows.in index 35dd4a4cc..7d221eac9 100644 --- a/util/grub.d/10_windows.in +++ b/util/grub.d/10_windows.in @@ -1,7 +1,7 @@ #! /bin/sh -e # grub-mkconfig helper script. -# Copyright (C) 2008 Free Software Foundation, Inc. +# Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. # # GRUB is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,8 +28,8 @@ esac # Try C: even if current system is on other partition. case "$SYSTEMDRIVE" in - [Cc]:) dirlist="C:" ;; - [D-Zd-z]:) dirlist="C: $SYSTEMDRIVE" ;; + [Cc]:) drives="C:" ;; + [D-Zd-z]:) drives="C: $SYSTEMDRIVE" ;; *) exit 0 ;; esac @@ -51,7 +51,13 @@ get_os_name_from_boot_ini () } -for dir in $dirlist ; do +for drv in $drives ; do + + # Convert to Cygwin path. + dir=`cygpath "$drv"` + test -n "$dir" || continue + + needmap= # Check for Vista bootmgr. if [ -f "$dir"/bootmgr -a -f "$dir"/boot/bcd ] ; then @@ -60,6 +66,7 @@ for dir in $dirlist ; do # Check for NTLDR. elif [ -f "$dir"/ntldr -a -f "$dir"/ntdetect.com -a -f "$dir"/boot.ini ] ; then OS=`get_os_name_from_boot_ini "$dir"/boot.ini` || OS="Windows NT/2000/XP loader" + needmap=t else continue @@ -68,14 +75,16 @@ for dir in $dirlist ; do # Get boot /dev/ice. dev=`${grub_probe} -t device "$dir" 2>/dev/null` || continue - echo "Found $OS on $dir ($dev)" >&2 + echo "Found $OS on $drv ($dev)" >&2 cat << EOF menuentry "$OS" { EOF save_default_entry | sed -e 's,^,\t,' prepare_grub_to_access_device "$dev" | sed 's,^,\t,' - + test -z "$needmap" || cat <. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "progname.h" - -#if GRUB_TARGET_WORDSIZE == 32 -# define grub_le_to_cpu(val) grub_le_to_cpu32(val) -#elif GRUB_TARGET_WORDSIZE == 64 -# define grub_le_to_cpu(val) grub_le_to_cpu64(val) -#endif - -static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; - -static inline Elf_Addr -align_address (Elf_Addr addr, unsigned alignment) -{ - return (addr + alignment - 1) & ~(alignment - 1); -} - -static inline Elf_Addr -align_pe32_section (Elf_Addr addr) -{ - return align_address (addr, GRUB_PE32_SECTION_ALIGNMENT); -} - -/* Read the whole kernel image. Return the pointer to a read image, - and store the size in bytes in *SIZE. */ -static char * -read_kernel_image (const char *dir, size_t *size) -{ - char *kernel_image; - char *kernel_path; - - kernel_path = grub_util_get_path (dir, "kernel.img"); - *size = grub_util_get_image_size (kernel_path); - kernel_image = grub_util_read_image (kernel_path); - free (kernel_path); - - return kernel_image; -} - -/* Return if the ELF header is valid. */ -static int -check_elf_header (Elf_Ehdr *e, size_t size) -{ - if (size < sizeof (*e) - || e->e_ident[EI_MAG0] != ELFMAG0 - || e->e_ident[EI_MAG1] != ELFMAG1 - || e->e_ident[EI_MAG2] != ELFMAG2 - || e->e_ident[EI_MAG3] != ELFMAG3 - || e->e_ident[EI_VERSION] != EV_CURRENT - || e->e_version != grub_cpu_to_le32 (EV_CURRENT) - || ((e->e_ident[EI_CLASS] != ELFCLASS32) && - (e->e_ident[EI_CLASS] != ELFCLASS64)) - || e->e_ident[EI_DATA] != ELFDATA2LSB - || ((e->e_machine != grub_cpu_to_le16 (EM_386)) && - (e->e_machine != grub_cpu_to_le16 (EM_X86_64)))) - return 0; - - return 1; -} - -/* Return the starting address right after the header, - aligned by the section alignment. Allocate 4 section tables for - .text, .data, .reloc, and mods. */ -static Elf_Addr -get_starting_section_address (void) -{ - return align_pe32_section (sizeof (struct grub_pe32_header) - + 4 * sizeof (struct grub_pe32_section_table)); -} - -/* Determine if this section is a text section. Return false if this - section is not allocated. */ -static int -is_text_section (Elf_Shdr *s) -{ - return ((s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)) - == grub_cpu_to_le32 (SHF_EXECINSTR | SHF_ALLOC)); -} - -/* Determine if this section is a data section. This assumes that - BSS is also a data section, since the converter initializes BSS - when producing PE32 to avoid a bug in EFI implementations. */ -static int -is_data_section (Elf_Shdr *s) -{ - return (s->sh_flags & grub_cpu_to_le32 (SHF_ALLOC) - && ! (s->sh_flags & grub_cpu_to_le32 (SHF_EXECINSTR))); -} - -/* Locate section addresses by merging code sections and data sections - into .text and .data, respectively. Return the array of section - addresses. */ -static Elf_Addr * -locate_sections (Elf_Shdr *sections, Elf_Half section_entsize, - Elf_Half num_sections, const char *strtab) -{ - int i; - Elf_Addr current_address; - Elf_Addr *section_addresses; - Elf_Shdr *s; - - section_addresses = xmalloc (sizeof (*section_addresses) * num_sections); - memset (section_addresses, 0, sizeof (*section_addresses) * num_sections); - - current_address = get_starting_section_address (); - - /* .text */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - current_address = align_pe32_section (current_address); - - /* .data */ - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - current_address = align_address (current_address, align); - - grub_util_info ("locating the section %s at 0x%x", - name, current_address); - section_addresses[i] = current_address; - current_address += grub_le_to_cpu32 (s->sh_size); - } - - return section_addresses; -} - -/* Return the symbol table section, if any. */ -static Elf_Shdr * -find_symtab_section (Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections) -{ - int i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (s->sh_type == grub_cpu_to_le32 (SHT_SYMTAB)) - return s; - - return 0; -} - -/* Return the address of the string table. */ -static const char * -find_strtab (Elf_Ehdr *e, Elf_Shdr *sections, Elf_Half section_entsize) -{ - Elf_Shdr *s; - char *strtab; - - s = (Elf_Shdr *) ((char *) sections - + grub_le_to_cpu16 (e->e_shstrndx) * section_entsize); - strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset); - return strtab; -} - -/* Relocate symbols; note that this function overwrites the symbol table. - Return the address of a start symbol. */ -static Elf_Addr -relocate_symbols (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Shdr *symtab_section, Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections) -{ - Elf_Word symtab_size, sym_size, num_syms; - Elf_Off symtab_offset; - Elf_Addr start_address = 0; - Elf_Sym *sym; - Elf_Word i; - Elf_Shdr *strtab_section; - const char *strtab; - - strtab_section - = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (symtab_section->sh_link) - * section_entsize)); - strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset); - - symtab_size = grub_le_to_cpu32 (symtab_section->sh_size); - sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize); - symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset); - num_syms = symtab_size / sym_size; - - for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); - i < num_syms; - i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) - { - Elf_Section index; - const char *name; - - name = strtab + grub_le_to_cpu32 (sym->st_name); - - index = grub_le_to_cpu16 (sym->st_shndx); - if (index == STN_ABS) - { - continue; - } - else if ((index == STN_UNDEF)) - { - if (sym->st_name) - grub_util_error ("undefined symbol %s", name); - else - continue; - } - else if (index >= num_sections) - grub_util_error ("section %d does not exist", index); - - sym->st_value = (grub_le_to_cpu32 (sym->st_value) - + section_addresses[index]); - grub_util_info ("locating %s at 0x%x", name, sym->st_value); - - if (! start_address) - if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) - start_address = sym->st_value; - } - - return start_address; -} - -/* Return the address of a symbol at the index I in the section S. */ -static Elf_Addr -get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i) -{ - Elf_Sym *sym; - - sym = (Elf_Sym *) ((char *) e - + grub_le_to_cpu32 (s->sh_offset) - + i * grub_le_to_cpu32 (s->sh_entsize)); - return sym->st_value; -} - -/* Return the address of a modified value. */ -static Elf_Addr * -get_target_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset) -{ - return (Elf_Addr *) ((char *) e + grub_le_to_cpu32 (s->sh_offset) + offset); -} - -/* Deal with relocation information. This function relocates addresses - within the virtual address space starting from 0. So only relative - addresses can be fully resolved. Absolute addresses must be relocated - again by a PE32 relocator when loaded. */ -static void -relocate_addresses (Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Addr *section_addresses, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rela *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Shdr *symtab_section; - Elf_Word target_section_index; - Elf_Addr target_section_addr; - Elf_Shdr *target_section; - Elf_Word j; - - symtab_section = (Elf_Shdr *) ((char *) sections - + (grub_le_to_cpu32 (s->sh_link) - * section_entsize)); - target_section_index = grub_le_to_cpu32 (s->sh_info); - target_section_addr = section_addresses[target_section_index]; - target_section = (Elf_Shdr *) ((char *) sections - + (target_section_index - * section_entsize)); - - grub_util_info ("dealing with the relocation section %s for %s", - strtab + grub_le_to_cpu32 (s->sh_name), - strtab + grub_le_to_cpu32 (target_section->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rela *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - Elf_Addr sym_addr; - Elf_Addr *target; - Elf_Addr addend; - - offset = grub_le_to_cpu (r->r_offset); - target = get_target_address (e, target_section, offset); - info = grub_le_to_cpu (r->r_info); - sym_addr = get_symbol_address (e, symtab_section, - ELF_R_SYM (info)); - - addend = (s->sh_type == grub_cpu_to_le32 (SHT_RELA)) ? - r->r_addend : 0; - - switch (ELF_R_TYPE (info)) - { -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - case R_386_NONE: - break; - - case R_386_32: - /* This is absolute. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - - case R_386_PC32: - /* This is relative. */ - *target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x", - *target, offset); - break; - -#else - - case R_X86_64_NONE: - break; - - case R_X86_64_64: - *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx", - *target, offset); - break; - - case R_X86_64_PC32: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr - - target_section_addr - offset); - grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - - case R_X86_64_32: - case R_X86_64_32S: - { - grub_uint32_t *t32 = (grub_uint32_t *) target; - *t32 = grub_cpu_to_le64 (grub_le_to_cpu32 (*t32) - + addend + sym_addr); - grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%llx", - *t32, offset); - break; - } - -#endif - default: - grub_util_error ("unknown relocation type %d", - ELF_R_TYPE (info)); - break; - } - } - } -} - -void -write_padding (FILE *out, size_t size) -{ - size_t i; - - for (i = 0; i < size; i++) - if (fputc (0, out) == EOF) - grub_util_error ("padding failed"); -} - -/* Add a PE32's fixup entry for a relocation. Return the resulting address - after having written to the file OUT. */ -Elf_Addr -add_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type, - Elf_Addr addr, int flush, Elf_Addr current_address, - FILE *out) -{ - struct grub_pe32_fixup_block *b = *block; - - /* First, check if it is necessary to write out the current block. */ - if (b) - { - if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr) - { - grub_uint32_t size; - - if (flush) - { - /* Add as much padding as necessary to align the address - with a section boundary. */ - Elf_Addr next_address; - unsigned padding_size; - size_t index; - - next_address = current_address + b->block_size; - padding_size = ((align_pe32_section (next_address) - - next_address) - >> 1); - index = ((b->block_size - sizeof (*b)) >> 1); - grub_util_info ("adding %d padding fixup entries", padding_size); - while (padding_size--) - { - b->entries[index++] = 0; - b->block_size += 2; - } - } - else if (b->block_size & (8 - 1)) - { - /* If not aligned with a 32-bit boundary, add - a padding entry. */ - size_t index; - - grub_util_info ("adding a padding fixup entry"); - index = ((b->block_size - sizeof (*b)) >> 1); - b->entries[index] = 0; - b->block_size += 2; - } - - /* Flush it. */ - grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", - b->block_size, b->page_rva); - size = b->block_size; - current_address += size; - b->page_rva = grub_cpu_to_le32 (b->page_rva); - b->block_size = grub_cpu_to_le32 (b->block_size); - if (fwrite (b, size, 1, out) != 1) - grub_util_error ("write failed"); - free (b); - *block = b = 0; - } - } - - if (! flush) - { - grub_uint16_t entry; - size_t index; - - /* If not allocated yet, allocate a block with enough entries. */ - if (! b) - { - *block = b = xmalloc (sizeof (*b) + 2 * 0x1000); - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ - b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - - /* Sanity check. */ - if (b->block_size >= sizeof (*b) + 2 * 0x1000) - grub_util_error ("too many fixup entries"); - - /* Add a new entry. */ - index = ((b->block_size - sizeof (*b)) >> 1); - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); - b->entries[index] = grub_cpu_to_le16 (entry); - b->block_size += 2; - } - - return current_address; -} - -/* Write out zeros to make space for the header. */ -static Elf_Addr -make_header_space (FILE *out) -{ - Elf_Addr addr; - - addr = get_starting_section_address (); - write_padding (out, addr); - - return addr; -} - -/* Write text sections. */ -static Elf_Addr -write_text_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the text section %s at 0x%x", - name, current_address); - - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write data sections. */ -static Elf_Addr -write_data_sections (FILE *out, Elf_Addr current_address, - Elf_Ehdr *e, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - Elf_Addr addr; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_data_section (s)) - { - Elf_Word align = grub_le_to_cpu32 (s->sh_addralign); - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - Elf_Word size = grub_le_to_cpu32 (s->sh_size); - const char *name = strtab + grub_le_to_cpu32 (s->sh_name); - - if (align) - { - addr = align_address (current_address, align); - if (current_address != addr) - { - grub_util_info ("padding %d bytes for the ELF section alignment", - addr - current_address); - write_padding (out, addr - current_address); - current_address = addr; - } - } - - grub_util_info ("writing the data section %s at 0x%x", - name, current_address); - - if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS)) - write_padding (out, size); - else - if (fwrite ((char *) e + offset, size, 1, out) != 1) - grub_util_error ("write failed"); - - current_address += size; - } - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Write modules. */ -static Elf_Addr -make_mods_section (FILE *out, Elf_Addr current_address, - const char *dir, char *mods[]) -{ - struct grub_util_path_list *path_list; - grub_size_t total_module_size; - struct grub_util_path_list *p; - struct grub_module_info modinfo; - Elf_Addr addr; - - memset (&modinfo, 0, sizeof (modinfo)); - - path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); - - total_module_size = sizeof (struct grub_module_info); - for (p = path_list; p; p = p->next) - { - total_module_size += (grub_util_get_image_size (p->name) - + sizeof (struct grub_module_header)); - } - - grub_util_info ("the total module size is 0x%x", total_module_size); - - modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC); - modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo)); - modinfo.size = grub_cpu_to_le32 (total_module_size); - - if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1) - grub_util_error ("write failed"); - - for (p = path_list; p; p = p->next) - { - struct grub_module_header header; - size_t mod_size; - char *mod_image; - - memset (&header, 0, sizeof (header)); - - grub_util_info ("adding module %s", p->name); - - mod_size = grub_util_get_image_size (p->name); - header.type = OBJ_TYPE_ELF; - header.size = grub_host_to_target32 (mod_size + sizeof (header)); - - mod_image = grub_util_read_image (p->name); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (mod_image, mod_size, 1, out) != 1) - grub_util_error ("write failed"); - - free (mod_image); - } - - for (p = path_list; p; ) - { - struct grub_util_path_list *q; - - q = p->next; - free (p); - p = q; - } - - current_address += total_module_size; - - addr = align_pe32_section (current_address); - if (addr != current_address) - { - grub_util_info ("padding %d bytes for the PE32 section alignment", - addr - current_address); - write_padding (out, addr - current_address); - } - - return addr; -} - -/* Make a .reloc section. */ -static Elf_Addr -make_reloc_section (FILE *out, Elf_Addr current_address, Elf_Ehdr *e, - Elf_Addr *section_addresses, Elf_Shdr *sections, - Elf_Half section_entsize, Elf_Half num_sections, - const char *strtab) -{ - Elf_Half i; - Elf_Shdr *s; - struct grub_pe32_fixup_block *fixup_block = 0; - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if ((s->sh_type == grub_cpu_to_le32 (SHT_REL)) || - (s->sh_type == grub_cpu_to_le32 (SHT_RELA))) - { - Elf_Rel *r; - Elf_Word rtab_size, r_size, num_rs; - Elf_Off rtab_offset; - Elf_Addr section_address; - Elf_Word j; - - grub_util_info ("translating the relocation section %s", - strtab + grub_le_to_cpu32 (s->sh_name)); - - rtab_size = grub_le_to_cpu32 (s->sh_size); - r_size = grub_le_to_cpu32 (s->sh_entsize); - rtab_offset = grub_le_to_cpu32 (s->sh_offset); - num_rs = rtab_size / r_size; - - section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)]; - - for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset); - j < num_rs; - j++, r = (Elf_Rel *) ((char *) r + r_size)) - { - Elf_Addr info; - Elf_Addr offset; - - offset = grub_le_to_cpu32 (r->r_offset); - info = grub_le_to_cpu32 (r->r_info); - - /* Necessary to relocate only absolute addresses. */ -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - if (ELF_R_TYPE (info) == R_386_32) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%x", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_HIGHLOW, - addr, 0, current_address, - out); - } -#else - if ((ELF_R_TYPE (info) == R_X86_64_32) || - (ELF_R_TYPE (info) == R_X86_64_32S)) - { - grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); - } - else if (ELF_R_TYPE (info) == R_X86_64_64) - { - Elf_Addr addr; - - addr = section_address + offset; - grub_util_info ("adding a relocation entry for 0x%llx", addr); - current_address = add_fixup_entry (&fixup_block, - GRUB_PE32_REL_BASED_DIR64, - addr, - 0, current_address, - out); - } -#endif - } - } - - current_address = add_fixup_entry (&fixup_block, 0, 0, 1, - current_address, out); - - return current_address; -} - -/* Create the header. */ -static void -make_header (FILE *out, Elf_Addr text_address, Elf_Addr data_address, - Elf_Addr mods_address, Elf_Addr reloc_address, - Elf_Addr end_address, Elf_Addr start_address) -{ - struct grub_pe32_header header; - struct grub_pe32_coff_header *c; - struct grub_pe32_optional_header *o; - struct grub_pe32_section_table text_section, data_section; - struct grub_pe32_section_table mods_section, reloc_section; - - /* The magic. */ - memset (&header, 0, sizeof (header)); - memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub)); - memcpy (header.signature, "PE\0\0", sizeof (header.signature)); - - /* The COFF file header. */ - c = &header.coff_header; -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386); -#else - c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_X86_64); -#endif - - c->num_sections = grub_cpu_to_le16 (4); - c->time = grub_cpu_to_le32 (time (0)); - c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header)); - c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE - | GRUB_PE32_LINE_NUMS_STRIPPED -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - | GRUB_PE32_32BIT_MACHINE -#endif - | GRUB_PE32_LOCAL_SYMS_STRIPPED - | GRUB_PE32_DEBUG_STRIPPED); - - /* The PE Optional header. */ - o = &header.optional_header; - o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC); - o->code_size = grub_cpu_to_le32 (data_address - text_address); - o->data_size = grub_cpu_to_le32 (reloc_address - data_address); - o->bss_size = 0; - o->entry_addr = grub_cpu_to_le32 (start_address); - o->code_base = grub_cpu_to_le32 (text_address); -#if GRUB_TARGET_SIZEOF_VOID_P == 4 - o->data_base = grub_cpu_to_le32 (data_address); -#endif - o->image_base = 0; - o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT); - o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT); - o->image_size = grub_cpu_to_le32 (end_address); - o->header_size = grub_cpu_to_le32 (text_address); - o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); - - /* Do these really matter? */ - o->stack_reserve_size = grub_cpu_to_le32 (0x10000); - o->stack_commit_size = grub_cpu_to_le32 (0x10000); - o->heap_reserve_size = grub_cpu_to_le32 (0x10000); - o->heap_commit_size = grub_cpu_to_le32 (0x10000); - - o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES); - - o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address); - o->base_relocation_table.size = grub_cpu_to_le32 (end_address - - reloc_address); - - /* The sections. */ - memset (&text_section, 0, sizeof (text_section)); - strcpy (text_section.name, ".text"); - text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address); - text_section.virtual_address = grub_cpu_to_le32 (text_address); - text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address); - text_section.raw_data_offset = grub_cpu_to_le32 (text_address); - text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE - | GRUB_PE32_SCN_MEM_EXECUTE - | GRUB_PE32_SCN_MEM_READ); - - memset (&data_section, 0, sizeof (data_section)); - strcpy (data_section.name, ".data"); - data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.virtual_address = grub_cpu_to_le32 (data_address); - data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address); - data_section.raw_data_offset = grub_cpu_to_le32 (data_address); - data_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&mods_section, 0, sizeof (mods_section)); - strcpy (mods_section.name, "mods"); - mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.virtual_address = grub_cpu_to_le32 (mods_address); - mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address); - mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address); - mods_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_READ - | GRUB_PE32_SCN_MEM_WRITE); - - memset (&reloc_section, 0, sizeof (reloc_section)); - strcpy (reloc_section.name, ".reloc"); - reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address); - reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address); - reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address); - reloc_section.characteristics - = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA - | GRUB_PE32_SCN_MEM_DISCARDABLE - | GRUB_PE32_SCN_MEM_READ); - - /* Write them out. */ - if (fseeko (out, 0, SEEK_SET) < 0) - grub_util_error ("seek failed"); - - if (fwrite (&header, sizeof (header), 1, out) != 1 - || fwrite (&text_section, sizeof (text_section), 1, out) != 1 - || fwrite (&data_section, sizeof (data_section), 1, out) != 1 - || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1 - || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1) - grub_util_error ("write failed"); -} - -/* Convert an ELF relocatable object into an EFI Application (PE32). */ -void -convert_elf (const char *dir, char *prefix, FILE *out, char *mods[]) -{ - char *kernel_image; - size_t kernel_size; - const char *strtab; - Elf_Ehdr *e; - Elf_Shdr *sections; - Elf_Off section_offset; - Elf_Half section_entsize; - Elf_Half num_sections; - Elf_Addr *section_addresses; - Elf_Shdr *symtab_section; - Elf_Addr start_address; - Elf_Addr text_address, data_address, reloc_address, mods_address; - Elf_Addr end_address; - Elf_Shdr *s; - int i; - - /* Get the kernel image and check the format. */ - kernel_image = read_kernel_image (dir, &kernel_size); - e = (Elf_Ehdr *) kernel_image; - if (! check_elf_header (e, kernel_size)) - grub_util_error ("invalid ELF header"); - - section_offset = grub_cpu_to_le32 (e->e_shoff); - section_entsize = grub_cpu_to_le16 (e->e_shentsize); - num_sections = grub_cpu_to_le16 (e->e_shnum); - - if (kernel_size < section_offset + section_entsize * num_sections) - grub_util_error ("invalid ELF format"); - - sections = (Elf_Shdr *) (kernel_image + section_offset); - strtab = find_strtab (e, sections, section_entsize); - - for (i = 0, s = sections; - i < num_sections; - i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) - if (is_text_section (s)) - { - Elf_Off offset = grub_le_to_cpu32 (s->sh_offset); - - if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END) - grub_util_error ("prefix too long"); - - strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix); - break; - } - - /* Relocate sections then symbols in the virtual address space. */ - section_addresses = locate_sections (sections, section_entsize, - num_sections, strtab); - - symtab_section = find_symtab_section (sections, - section_entsize, num_sections); - if (! symtab_section) - grub_util_error ("no symbol table"); - - start_address = relocate_symbols (e, sections, symtab_section, - section_addresses, section_entsize, - num_sections); - if (start_address == 0) - grub_util_error ("start symbol is not defined"); - - /* Resolve addresses in the virtual address space. */ - relocate_addresses (e, sections, section_addresses, section_entsize, - num_sections, strtab); - - /* Generate a PE32 image file. The strategy is to dump binary data first, - then fill up the header. */ - text_address = make_header_space (out); - data_address = write_text_sections (out, text_address, e, sections, - section_entsize, num_sections, - strtab); - mods_address = write_data_sections (out, data_address, e, sections, - section_entsize, num_sections, - strtab); - reloc_address = make_mods_section (out, mods_address, dir, mods); - end_address = make_reloc_section (out, reloc_address, e, section_addresses, - sections, section_entsize, num_sections, - strtab); - make_header (out, text_address, data_address, mods_address, - reloc_address, end_address, start_address); - - /* Clean up. */ - free (section_addresses); - free (kernel_image); -} - -static struct option options[] = - { - {"directory", required_argument, 0, 'd'}, - {"prefix", required_argument, 0, 'p'}, - {"output", required_argument, 0, 'o'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {"verbose", no_argument, 0, 'v'}, - { 0, 0, 0, 0 } - }; - -static void -usage (int status) -{ - if (status) - fprintf (stderr, "Try `%s --help' for more information.\n", program_name); - else - printf ("\ -Usage: %s -o FILE [OPTION]... [MODULES]\n\ -\n\ -Make a bootable image of GRUB.\n\ -\n\ - -d, --directory=DIR use images and modules under DIR [default=%s]\n\ - -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ - -o, --output=FILE output a generated image to FILE\n\ - -h, --help display this message and exit\n\ - -V, --version print version information and exit\n\ - -v, --verbose print verbose messages\n\ -\n\ -Report bugs to <%s>.\n\ -", program_name, GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT); - - exit (status); -} - -int -main (int argc, char *argv[]) -{ - FILE *fp; - char *output = NULL; - char *dir = NULL; - char *prefix = NULL; - - program_name = "grub-mkimage"; - - while (1) - { - int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0); - if (c == -1) - break; - - switch (c) - { - case 'd': - if (dir) - free (dir); - dir = xstrdup (optarg); - break; - case 'h': - usage (0); - break; - case 'o': - if (output) - free (output); - output = xstrdup (optarg); - break; - case 'p': - if (prefix) - free (prefix); - prefix = xstrdup (optarg); - break; - case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); - return 0; - case 'v': - verbosity++; - break; - default: - usage (1); - break; - } - } - - if (! output) - usage (1); - - fp = fopen (output, "wb"); - if (! fp) - grub_util_error ("cannot open %s", output); - - convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind); - - fclose (fp); - - return 0; -} diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..6e6b2e878 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -28,14 +28,14 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include +#include static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT; @@ -57,6 +57,13 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) + void grub_putchar (int c) { @@ -423,7 +430,7 @@ unable_to_embed: /* Make sure that GRUB reads the identical image as the OS. */ tmp_img = xmalloc (core_size); core_path_dev_full = grub_util_get_path (dir, core_file); - core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full); + core_path_dev = grub_make_system_path_relative_to_its_root (core_path_dev_full); free (core_path_dev_full); /* It is a Good Thing to sync two times. */ diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 363f312db..4d00cc217 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,7 +34,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` @@ -189,7 +189,7 @@ devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_ma modules="$modules $fs_module $partmap_module $devabstraction_module" # Now perform the installation. -"$grub_mkimage" --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 +"$grub_mkimage" -O ${target_cpu}-ieee1275 --directory=${pkglibdir} --output=${grubdir}/grub $modules || exit 1 if test $update_nvram = yes; then set $ofpathname dummy diff --git a/util/misc.c b/util/misc.c index 17fa6d5e4..46e5c6093 100644 --- a/util/misc.c +++ b/util/misc.c @@ -58,53 +58,6 @@ #include #endif -int verbosity = 0; - -void -grub_util_warn (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: warn:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); -} - -void -grub_util_info (const char *fmt, ...) -{ - if (verbosity > 0) - { - va_list ap; - - fprintf (stderr, _("%s: info:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - fflush (stderr); - } -} - -void -grub_util_error (const char *fmt, ...) -{ - va_list ap; - - fprintf (stderr, _("%s: error:"), program_name); - fprintf (stderr, " "); - va_start (ap, fmt); - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); - exit (1); -} - #ifdef GRUB_UTIL int grub_err_printf (const char *fmt, ...) @@ -120,41 +73,6 @@ grub_err_printf (const char *fmt, ...) } #endif -void * -xmalloc (size_t size) -{ - void *p; - - p = malloc (size); - if (! p) - grub_util_error ("out of memory"); - - return p; -} - -void * -xrealloc (void *ptr, size_t size) -{ - ptr = realloc (ptr, size); - if (! ptr) - grub_util_error ("out of memory"); - - return ptr; -} - -char * -xstrdup (const char *str) -{ - size_t len; - char *newstr; - - len = strlen (str); - newstr = (char *) xmalloc (len + 1); - memcpy (newstr, str, len + 1); - - return newstr; -} - char * grub_util_get_path (const char *dir, const char *file) { @@ -277,34 +195,6 @@ grub_register_exported_symbols (void) } #endif -void -grub_exit (void) -{ - exit (1); -} - -grub_uint32_t -grub_get_rtc (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - return (tv.tv_sec * GRUB_TICKS_PER_SECOND - + (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec) - * GRUB_TICKS_PER_SECOND / 1000000)); -} - -grub_uint64_t -grub_get_time_ms (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - return (tv.tv_sec * 1000 + tv.tv_usec / 1000); -} - #ifdef __MINGW32__ void @@ -335,53 +225,6 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), } #endif -#ifndef HAVE_VASPRINTF - -int -vasprintf (char **buf, const char *fmt, va_list ap) -{ - /* Should be large enough. */ - *buf = xmalloc (512); - - return vsprintf (*buf, fmt, ap); -} - -#endif - -#ifndef HAVE_ASPRINTF - -int -asprintf (char **buf, const char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (*buf, fmt, ap); - va_end (ap); - - return status; -} - -#endif - -char * -xasprintf (const char *fmt, ...) -{ - va_list ap; - char *result; - - va_start (ap, fmt); - if (vasprintf (&result, fmt, ap) < 0) - { - if (errno == ENOMEM) - grub_util_error ("out of memory"); - return NULL; - } - - return result; -} - #ifdef __MINGW32__ void sync (void) @@ -443,116 +286,6 @@ fail: #endif /* __MINGW32__ */ -char * -canonicalize_file_name (const char *path) -{ - char *ret; -#ifdef PATH_MAX - ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); -#else - ret = realpath (path, NULL); -#endif - return ret; -} - -/* This function never prints trailing slashes (so that its output - can be appended a slash unconditionally). */ -char * -make_system_path_relative_to_its_root (const char *path) -{ - struct stat st; - char *p, *buf, *buf2, *buf3; - uintptr_t offset = 0; - dev_t num; - size_t len; - - /* canonicalize. */ - p = canonicalize_file_name (path); - - if (p == NULL) - grub_util_error ("failed to get canonical path of %s", path); - - len = strlen (p) + 1; - buf = xstrdup (p); - free (p); - - if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); - - buf2 = xstrdup (buf); - num = st.st_dev; - - /* This loop sets offset to the number of chars of the root - directory we're inspecting. */ - while (1) - { - p = strrchr (buf, '/'); - if (p == NULL) - /* This should never happen. */ - grub_util_error ("FIXME: no / in buf. (make_system_path_relative_to_its_root)"); - if (p != buf) - *p = 0; - else - *++p = 0; - - if (stat (buf, &st) < 0) - grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); - - /* buf is another filesystem; we found it. */ - if (st.st_dev != num) - { - /* offset == 0 means path given is the mount point. - This works around special-casing of "/" in Un*x. This function never - prints trailing slashes (so that its output can be appended a slash - unconditionally). Each slash in is considered a preceding slash, and - therefore the root directory is an empty string. */ - if (offset == 0) - { - free (buf); - free (buf2); - return xstrdup (""); - } - else - break; - } - - offset = p - buf; - /* offset == 1 means root directory. */ - if (offset == 1) - { - free (buf); - len = strlen (buf2); - while (buf2[len - 1] == '/' && len > 1) - { - buf2[len - 1] = '\0'; - len--; - } - if (len > 1) - return buf2; - else - { - /* This means path given is just a backslash. As above - we have to return an empty string. */ - free (buf2); - return xstrdup (""); - } - } - } - free (buf); - buf3 = xstrdup (buf2 + offset); - free (buf2); - - len = strlen (buf3); - while (buf3[len - 1] == '/' && len > 1) - { - buf3[len - 1] = '\0'; - len--; - } - - return buf3; -} - #ifdef GRUB_UTIL void grub_util_init_nls (void) @@ -564,3 +297,17 @@ grub_util_init_nls (void) #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ } #endif + +int +grub_dl_ref (grub_dl_t mod) +{ + (void) mod; + return 0; +} + +int +grub_dl_unref (grub_dl_t mod) +{ + (void) mod; + return 0; +} diff --git a/util/mkisofs/defaults.h b/util/mkisofs/defaults.h deleted file mode 100644 index 2ce9e8d6b..000000000 --- a/util/mkisofs/defaults.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Header file defaults.h - assorted default values for character strings in - * the volume descriptor. - * - * $Id: defaults.h,v 1.8 1999/03/02 03:41:25 eric Exp $ - */ - -#define PREPARER_DEFAULT NULL -#define PUBLISHER_DEFAULT NULL -#ifndef APPID_DEFAULT -#define APPID_DEFAULT PACKAGE_NAME " ISO 9660 filesystem builder" -#endif -#define COPYRIGHT_DEFAULT NULL -#define BIBLIO_DEFAULT NULL -#define ABSTRACT_DEFAULT NULL -#define VOLSET_ID_DEFAULT NULL -#define VOLUME_ID_DEFAULT "CDROM" -#define BOOT_CATALOG_DEFAULT "boot.catalog" -#define BOOT_IMAGE_DEFAULT NULL -#define SYSTEM_ID_DEFAULT "GNU" diff --git a/util/mkisofs/eltorito.c b/util/mkisofs/eltorito.c deleted file mode 100644 index 1d2a715e0..000000000 --- a/util/mkisofs/eltorito.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Program eltorito.c - Handle El Torito specific extensions to iso9660. - * - - Written by Michael Fulbright (1996). - - Copyright 1996 RedHat Software, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - Boot Info Table generation based on code from genisoimage.c - (from cdrkit 1.1.9), which was originally licensed under GPLv2+. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -/* used by Win32 for opening binary file - not used by Unix */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif /* O_BINARY */ - -#undef MIN -#define MIN(a, b) (((a) < (b))? (a): (b)) - -static struct eltorito_validation_entry valid_desc; -static struct eltorito_defaultboot_entry default_desc; -static struct eltorito_boot_descriptor gboot_desc; - -static int tvd_write __PR((FILE * outfile)); - -/* - * Check for presence of boot catalog. If it does not exist then make it - */ -void FDECL1(init_boot_catalog, const char *, path) -{ - FILE *bcat; - char * bootpath; /* filename of boot catalog */ - char * buf; - struct stat statbuf; - - bootpath = (char *) e_malloc(strlen(boot_catalog)+strlen(path)+2); - strcpy(bootpath, path); - if (bootpath[strlen(bootpath)-1] != '/') - { - strcat(bootpath,"/"); - } - - strcat(bootpath, boot_catalog); - - /* - * check for the file existing - */ -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for boot catalog file %s\n",bootpath); -#endif - - if (!stat_filter(bootpath, &statbuf)) - { - /* - * make sure its big enough to hold what we want - */ - if (statbuf.st_size == 2048) - { - /* - * printf("Boot catalog exists, so we do nothing\n"); - */ - free(bootpath); - return; - } - else - { - fprintf (stderr, _("A boot catalog exists and appears corrupted.\n")); - fprintf (stderr, _("Please check the following file: %s.\n"), bootpath); - fprintf (stderr, _("This file must be removed before a bootable CD can be done.\n")); - free (bootpath); - exit (1); - } - } - - /* - * file does not exist, so we create it - * make it one CD sector long - */ - bcat = fopen (bootpath, "wb"); - if (bcat == NULL) - error (1, errno, _("Error creating boot catalog (%s)"), bootpath); - - buf = (char *) e_malloc( 2048 ); - if (fwrite (buf, 1, 2048, bcat) != 2048) - error (1, errno, _("Error writing to boot catalog (%s)"), bootpath); - fclose (bcat); - chmod (bootpath, S_IROTH | S_IRGRP | S_IRWXU); - - free(bootpath); -} /* init_boot_catalog(... */ - -void FDECL1(get_torito_desc, struct eltorito_boot_descriptor *, boot_desc) -{ - FILE *bootcat; - int checksum; - unsigned char * checksum_ptr; - struct directory_entry * de; - struct directory_entry * de2; - unsigned int i; - int nsectors; - - memset(boot_desc, 0, sizeof(*boot_desc)); - boot_desc->id[0] = 0; - memcpy(boot_desc->id2, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - boot_desc->version[0] = 1; - - memcpy(boot_desc->system_id, EL_TORITO_ID, sizeof(EL_TORITO_ID)); - - /* - * search from root of iso fs to find boot catalog - */ - de2 = search_tree_file(root, boot_catalog); - if (!de2) - { - fprintf (stderr, _("Boot catalog cannot be found!\n")); - exit (1); - } - - set_731(boot_desc->bootcat_ptr, - (unsigned int) get_733(de2->isorec.extent)); - - /* - * now adjust boot catalog - * lets find boot image first - */ - de=search_tree_file(root, boot_image); - if (!de) - { - fprintf (stderr, _("Boot image cannot be found!\n")); - exit (1); - } - - /* - * we have the boot image, so write boot catalog information - * Next we write out the primary descriptor for the disc - */ - memset(&valid_desc, 0, sizeof(valid_desc)); - valid_desc.headerid[0] = 1; - valid_desc.arch[0] = EL_TORITO_ARCH_x86; - - /* - * we'll shove start of publisher id into id field, may get truncated - * but who really reads this stuff! - */ - if (publisher) - memcpy_max(valid_desc.id, publisher, MIN(23, strlen(publisher))); - - valid_desc.key1[0] = 0x55; - valid_desc.key2[0] = 0xAA; - - /* - * compute the checksum - */ - checksum=0; - checksum_ptr = (unsigned char *) &valid_desc; - for (i=0; isize + 511) & ~(511))/512; - fprintf (stderr, _("\nSize of boot image is %d sectors"), nsectors); - fprintf (stderr, " -> "); - - if (! use_eltorito_emul_floppy) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_NOEMUL; - fprintf (stderr, _("No emulation\n")); - } - else if (nsectors == 2880 ) - /* - * choose size of emulated floppy based on boot image size - */ - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_144FLOP; - fprintf (stderr, _("Emulating a 1.44 meg floppy\n")); - } - else if (nsectors == 5760 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_288FLOP; - fprintf (stderr, _("Emulating a 2.88 meg floppy\n")); - } - else if (nsectors == 2400 ) - { - default_desc.boot_media[0] = EL_TORITO_MEDIA_12FLOP; - fprintf (stderr, _("Emulating a 1.2 meg floppy\n")); - } - else - { - fprintf (stderr, _("\nError - boot image is not the an allowable size.\n")); - exit (1); - } - - /* - * FOR NOW LOAD 1 SECTOR, JUST LIKE FLOPPY BOOT!!! - */ - nsectors = 1; - set_721(default_desc.nsect, (unsigned int) nsectors ); -#ifdef DEBUG_TORITO - fprintf(stderr,"Extent of boot images is %d\n",get_733(de->isorec.extent)); -#endif - set_731(default_desc.bootoff, - (unsigned int) get_733(de->isorec.extent)); - - /* - * now write it to disk - */ - bootcat = fopen (de2->whole_name, "r+b"); - if (bootcat == NULL) - error (1, errno, _("Error opening boot catalog for update")); - - /* - * write out - */ - if (fwrite (&valid_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - if (fwrite (&default_desc, 1, 32, bootcat) != 32) - error (1, errno, _("Error writing to boot catalog")); - fclose (bootcat); - - /* If the user has asked for it, patch the boot image */ - if (use_boot_info_table) - { - FILE *bootimage; - uint32_t bi_checksum; - unsigned int total_len; - static char csum_buffer[SECTOR_SIZE]; - int len; - struct eltorito_boot_info bi_table; - bootimage = fopen (de->whole_name, "r+b"); - if (bootimage == NULL) - error (1, errno, _("Error opening boot image file `%s' for update"), - de->whole_name); - /* Compute checksum of boot image, sans 64 bytes */ - total_len = 0; - bi_checksum = 0; - while ((len = fread (csum_buffer, 1, SECTOR_SIZE, bootimage)) > 0) - { - if (total_len & 3) - error (1, 0, _("Odd alignment at non-end-of-file in boot image `%s'"), - de->whole_name); - if (total_len < 64) - memset (csum_buffer, 0, 64 - total_len); - if (len < SECTOR_SIZE) - memset (csum_buffer + len, 0, SECTOR_SIZE - len); - for (i = 0; i < SECTOR_SIZE; i += 4) - bi_checksum += get_731 (&csum_buffer[i]); - total_len += len; - } - - if (total_len != de->size) - error (1, 0, _("Boot image file `%s' changed unexpectedly"), - de->whole_name); - /* End of file, set position to byte 8 */ - fseeko (bootimage, (off_t) 8, SEEK_SET); - memset (&bi_table, 0, sizeof (bi_table)); - /* Is it always safe to assume PVD is at session_start+16? */ - set_731 (bi_table.pvd_addr, session_start + 16); - set_731 (bi_table.file_addr, de->starting_block); - set_731 (bi_table.file_length, de->size); - set_731 (bi_table.file_checksum, bi_checksum); - - if (fwrite (&bi_table, 1, sizeof (bi_table), bootimage) != sizeof (bi_table)) - error (1, errno, _("Error writing to boot image (%s)"), bootimage); - fclose (bootimage); - } - -} /* get_torito_desc(... */ - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(tvd_write, FILE *, outfile) -{ - /* - * Next we write out the boot volume descriptor for the disc - */ - get_torito_desc(&gboot_desc); - xfwrite(&gboot_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -struct output_fragment torito_desc = {NULL, oneblock_size, NULL, tvd_write}; diff --git a/util/mkisofs/exclude.h b/util/mkisofs/exclude.h deleted file mode 100644 index ac1a561ad..000000000 --- a/util/mkisofs/exclude.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * 9-Dec-93 R.-D. Marzusch, marzusch@odiehh.hanse.de: - * added 'exclude' option (-x) to specify pathnames NOT to be included in - * CD image. - * - * $Id: exclude.h,v 1.2 1999/03/02 03:41:25 eric Exp $ - */ - -void exclude __PR((char * fn)); -int is_excluded __PR((char * fn)); diff --git a/util/mkisofs/hash.c b/util/mkisofs/hash.c deleted file mode 100644 index 41e76b342..000000000 --- a/util/mkisofs/hash.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * File hash.c - generate hash tables for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - This program 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 2, or (at your option) - any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include "config.h" -#include "mkisofs.h" - -#define NR_HASH 1024 - -#define HASH_FN(DEV, INO) ((DEV + INO + (INO >> 2) + (INO << 8)) % NR_HASH) - -static struct file_hash * hash_table[NR_HASH] = {0,}; - -void FDECL1(add_hash, struct directory_entry *, spnt){ - struct file_hash * s_hash; - unsigned int hash_number; - - if(spnt->size == 0 || spnt->starting_block == 0) - if(spnt->size != 0 || spnt->starting_block != 0) { - fprintf(stderr,"Non zero-length file assigned zero extent.\n"); - exit(1); - }; - - if (spnt->dev == (dev_t) UNCACHED_DEVICE || spnt->inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) spnt->dev, (unsigned int) spnt->inode); - -#if 0 - if (verbose > 1) fprintf(stderr,"%s ",spnt->name); -#endif - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = hash_table[hash_number]; - s_hash->inode = spnt->inode; - s_hash->dev = spnt->dev; - s_hash->starting_block = spnt->starting_block; - s_hash->size = spnt->size; - hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - - -static struct file_hash * directory_hash_table[NR_HASH] = {0,}; - -void FDECL2(add_directory_hash, dev_t, dev, ino_t, inode){ - struct file_hash * s_hash; - unsigned int hash_number; - - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - - s_hash = (struct file_hash *) e_malloc(sizeof(struct file_hash)); - s_hash->next = directory_hash_table[hash_number]; - s_hash->inode = inode; - s_hash->dev = dev; - directory_hash_table[hash_number] = s_hash; -} - -struct file_hash * FDECL2(find_directory_hash, dev_t, dev, ino_t, inode){ - unsigned int hash_number; - struct file_hash * spnt; - hash_number = HASH_FN((unsigned int) dev, (unsigned int) inode); - if (dev == (dev_t) UNCACHED_DEVICE || inode == UNCACHED_INODE) return NULL; - - spnt = directory_hash_table[hash_number]; - while(spnt){ - if(spnt->inode == inode && spnt->dev == dev) return spnt; - spnt = spnt->next; - }; - return NULL; -} - -struct name_hash -{ - struct name_hash * next; - struct directory_entry * de; -}; - -#define NR_NAME_HASH 128 - -static struct name_hash * name_hash_table[NR_NAME_HASH] = {0,}; - -/* - * Find the hash bucket for this name. - */ -static unsigned int FDECL1(name_hash, const char *, name) -{ - unsigned int hash = 0; - const char * p; - - p = name; - - while (*p) - { - /* - * Don't hash the iso9660 version number. This way - * we can detect duplicates in cases where we have - * directories (i.e. foo) and non-directories - * (i.e. foo;1). - */ - if( *p == ';' ) - { - break; - } - hash = (hash << 15) + (hash << 3) + (hash >> 3) + *p++; - } - return hash % NR_NAME_HASH; -} - -void FDECL1(add_file_hash, struct directory_entry *, de){ - struct name_hash * new; - int hash; - - new = (struct name_hash *) e_malloc(sizeof(struct name_hash)); - new->de = de; - new->next = NULL; - hash = name_hash(de->isorec.name); - - /* Now insert into the hash table */ - new->next = name_hash_table[hash]; - name_hash_table[hash] = new; -} - -struct directory_entry * FDECL1(find_file_hash, char *, name) -{ - struct name_hash * nh; - char * p1; - char * p2; - - for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next) - { - p1 = name; - p2 = nh->de->isorec.name; - - /* - * Look for end of string, or a mismatch. - */ - while(1==1) - { - if( (*p1 == '\0' || *p1 == ';') - || (*p2 == '\0' || *p2 == ';') - || (*p1 != *p2) ) - { - break; - } - p1++; - p2++; - } - - /* - * If we are at the end of both strings, then - * we have a match. - */ - if( (*p1 == '\0' || *p1 == ';') - && (*p2 == '\0' || *p2 == ';') ) - { - return nh->de; - } - } - return NULL; -} - -int FDECL1(delete_file_hash, struct directory_entry *, de){ - struct name_hash * nh, *prev; - int hash; - - prev = NULL; - hash = name_hash(de->isorec.name); - for(nh = name_hash_table[hash]; nh; nh = nh->next) { - if(nh->de == de) break; - prev = nh; - } - if(!nh) return 1; - if(!prev) - name_hash_table[hash] = nh->next; - else - prev->next = nh->next; - free(nh); - return 0; -} - -void flush_file_hash(){ - struct name_hash * nh, *nh1; - int i; - - for(i=0; inext; - free(nh); - nh = nh1; - } - name_hash_table[i] = NULL; - - } -} diff --git a/util/mkisofs/include/fctldefs.h b/util/mkisofs/include/fctldefs.h deleted file mode 100644 index de6b6a394..000000000 --- a/util/mkisofs/include/fctldefs.h +++ /dev/null @@ -1,57 +0,0 @@ -/* @(#)fctldefs.h 1.2 98/10/08 Copyright 1996 J. Schilling */ -/* - * Generic header for users of open(), creat() and chmod() - * - * Copyright (c) 1996 J. Schilling - */ -/* - * This program 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 2, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _FCTLDEFS_H -#define _FCTLDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#include -#include - -#ifdef HAVE_FCNTL_H - -# include - -#else /* HAVE_FCNTL_H */ - -# include - -#endif /* HAVE_FCNTL_H */ - -/* - * Do not define more than O_RDONLY / O_WRONLY / O_RDWR - * The values may differ. - */ -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#endif /* _FCTLDEFS_H */ diff --git a/util/mkisofs/include/mconfig.h b/util/mkisofs/include/mconfig.h deleted file mode 100644 index 1891d7ded..000000000 --- a/util/mkisofs/include/mconfig.h +++ /dev/null @@ -1,253 +0,0 @@ -/* @(#)mconfig.h 1.24 98/12/14 Copyright 1995 J. Schilling */ -/* - * definitions for machine configuration - * - * Copyright (c) 1995 J. Schilling - * - * This file must be included before any other file. - * Use only cpp instructions. - * - * NOTE: SING: (Schily Is Not Gnu) - */ -/* - * This program 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 2, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MCONFIG_H -#define _MCONFIG_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(unix) || defined(__unix) || defined(__unix__) -# define IS_UNIX -#endif - -#ifdef __MSDOS__ -# define IS_MSDOS -#endif - -#if defined(tos) || defined(__tos) -# define IS_TOS -#endif - -#ifdef THINK_C -# define IS_MAC -#endif - -#if defined(sun) || defined(__sun) || defined(__sun__) -# define IS_SUN -#endif - -#if defined(__CYGWIN32__) -# define IS_GCC_WIN32 -#endif - -/*--------------------------------------------------------------------------*/ -/* - * Some magic that cannot (yet) be figured out with autoconf. - */ - -#ifdef sparc -# ifndef HAVE_LDSTUB -# define HAVE_LDSTUB -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif -#if defined(__i386_) || defined(i386) -# ifndef HAVE_XCHG -# define HAVE_XCHG -# endif -# ifndef HAVE_SCANSTACK -# define HAVE_SCANSTACK -# endif -#endif - -#if defined(SOL2) || defined(SOL2) || defined(S5R4) || defined(__S5R4) \ - || defined(SVR4) -# ifndef __SVR4 -# define __SVR4 -# endif -#endif - -#ifdef __SVR4 -# ifndef SVR4 -# define SVR4 -# endif -#endif - -/* - * SunOS 4.x / SunOS 5.x - */ -#if defined(IS_SUN) -# define HAVE_GETAV0 -#endif - -/* - * AIX - */ -#if defined(_IBMR2) || defined(_AIX) -# define IS_UNIX /* ??? really ??? */ -#endif - -/* - * Silicon Graphics (must be before SVR4) - */ -#if defined(sgi) || defined(__sgi) -# define __NOT_SVR4__ /* Not a real SVR4 implementation */ -#endif - -/* - * Data General - */ -#if defined(__DGUX__) -#ifdef XXXXXXX -# undef HAVE_MTGET_DSREG -# undef HAVE_MTGET_RESID -# undef HAVE_MTGET_FILENO -# undef HAVE_MTGET_BLKNO -#endif -# define mt_type mt_model -# define mt_dsreg mt_status1 -# define mt_erreg mt_status2 - /* - * DGUX hides its flock as dg_flock. - */ -# define HAVE_FLOCK -# define flock dg_flock - /* - * Use the BSD style wait on DGUX to get the resource usages of child - * processes. - */ -# define _BSD_WAIT_FLAVOR -#endif - -/* - * Apple Rhapsody - */ -#if defined(__NeXT__) && defined(__TARGET_OSNAME) && __TARGET_OSNAME == rhapsody -# define HAVE_OSDEF /* prevent later definitions to overwrite current */ -#endif - -/* - * NextStep - */ -#if defined(__NeXT__) && !defined(HAVE_OSDEF) -#define NO_PRINT_OVR -#undef HAVE_USG_STDIO /* - * NeXT Step 3.x uses __flsbuf(unsigned char , FILE *) - * instead of __flsbuf(int, FILE *) - */ -#endif - -/* - * NextStep 3.x has a broken linker that does not allow us to override - * these functions. - */ -#ifndef __OPRINTF__ - -#ifdef NO_PRINT_OVR -# define printf Xprintf -# define fprintf Xfprintf -# define sprintf Xsprintf -#endif - -#endif /* __OPRINTF__ */ - -/*--------------------------------------------------------------------------*/ -/* - * If there is no flock defined by the system, use emulation - * through fcntl record locking. - */ -#ifndef HAVE_FLOCK -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* don't block when locking */ -#define LOCK_UN 8 /* unlock */ -#endif - -#include - -/* - * gcc 2.x generally implements the long long type. - */ -#ifdef __GNUC__ -# if __GNUC__ > 1 -# ifndef HAVE_LONGLONG -# define HAVE_LONGLONG -# endif -# endif -#endif - -/* - * Convert to GNU name - */ -#ifdef HAVE_STDC_HEADERS -# ifndef STDC_HEADERS -# define STDC_HEADERS -# endif -#endif -/* - * Convert to SCHILY name - */ -#ifdef STDC_HEADERS -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -#endif - -#ifdef IS_UNIX -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_GCC_WIN32 -# define PATH_DELIM '/' -# define PATH_DELIM_STR "/" -# define far -# define near -#endif - -#ifdef IS_MSDOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -#endif - -#ifdef IS_TOS -# define PATH_DELIM '\\' -# define PATH_DELIM_STR "\\" -# define far -# define near -#endif - -#ifdef IS_MAC -# define PATH_DELIM ':' -# define PATH_DELIM_STR ":" -# define far -# define near -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _MCONFIG_H */ diff --git a/util/mkisofs/include/prototyp.h b/util/mkisofs/include/prototyp.h deleted file mode 100644 index c74ae0af8..000000000 --- a/util/mkisofs/include/prototyp.h +++ /dev/null @@ -1,74 +0,0 @@ -/* @(#)prototyp.h 1.7 98/10/08 Copyright 1995 J. Schilling */ -/* - * Definitions for dealing with ANSI / KR C-Compilers - * - * Copyright (c) 1995 J. Schilling - */ -/* - * This program 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 2, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _PROTOTYP_H -#define _PROTOTYP_H - -#ifndef PROTOTYPES - /* - * If this has already been defined, - * someone else knows better than us... - */ -# ifdef __STDC__ -# if __STDC__ /* ANSI C */ -# define PROTOTYPES -# endif -# if defined(sun) && __STDC__ - 0 == 0 /* Sun C */ -# define PROTOTYPES -# endif -# endif -#endif /* PROTOTYPES */ - -/* - * If we have prototypes, we should have stdlib.h string.h stdarg.h - */ -#ifdef PROTOTYPES -#if !(defined(SABER) && defined(sun)) -# ifndef HAVE_STDARG_H -# define HAVE_STDARG_H -# endif -#endif -# ifndef HAVE_STDLIB_H -# define HAVE_STDLIB_H -# endif -# ifndef HAVE_STRING_H -# define HAVE_STRING_H -# endif -# ifndef HAVE_STDC_HEADERS -# define HAVE_STDC_HEADERS -# endif -# ifndef STDC_HEADERS -# define STDC_HEADERS /* GNU name */ -# endif -#endif - -#ifdef NO_PROTOTYPES /* Force not to use prototypes */ -# undef PROTOTYPES -#endif - -#ifdef PROTOTYPES -# define __PR(a) a -#else -# define __PR(a) () -#endif - -#endif /* _PROTOTYP_H */ diff --git a/util/mkisofs/include/statdefs.h b/util/mkisofs/include/statdefs.h deleted file mode 100644 index 0e34805ce..000000000 --- a/util/mkisofs/include/statdefs.h +++ /dev/null @@ -1,139 +0,0 @@ -/* @(#)statdefs.h 1.1 98/11/22 Copyright 1998 J. Schilling */ -/* - * Definitions for stat() file mode - * - * Copyright (c) 1998 J. Schilling - */ -/* - * This program 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 2, or (at your option) - * any later version. - * - * This program 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 this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _STATDEFS_H -#define _STATDEFS_H - -#ifndef _MCONFIG_H -#include -#endif - -#ifdef STAT_MACROS_BROKEN -#undef S_ISFIFO /* Named pipe */ -#undef S_ISCHR /* Character special */ -#undef S_ISMPC /* UNUSED multiplexed c */ -#undef S_ISDIR /* Directory */ -#undef S_ISNAM /* Named file (XENIX) */ -#undef S_ISBLK /* Block special */ -#undef S_ISMPB /* UNUSED multiplexed b */ -#undef S_ISREG /* Regular file */ -#undef S_ISCNT /* Contiguous file */ -#undef S_ISLNK /* Symbolic link */ -#undef S_ISSHAD /* Solaris shadow inode */ -#undef S_ISSOCK /* UNIX domain socket */ -#undef S_ISDOOR /* Solaris DOOR */ -#endif - -#ifndef S_ISFIFO /* Named pipe */ -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) (0) -# endif -#endif -#ifndef S_ISCHR /* Character special */ -# ifdef S_IFCHR -# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) -# else -# define S_ISCHR(m) (0) -# endif -#endif -#ifndef S_ISMPC /* UNUSED multiplexed c */ -# ifdef S_IFMPC -# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) -# else -# define S_ISMPC(m) (0) -# endif -#endif -#ifndef S_ISDIR /* Directory */ -# ifdef S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# else -# define S_ISDIR(m) (0) -# endif -#endif -#ifndef S_ISNAM /* Named file (XENIX) */ -# ifdef S_IFNAM -# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM) -# else -# define S_ISNAM(m) (0) -# endif -#endif -#ifndef S_ISBLK /* Block special */ -# ifdef S_IFBLK -# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) -# else -# define S_ISBLK(m) (0) -# endif -#endif -#ifndef S_ISMPB /* UNUSED multiplexed b */ -# ifdef S_IFMPB -# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) -# else -# define S_ISMPB(m) (0) -# endif -#endif -#ifndef S_ISREG /* Regular file */ -# ifdef S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -# else -# define S_ISREG(m) (0) -# endif -#endif -#ifndef S_ISCNT /* Contiguous file */ -# ifdef S_IFCNT -# define S_ISCNT(m) (((m) & S_IFMT) == S_IFCNT) -# else -# define S_ISCNT(m) (0) -# endif -#endif -#ifndef S_ISLNK /* Symbolic link */ -# ifdef S_IFLNK -# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -# else -# define S_ISLNK(m) (0) -# endif -#endif -#ifndef S_ISSHAD /* Solaris shadow inode */ -# ifdef S_IFSHAD -# define S_ISSHAD(m) (((m) & S_IFMT) == S_IFSHAD) -# else -# define S_ISSHAD(m) (0) -# endif -#endif -#ifndef S_ISSOCK /* UNIX domain socket */ -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#ifndef S_ISDOOR /* Solaris DOOR */ -# ifdef S_IFDOOR -# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR) -# else -# define S_ISDOOR(m) (0) -# endif -#endif - -#endif /* _STATDEFS_H */ - diff --git a/util/mkisofs/iso9660.h b/util/mkisofs/iso9660.h deleted file mode 100644 index 78a05db92..000000000 --- a/util/mkisofs/iso9660.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Header file iso9660.h - assorted structure definitions and typecasts. - * specific to iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -/* - * $Id: iso9660.h,v 1.2 1997/05/17 15:46:44 eric Exp $ - */ - -#ifndef _ISOFS_FS_H -#define _ISOFS_FS_H - -/* - * The isofs filesystem constants/structures - */ - -/* This part borrowed from the bsd386 isofs */ -#define ISODCL(from, to) (to - from + 1) - -struct iso_volume_descriptor { - char type[ISODCL(1,1)]; /* 711 */ - char id[ISODCL(2,6)]; - char version[ISODCL(7,7)]; - char data[ISODCL(8,2048)]; -}; - -/* volume descriptor types */ -#define ISO_VD_PRIMARY 1 -#define ISO_VD_SUPPLEMENTARY 2 /* Used by Joliet */ -#define ISO_VD_END 255 - -#define ISO_STANDARD_ID "CD001" - -#define EL_TORITO_ID "EL TORITO SPECIFICATION" -#define EL_TORITO_ARCH_x86 0 -#define EL_TORITO_ARCH_PPC 1 -#define EL_TORITO_ARCH_MAC 2 -#define EL_TORITO_BOOTABLE 0x88 -#define EL_TORITO_MEDIA_NOEMUL 0 -#define EL_TORITO_MEDIA_12FLOP 1 -#define EL_TORITO_MEDIA_144FLOP 2 -#define EL_TORITO_MEDIA_288FLOP 3 -#define EL_TORITO_MEDIA_HD 4 - -struct iso_primary_descriptor { - char type [ISODCL ( 1, 1)]; /* 711 */ - char id [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char unused1 [ISODCL ( 8, 8)]; - char system_id [ISODCL ( 9, 40)]; /* achars */ - char volume_id [ISODCL ( 41, 72)]; /* dchars */ - char unused2 [ISODCL ( 73, 80)]; - char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ - char escape_sequences [ISODCL ( 89, 120)]; - char volume_set_size [ISODCL (121, 124)]; /* 723 */ - char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ - char logical_block_size [ISODCL (129, 132)]; /* 723 */ - char path_table_size [ISODCL (133, 140)]; /* 733 */ - char type_l_path_table [ISODCL (141, 144)]; /* 731 */ - char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ - char type_m_path_table [ISODCL (149, 152)]; /* 732 */ - char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ - char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ - char volume_set_id [ISODCL (191, 318)]; /* dchars */ - char publisher_id [ISODCL (319, 446)]; /* achars */ - char preparer_id [ISODCL (447, 574)]; /* achars */ - char application_id [ISODCL (575, 702)]; /* achars */ - char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ - char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ - char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ - char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ - char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ - char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ - char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ - char file_structure_version [ISODCL (882, 882)]; /* 711 */ - char unused4 [ISODCL (883, 883)]; - char application_data [ISODCL (884, 1395)]; - char unused5 [ISODCL (1396, 2048)]; -}; - -/* El Torito Boot Record Volume Descriptor */ -struct eltorito_boot_descriptor { - char id [ISODCL ( 1, 1)]; /* 711 */ - char id2 [ISODCL ( 2, 6)]; - char version [ISODCL ( 7, 7)]; /* 711 */ - char system_id [ISODCL ( 8, 39)]; - char unused2 [ISODCL ( 40, 71)]; - char bootcat_ptr [ISODCL ( 72 , 75)]; - char unused5 [ISODCL ( 76, 2048)]; -}; - -/* Validation entry for El Torito */ -struct eltorito_validation_entry { - char headerid [ISODCL ( 1, 1)]; /* 711 */ - char arch [ISODCL ( 2, 2)]; - char pad1 [ISODCL ( 3, 4)]; /* 711 */ - char id [ISODCL ( 5, 28)]; - char cksum [ISODCL ( 29, 30)]; - char key1 [ISODCL ( 31, 31)]; - char key2 [ISODCL ( 32, 32)]; -}; - -/* El Torito initial/default entry in boot catalog */ -struct eltorito_defaultboot_entry { - char boot_id [ISODCL ( 1, 1)]; /* 711 */ - char boot_media [ISODCL ( 2, 2)]; - char loadseg [ISODCL ( 3, 4)]; /* 711 */ - char arch [ISODCL ( 5, 5)]; - char pad1 [ISODCL ( 6, 6)]; - char nsect [ISODCL ( 7, 8)]; - char bootoff [ISODCL ( 9, 12)]; - char pad2 [ISODCL ( 13, 32)]; -}; - -/* El Torito boot information table */ -struct eltorito_boot_info -{ - /* Address of Primary Volume Descriptor. */ - char pvd_addr[ISODCL (1, 4)]; - /* Boot file address. */ - char file_addr[ISODCL (5, 8)]; - /* Boot file length. */ - char file_length[ISODCL (9, 12)]; - /* Boot file checksum. */ - char file_checksum[ISODCL (13, 16)]; - char dummy[ISODCL (17, 56)]; -}; - - -/* We use this to help us look up the parent inode numbers. */ - -struct iso_path_table{ - unsigned char name_len[2]; /* 721 */ - char extent[4]; /* 731 */ - char parent[2]; /* 721 */ - char name[1]; -}; - -struct iso_directory_record { - unsigned char length [ISODCL (1, 1)]; /* 711 */ - char ext_attr_length [ISODCL (2, 2)]; /* 711 */ - char extent [ISODCL (3, 10)]; /* 733 */ - char size [ISODCL (11, 18)]; /* 733 */ - char date [ISODCL (19, 25)]; /* 7 by 711 */ - char flags [ISODCL (26, 26)]; - char file_unit_size [ISODCL (27, 27)]; /* 711 */ - char interleave [ISODCL (28, 28)]; /* 711 */ - char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ - unsigned char name_len [ISODCL (33, 33)]; /* 711 */ - char name [34]; /* Not really, but we need something here */ -}; -#endif - - - diff --git a/util/mkisofs/joliet.c b/util/mkisofs/joliet.c deleted file mode 100644 index b3c755792..000000000 --- a/util/mkisofs/joliet.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * File joliet.c - handle Win95/WinNT long file/unicode extensions for iso9660. - - Copyright 1997 Eric Youngdale. - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -/* - * Joliet extensions for ISO9660. These are spottily documented by - * Microsoft. In their infinite stupidity, they completely ignored - * the possibility of using an SUSP record with the long filename - * in it, and instead wrote out a duplicate directory tree with the - * long filenames in it. - * - * I am not sure why they did this. One reason is that they get the path - * tables with the long filenames in them. - * - * There are two basic principles to Joliet, and the non-Unicode variant - * known as Romeo. Long filenames seem to be the main one, and the second - * is that the character set and a few other things is substantially relaxed. - * - * The SVD is identical to the PVD, except: - * - * Id is 2, not 1 (indicates SVD). - * escape_sequences contains UCS-2 indicator (levels 1, 2 or 3). - * The root directory record points to a different extent (with different - * size). - * There are different path tables for the two sets of directory trees. - * - * The following fields are recorded in Unicode: - * system_id - * volume_id - * volume_set_id - * publisher_id - * preparer_id - * application_id - * copyright_file_id - * abstract_file_id - * bibliographic_file_id - * - * Unicode strings are always encoded in big-endian format. - * - * In a directory record, everything is the same as with iso9660, except - * that the name is recorded in unicode. The name length is specified in - * total bytes, not in number of unicode characters. - * - * The character set used for the names is different with UCS - the - * restrictions are that the following are not allowed: - * - * Characters (00)(00) through (00)(1f) (control chars) - * (00)(2a) '*' - * (00)(2f) '/' - * (00)(3a) ':' - * (00)(3b) ';' - * (00)(3f) '?' - * (00)(5c) '\' - */ -#include "config.h" -#include "mkisofs.h" -#include "iso9660.h" - -#include -#include -#include - -static unsigned int jpath_table_index; -static struct directory ** jpathlist; -static int next_jpath_index = 1; -static int sort_goof; - -static int generate_joliet_path_tables __PR((void)); -static int DECL(joliet_sort_directory, (struct directory_entry ** sort_dir)); -static void DECL(assign_joliet_directory_addresses, (struct directory * node)); -static int jroot_gen __PR((void)); - -/* - * Function: convert_to_unicode - * - * Purpose: Perform a 1/2 assed unicode conversion on a text - * string. - * - * Notes: - */ -static void FDECL3(convert_to_unicode, unsigned char *, buffer, int, size, char *, source ) -{ - unsigned char * tmpbuf; - int i; - int j; - - /* - * If we get a NULL pointer for the source, it means we have an inplace - * copy, and we need to make a temporary working copy first. - */ - if( source == NULL ) - { - tmpbuf = (uint8_t *) e_malloc(size); - memcpy( tmpbuf, buffer, size); - } - else - { - tmpbuf = (uint8_t *)source; - } - - /* - * Now start copying characters. If the size was specified to be 0, then - * assume the input was 0 terminated. - */ - j = 0; - for(i=0; i < size ; i += 2, j++) - { - buffer[i] = 0; - /* - * JS integrated from: Achim_Kaiser@t-online.de - * - * Let all valid unicode characters pass through (assuming ISO-8859-1). - * Others are set to '_' . - */ - if( tmpbuf[j] != 0 && - (tmpbuf[j] <= 0x1f || (tmpbuf[j] >= 0x7F && tmpbuf[j] <= 0xA0)) ) - { - buffer[i+1] = '_'; - } - else - { - switch(tmpbuf[j]) - { - case '*': - case '/': - case ':': - case ';': - case '?': - case '\\': - /* - * Even Joliet has some standards as to what is allowed in a pathname. - * Pretty tame in comparison to what DOS restricts you to. - */ - buffer[i+1] = '_'; - break; - default: - buffer[i+1] = tmpbuf[j]; - break; - } - } - } - - if( source == NULL ) - { - free(tmpbuf); - } -} - -/* - * Function: joliet_strlen - * - * Purpose: Return length in bytes of string after conversion to unicode. - * - * Notes: This is provided mainly as a convenience so that when more intelligent - * Unicode conversion for either Multibyte or 8-bit codes is available that - * we can easily adapt. - */ -static int FDECL1(joliet_strlen, const char *, string) -{ - int rtn; - - rtn = strlen(string) << 1; - - /* - * We do clamp the maximum length of a Joliet string to be the - * maximum path size. This helps to ensure that we don't completely - * bolix things up with very long paths. The Joliet specs say - * that the maximum length is 128 bytes, or 64 unicode characters. - */ - if( rtn > 0x80) - { - rtn = 0x80; - } - return rtn; -} - -/* - * Function: get_joliet_vol_desc - * - * Purpose: generate a Joliet compatible volume desc. - * - * Notes: Assume that we have the non-joliet vol desc - * already present in the buffer. Just modifiy the - * appropriate fields. - */ -static void FDECL1(get_joliet_vol_desc, struct iso_primary_descriptor *, jvol_desc) -{ - jvol_desc->type[0] = ISO_VD_SUPPLEMENTARY; - - /* - * For now, always do Unicode level 3. I don't really know what 1 and 2 - * are - perhaps a more limited Unicode set. - * - * FIXME(eric) - how does Romeo fit in here? As mkisofs just - * "expands" 8 bit character codes to 16 bits and does nothing - * special with the Unicode characters, therefore shouldn't mkisofs - * really be stating that it's using UCS-2 Level 1, not Level 3 for - * the Joliet directory tree. - */ - strcpy(jvol_desc->escape_sequences, "%/@"); - - /* - * Until we have Unicode path tables, leave these unset. - */ - set_733((char *) jvol_desc->path_table_size, jpath_table_size); - set_731(jvol_desc->type_l_path_table, jpath_table[0]); - set_731(jvol_desc->opt_type_l_path_table, jpath_table[1]); - set_732(jvol_desc->type_m_path_table, jpath_table[2]); - set_732(jvol_desc->opt_type_m_path_table, jpath_table[3]); - - /* - * Set this one up. - */ - memcpy(jvol_desc->root_directory_record, &jroot_record, - sizeof(struct iso_directory_record)); - - /* - * Finally, we have a bunch of strings to convert to Unicode. - * FIXME(eric) - I don't know how to do this in general, so we will - * just be really lazy and do a char -> short conversion. We probably - * will want to filter any characters >= 0x80. - */ - convert_to_unicode((uint8_t *)jvol_desc->system_id, sizeof(jvol_desc->system_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_id, sizeof(jvol_desc->volume_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->volume_set_id, sizeof(jvol_desc->volume_set_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->publisher_id, sizeof(jvol_desc->publisher_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->preparer_id, sizeof(jvol_desc->preparer_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->application_id, sizeof(jvol_desc->application_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->copyright_file_id, sizeof(jvol_desc->copyright_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->abstract_file_id, sizeof(jvol_desc->abstract_file_id), NULL); - convert_to_unicode((uint8_t *)jvol_desc->bibliographic_file_id, sizeof(jvol_desc->bibliographic_file_id), NULL); - - -} - -static void FDECL1(assign_joliet_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->jpath_index = next_jpath_index++; - if( dpnt->jextent == 0 ) - { - dpnt->jextent = last_extent; - dir_size = (dpnt->jsize + (SECTOR_SIZE - 1)) >> 11; - last_extent += dir_size; - } - } - - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - { - assign_joliet_directory_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} - -static -void FDECL1(build_jpathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - jpathlist[dpnt->jpath_index] = dpnt; - } - if(dpnt->subdir) build_jpathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_jpathlist(... */ - -static int FDECL2(joliet_compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - int rparent, lparent; - - rparent = rr->parent->jpath_index; - lparent = ll->parent->jpath_index; - if( rr->parent == reloc_dir ) - { - rparent = rr->self->parent_rec->filedir->jpath_index; - } - - if( ll->parent == reloc_dir ) - { - lparent = ll->self->parent_rec->filedir->jpath_index; - } - - if (rparent < lparent) - { - return -1; - } - - if (rparent > lparent) - { - return 1; - } - - return strcmp(rr->self->name, ll->self->name); - -} /* compare_paths(... */ - -static int generate_joliet_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = jpath_blocks << 11; - jpath_table_m = (char *) e_malloc(tablesize); - jpath_table_l = (char *) e_malloc(tablesize); - memset(jpath_table_l, 0, tablesize); - memset(jpath_table_m, 0, tablesize); - - if( next_jpath_index > 0xffff ) - { - fprintf (stderr, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_jpath_index); - exit (1); - } - /* - * Now start filling in the path tables. Start with root directory - */ - jpath_table_index = 0; - jpathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_jpath_index); - memset(jpathlist, 0, sizeof(struct directory *) * next_jpath_index); - build_jpathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))joliet_compare_paths); -#else - qsort(&jpathlist[1], next_jpath_index-1, sizeof(struct directory *), - joliet_compare_paths); -#endif - - for(j=1; jjpath_index != j) - { - jpathlist[j]->jpath_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - fprintf (stderr, _("Fatal goof - directory has amnesia\n")); - exit (1); - } - - namelen = joliet_strlen(de->name); - - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 1; - jpath_table_m[jpath_table_index] = 1; - } - else - { - jpath_table_l[jpath_table_index] = namelen; - jpath_table_m[jpath_table_index] = namelen; - } - jpath_table_index += 2; - - set_731(jpath_table_l + jpath_table_index, dpnt->jextent); - set_732(jpath_table_m + jpath_table_index, dpnt->jextent); - jpath_table_index += 4; - - if( dpnt->parent != reloc_dir ) - { - set_721(jpath_table_l + jpath_table_index, - dpnt->parent->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->parent->jpath_index); - } - else - { - set_721(jpath_table_l + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - set_722(jpath_table_m + jpath_table_index, - dpnt->self->parent_rec->filedir->jpath_index); - } - - jpath_table_index += 2; - - /* - * The root directory is still represented in non-unicode fashion. - */ - if( dpnt == root ) - { - jpath_table_l[jpath_table_index] = 0; - jpath_table_m[jpath_table_index] = 0; - jpath_table_index ++; - } - else - { - convert_to_unicode((uint8_t *)jpath_table_l + jpath_table_index, - namelen, de->name); - convert_to_unicode((uint8_t *)jpath_table_m + jpath_table_index, - namelen, de->name); - jpath_table_index += namelen; - } - - if(jpath_table_index & 1) - { - jpath_table_index++; /* For odd lengths we pad */ - } - } - - free(jpathlist); - if(jpath_table_index != jpath_table_size) - { - fprintf(stderr, _("Joliet path table lengths do not match %d %d\n"), - jpath_table_index, - jpath_table_size); - } - return 0; -} /* generate_path_tables(... */ - -static void FDECL2(generate_one_joliet_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct iso_directory_record jrec; - unsigned int total_size; - int cvt_len; - struct directory * finddir; - - total_size = (dpnt->jsize + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - s_entry = dpnt->jcontents; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_JOLIET_ENTRY) { - s_entry = s_entry->jnext; - continue; - } - - /* - * If this entry was a directory that was relocated, we have a bit - * of trouble here. We need to dig out the real thing and put it - * back here. In the Joliet tree, there is no relocated rock - * ridge, as there are no depth limits to a directory tree. - */ - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - for(s_entry1 = reloc_dir->contents; s_entry1; s_entry1 = s_entry1->next) - { - if( s_entry1->parent_rec == s_entry ) - { - break; - } - } - if( s_entry1 == NULL ) - { - /* - * We got trouble. - */ - fprintf (stderr, _("Unable to locate relocated directory\n")); - exit (1); - } - } - else - { - s_entry1 = s_entry; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry1->jreclen; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(&jrec, &s_entry1->isorec, sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - cvt_len = joliet_strlen(s_entry1->name); - - /* - * Fix the record length - this was the non-Joliet version we - * were seeing. - */ - jrec.name_len[0] = cvt_len; - jrec.length[0] = s_entry1->jreclen; - - /* - * If this is a directory, fix the correct size and extent - * number. - */ - if( (jrec.flags[0] & 2) != 0 ) - { - if(strcmp(s_entry1->name,".") == 0) - { - jrec.name_len[0] = 1; - set_733((char *) jrec.extent, dpnt->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->jsize)); - } - else if(strcmp(s_entry1->name,"..") == 0) - { - jrec.name_len[0] = 1; - if( dpnt->parent == reloc_dir ) - { - set_733((char *) jrec.extent, dpnt->self->parent_rec->filedir->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->self->parent_rec->filedir->jsize)); - } - else - - { - set_733((char *) jrec.extent, dpnt->parent->jextent); - set_733((char *) jrec.size, ROUND_UP(dpnt->parent->jsize)); - } - } - else - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 ) - { - finddir = reloc_dir->subdir; - } - else - { - finddir = dpnt->subdir; - } - while(1==1) - { - if(finddir->self == s_entry1) break; - finddir = finddir->next; - if(!finddir) - { - fprintf (stderr, _("Fatal goof - unable to find directory location\n")); - exit (1); - } - } - set_733((char *) jrec.extent, finddir->jextent); - set_733((char *) jrec.size, ROUND_UP(finddir->jsize)); - } - } - - memcpy(directory_buffer + dir_index, &jrec, - sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name)); - - - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry1->isorec.name); - - /* - * Finally dump the Unicode version of the filename. - * Note - . and .. are the same as with non-Joliet discs. - */ - if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, ".") == 0 ) - { - directory_buffer[dir_index++] = 0; - } - else if( (jrec.flags[0] & 2) != 0 - && strcmp(s_entry1->name, "..") == 0 ) - { - directory_buffer[dir_index++] = 1; - } - else - { - convert_to_unicode((uint8_t *)directory_buffer + dir_index, - cvt_len, - s_entry1->name); - dir_index += cvt_len; - } - - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry = s_entry->jnext; - } - - if(dpnt->jsize != dir_index) - { - fprintf (stderr, _("Unexpected joliet directory length %d %d %s\n"), - dpnt->jsize, dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); -} /* generate_one_joliet_directory(... */ - -static int FDECL1(joliet_sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - int status = 0; - - /* don't want to skip this directory if it's the reloc_dir at the moment */ - if(this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) - { - return 0; - } - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip hidden entries */ - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - /* - * First update the path table sizes for directories. - * - * Finally, set the length of the directory entry if Joliet is used. - * The name is longer, but no Rock Ridge is ever used here, so - * depending upon the options the entry size might turn out to be about - * the same. The Unicode name is always a multiple of 2 bytes, so - * we always add 1 to make it an even number. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - jpath_table_size += joliet_strlen(s_entry->name) + sizeof(struct iso_path_table) - 1; - if (jpath_table_size & 1) - { - jpath_table_size++; - } - } - else - { - if (this_dir == root && strlen(s_entry->name) == 1) - { - jpath_table_size += sizeof(struct iso_path_table); - if (jpath_table_size & 1) jpath_table_size++; - } - } - } - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + joliet_strlen(s_entry->name) - + 1; - } - else - { - /* - * Special - for '.' and '..' we generate the same records we - * did for non-Joliet discs. - */ - s_entry->jreclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) - + 1; - } - - - } - - if( (this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - return 0; - } - - this_dir->jcontents = this_dir->contents; - status = joliet_sort_directory(&this_dir->jcontents); - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->jcontents; -/* - * XXX Is it ok to comment this out? - */ -/*XXX JS this_dir->ce_bytes = 0;*/ - for(s_entry = this_dir->jcontents; s_entry; s_entry = s_entry->jnext) - { - int jreclen; - - if( (s_entry->de_flags & INHIBIT_JOLIET_ENTRY) != 0 ) - { - continue; - } - - jreclen = s_entry->jreclen; - - if ((this_dir->jsize & (SECTOR_SIZE - 1)) + jreclen >= SECTOR_SIZE) - { - this_dir->jsize = (this_dir->jsize + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - this_dir->jsize += jreclen; - } - return status; -} - -/* - * Similar to the iso9660 case, except here we perform a full sort based upon the - * regular name of the file, not the 8.3 version. - */ -static int FDECL2(joliet_compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->name; - lpnt = (*l)->name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - */ - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - /* - * Extensions are not special here. Don't treat the dot as something that - * must be bumped to the start of the list. - */ -#if 0 - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; -#endif - - if(*rpnt < *lpnt) return -1; - if(*rpnt > *lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -static int FDECL1(joliet_sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int i; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) - dcount++; - s_entry = s_entry->next; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - /* skip hidden entries */ - if (!(s_entry->de_flags & INHIBIT_JOLIET_ENTRY)) { - sortlist[dcount] = s_entry; - dcount++; - } - s_entry = s_entry->next; - } - - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))joliet_compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - joliet_compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - */ - for(i=0; ijnext = sortlist[i+1]; - } - - sortlist[dcount-1]->jnext = NULL; - *sort_dir = sortlist[0]; - - free(sortlist); - return sort_goof; -} - -int FDECL1(joliet_sort_tree, struct directory *, node) -{ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = joliet_sort_n_finish(dpnt); - if( ret ) - { - break; - } - if(dpnt->subdir) ret = joliet_sort_tree(dpnt->subdir); - if( ret ) - { - break; - } - dpnt = dpnt->next; - } - return ret; -} - -static void FDECL2(generate_joliet_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - if( (dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) == 0 ) - { - /* - * In theory we should never reuse a directory, so this doesn't - * make much sense. - */ - if( dpnt->jextent > session_start ) - { - generate_one_joliet_directory(dpnt, outfile); - } - } - /* skip if hidden - but not for the rr_moved dir */ - if(dpnt->subdir && (!(dpnt->dir_flags & INHIBIT_JOLIET_ENTRY) || dpnt == reloc_dir)) - generate_joliet_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jpathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(jpath_table_l, 1, jpath_blocks << 11, outfile); - xfwrite(jpath_table_m, 1, jpath_blocks << 11, outfile); - last_extent_written += 2*jpath_blocks; - free(jpath_table_l); - free(jpath_table_m); - jpath_table_l = NULL; - jpath_table_m = NULL; - return 0; -} - -static int FDECL1(jdirtree_size, int, starting_extent) -{ - assign_joliet_directory_addresses(root); - return 0; -} - -static int jroot_gen() -{ - jroot_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(jroot_record.name); - jroot_record.ext_attr_length[0] = 0; - set_733((char *) jroot_record.extent, root->jextent); - set_733((char *) jroot_record.size, ROUND_UP(root->jsize)); - iso9660_date(jroot_record.date, root_statbuf.st_mtime); - jroot_record.flags[0] = 2; - jroot_record.file_unit_size[0] = 0; - jroot_record.interleave[0] = 0; - set_723(jroot_record.volume_sequence_number, volume_sequence_number); - jroot_record.name_len[0] = 1; - return 0; -} - -static int FDECL1(jdirtree_write, FILE *, outfile) -{ - generate_joliet_directories(root, outfile); - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(jvd_write, FILE *, outfile) -{ - struct iso_primary_descriptor jvol_desc; - - /* - * Next we write out the boot volume descriptor for the disc - */ - jvol_desc = vol_desc; - get_joliet_vol_desc(&jvol_desc); - xfwrite(&jvol_desc, 1, 2048, outfile); - last_extent_written ++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -static int FDECL1(jpathtab_size, int, starting_extent) -{ - jpath_table[0] = starting_extent; - jpath_table[1] = 0; - jpath_table[2] = jpath_table[0] + jpath_blocks; - jpath_table[3] = 0; - - last_extent += 2*jpath_blocks; - return 0; -} - -struct output_fragment joliet_desc = {NULL, oneblock_size, jroot_gen,jvd_write}; -struct output_fragment jpathtable_desc= {NULL, jpathtab_size, generate_joliet_path_tables, jpathtab_write}; -struct output_fragment jdirtree_desc = {NULL, jdirtree_size, NULL, jdirtree_write}; diff --git a/util/mkisofs/match.c b/util/mkisofs/match.c deleted file mode 100644 index 0072b504e..000000000 --- a/util/mkisofs/match.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -#include "config.h" - -#include -#include -#include "fnmatch.h" - -#include "match.h" - -struct pattern -{ - char *str; - struct pattern *next; -}; - -static struct pattern *patlist = NULL; -static struct pattern *i_patlist = NULL; /* ISO9660/RR */ -static struct pattern *j_patlist = NULL; /* Joliet */ - -#define DECL_ADD_MATCH(function, list) \ -void \ -function (char *pattern) \ -{ \ - struct pattern *new; \ - new = malloc (sizeof (*new)); \ - new->str = strdup (pattern); \ - new->next = list; \ - list = new; \ -} - -DECL_ADD_MATCH (add_match, patlist) -DECL_ADD_MATCH (i_add_match, i_patlist) -DECL_ADD_MATCH (j_add_match, j_patlist) - -#define DECL_MATCHES(function, list) \ -int \ -function (char *str) \ -{ \ - struct pattern *i; \ - for (i = list; i != NULL; i = i->next) \ - if (fnmatch (i->str, str, FNM_FILE_NAME) != FNM_NOMATCH) \ - return 1; \ - return 0; \ -} - -DECL_MATCHES (matches, patlist) -DECL_MATCHES (i_matches, i_patlist) -DECL_MATCHES (j_matches, j_patlist) - -int -i_ishidden() -{ - return (i_patlist != NULL); -} - - -int j_ishidden() -{ - return (j_patlist != NULL); -} diff --git a/util/mkisofs/match.h b/util/mkisofs/match.h deleted file mode 100644 index ee346a24c..000000000 --- a/util/mkisofs/match.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -#include "config.h" - -extern void add_match (char *); -extern void i_add_match (char *); -extern void j_add_match (char *); - -extern int matches (char *); -extern int i_matches (char *); -extern int j_matches (char *); - -extern int i_ishidden (); -extern int j_ishidden (); diff --git a/util/mkisofs/mkisofs.c b/util/mkisofs/mkisofs.c deleted file mode 100644 index 16e2f0c7d..000000000 --- a/util/mkisofs/mkisofs.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* - * Program mkisofs.c - generate iso9660 filesystem based upon directory - * tree on hard disk. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -#include -#include "config.h" -#include "mkisofs.h" -#include "match.h" -#include "getopt.h" - -#include "iso9660.h" -#include - -#ifndef VMS -#include -#else -#include -#include "vms.h" -#endif - -#include -#include - -#ifndef VMS -#ifdef HAVE_UNISTD_H -#include -#endif -#endif -#include - -#include "exclude.h" - -#ifdef __NetBSD__ -#include -#include -#endif - -struct directory * root = NULL; - -static char version_string[] = "mkisofs 1.12b5"; - -#include "progname.h" - -char * outfile; -FILE * discimage; -uint64_t next_extent = 0; -uint64_t last_extent = 0; -uint64_t session_start = 0; -unsigned int path_table_size = 0; -unsigned int path_table[4] = {0,}; -unsigned int path_blocks = 0; - - -unsigned int jpath_table_size = 0; -unsigned int jpath_table[4] = {0,}; -unsigned int jpath_blocks = 0; - -struct iso_directory_record root_record; -struct iso_directory_record jroot_record; - -char * extension_record = NULL; -int extension_record_extent = 0; -int extension_record_size = 0; - -/* These variables are associated with command line options */ -int use_eltorito = 0; -int use_eltorito_emul_floppy = 0; -int use_embedded_boot = 0; -int use_protective_msdos_label = 0; -int use_boot_info_table = 0; -int use_RockRidge = 0; -int use_Joliet = 0; -int verbose = 1; -int all_files = 0; -int follow_links = 0; -int rationalize = 0; -int generate_tables = 0; -int print_size = 0; -int split_output = 0; -char *preparer = PREPARER_DEFAULT; -char *publisher = PUBLISHER_DEFAULT; -char *appid = APPID_DEFAULT; -char *copyright = COPYRIGHT_DEFAULT; -char *biblio = BIBLIO_DEFAULT; -char *abstract = ABSTRACT_DEFAULT; -char *volset_id = VOLSET_ID_DEFAULT; -char *volume_id = VOLUME_ID_DEFAULT; -char *system_id = SYSTEM_ID_DEFAULT; -char *boot_catalog = BOOT_CATALOG_DEFAULT; -char *boot_image = BOOT_IMAGE_DEFAULT; -char *boot_image_embed = NULL; -int volume_set_size = 1; -int volume_sequence_number = 1; - -int omit_period = 0; /* Violates iso9660, but these are a pain */ -int transparent_compression = 0; /* So far only works with linux */ -int omit_version_number = 0; /* May violate iso9660, but noone uses vers*/ -unsigned int RR_relocation_depth = 6; /* Violates iso9660, but most systems work */ -int full_iso9660_filenames = 0; /* Used with Amiga. Disc will not work with - DOS */ -int allow_leading_dots = 0; /* DOS cannot read names with leading dots */ -int split_SL_component = 1; /* circumvent a bug in the SunOS driver */ -int split_SL_field = 1; /* circumvent a bug in the SunOS */ - -struct rcopts{ - char * tag; - char ** variable; -}; - -struct rcopts rcopt[] = { - {"PREP", &preparer}, - {"PUBL", &publisher}, - {"APPI", &appid}, - {"COPY", ©right}, - {"BIBL", &biblio}, - {"ABST", &abstract}, - {"VOLS", &volset_id}, - {"VOLI", &volume_id}, - {"SYSI", &system_id}, - {NULL, NULL} -}; - -/* - * In case it isn't obvious, the option handling code was ripped off from GNU-ld. - */ -struct ld_option -{ - /* The long option information. */ - struct option opt; - /* The short option with the same meaning ('\0' if none). */ - char shortopt; - /* The name of the argument (NULL if none). */ - const char *arg; - /* The documentation string. If this is NULL, this is a synonym for - the previous option. */ - const char *doc; - enum - { - /* Use one dash before long option name. */ - ONE_DASH, - /* Use two dashes before long option name. */ - TWO_DASHES, - /* Don't mention this option in --help output. */ - NO_HELP - } control; -}; - -/* Codes used for the long options with no short synonyms. 150 isn't - special; it's just an arbitrary non-ASCII char value. */ -#define OPTION_HELP 150 -#define OPTION_QUIET 151 -#define OPTION_NOSPLIT_SL_COMPONENT 152 -#define OPTION_NOSPLIT_SL_FIELD 153 -#define OPTION_PRINT_SIZE 154 -#define OPTION_SPLIT_OUTPUT 155 -#define OPTION_ABSTRACT 156 -#define OPTION_BIBLIO 157 -#define OPTION_COPYRIGHT 158 -#define OPTION_SYSID 159 -#define OPTION_VOLSET 160 -#define OPTION_VOLSET_SIZE 161 -#define OPTION_VOLSET_SEQ_NUM 162 -#define OPTION_I_HIDE 163 -#define OPTION_J_HIDE 164 -#define OPTION_LOG_FILE 165 - -#define OPTION_CREAT_DATE 166 -#define OPTION_MODIF_DATE 167 -#define OPTION_EXPIR_DATE 168 -#define OPTION_EFFEC_DATE 169 - -#define OPTION_BOOT_INFO_TABLE 170 -#define OPTION_NO_EMUL_BOOT 171 -#define OPTION_ELTORITO_EMUL_FLOPPY 172 - -#define OPTION_VERSION 173 - -#define OPTION_PROTECTIVE_MSDOS_LABEL 174 - -static const struct ld_option ld_options[] = -{ - { {"all-files", no_argument, NULL, 'a'}, - 'a', NULL, N_("Process all files (don't skip backup files)"), ONE_DASH }, - { {"abstract", required_argument, NULL, OPTION_ABSTRACT}, - '\0', N_("FILE"), N_("Set Abstract filename"), ONE_DASH }, - { {"appid", required_argument, NULL, 'A'}, - 'A', N_("ID"), N_("Set Application ID"), ONE_DASH }, - { {"biblio", required_argument, NULL, OPTION_BIBLIO}, - '\0', N_("FILE"), N_("Set Bibliographic filename"), ONE_DASH }, - { {"copyright", required_argument, NULL, OPTION_COPYRIGHT}, - '\0', N_("FILE"), N_("Set Copyright filename"), ONE_DASH }, - { {"embedded-boot", required_argument, NULL, 'G'}, - 'G', N_("FILE"), N_("Set embedded boot image name"), TWO_DASHES }, - { {"protective-msdos-label", no_argument, NULL, OPTION_PROTECTIVE_MSDOS_LABEL }, - '\0', NULL, N_("Patch a protective DOS-style label in the image"), TWO_DASHES }, - { {"eltorito-boot", required_argument, NULL, 'b'}, - 'b', N_("FILE"), N_("Set El Torito boot image name"), ONE_DASH }, - { {"eltorito-catalog", required_argument, NULL, 'c'}, - 'c', N_("FILE"), N_("Set El Torito boot catalog name"), ONE_DASH }, - { {"boot-info-table", no_argument, NULL, OPTION_BOOT_INFO_TABLE }, - '\0', NULL, N_("Patch Boot Info Table in El Torito boot image"), ONE_DASH }, - { {"no-emul-boot", no_argument, NULL, OPTION_NO_EMUL_BOOT }, - '\0', NULL, N_("Dummy option for backward compatibility"), ONE_DASH }, - { {"eltorito-emul-floppy", no_argument, NULL, OPTION_ELTORITO_EMUL_FLOPPY }, - '\0', NULL, N_("Enable floppy drive emulation for El Torito"), TWO_DASHES }, - { {"cdwrite-params", required_argument, NULL, 'C'}, - 'C', N_("PARAMS"), N_("Magic parameters from cdrecord"), ONE_DASH }, - { {"omit-period", no_argument, NULL, 'd'}, - 'd', NULL, N_("Omit trailing periods from filenames"), ONE_DASH }, - { {"disable-deep-relocation", no_argument, NULL, 'D'}, - 'D', NULL, N_("Disable deep directory relocation"), ONE_DASH }, - { {"follow-links", no_argument, NULL, 'f'}, - 'f', NULL, N_("Follow symbolic links"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), ONE_DASH }, - { {"help", no_argument, NULL, OPTION_HELP}, - '\0', NULL, N_("Print option help"), TWO_DASHES }, - { {"version", no_argument, NULL, OPTION_VERSION}, - '\0', NULL, N_("Print version information and exit"), TWO_DASHES }, - { {"hide", required_argument, NULL, OPTION_I_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide ISO9660/RR file"), ONE_DASH }, - { {"hide-joliet", required_argument, NULL, OPTION_J_HIDE}, - '\0', N_("GLOBFILE"), N_("Hide Joliet file"), ONE_DASH }, - { {NULL, required_argument, NULL, 'i'}, - 'i', N_("ADD_FILES"), N_("No longer supported"), TWO_DASHES }, - { {"joliet", no_argument, NULL, 'J'}, - 'J', NULL, N_("Generate Joliet directory information"), ONE_DASH }, - { {"full-iso9660-filenames", no_argument, NULL, 'l'}, - 'l', NULL, N_("Allow full 32 character filenames for iso9660 names"), ONE_DASH }, - { {"allow-leading-dots", no_argument, NULL, 'L'}, - 'L', NULL, N_("Allow iso9660 filenames to start with '.'"), ONE_DASH }, - { {"log-file", required_argument, NULL, OPTION_LOG_FILE}, - '\0', N_("LOG_FILE"), N_("Re-direct messages to LOG_FILE"), ONE_DASH }, - { {"exclude", required_argument, NULL, 'm'}, - 'm', N_("GLOBFILE"), N_("Exclude file name"), ONE_DASH }, - { {"prev-session", required_argument, NULL, 'M'}, - 'M', N_("FILE"), N_("Set path to previous session to merge"), ONE_DASH }, - { {"omit-version-number", no_argument, NULL, 'N'}, - 'N', NULL, N_("Omit version number from iso9660 filename"), ONE_DASH }, - { {"no-split-symlink-components", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink components"), ONE_DASH }, - { {"no-split-symlink-fields", no_argument, NULL, 0}, - 0, NULL, N_("Inhibit splitting symlink fields"), ONE_DASH }, - { {"output", required_argument, NULL, 'o'}, - 'o', N_("FILE"), N_("Set output file name"), ONE_DASH }, - { {"preparer", required_argument, NULL, 'p'}, - 'p', N_("PREP"), N_("Set Volume preparer"), ONE_DASH }, - { {"print-size", no_argument, NULL, OPTION_PRINT_SIZE}, - '\0', NULL, N_("Print estimated filesystem size and exit"), ONE_DASH }, - { {"publisher", required_argument, NULL, 'P'}, - 'P', N_("PUB"), N_("Set Volume publisher"), ONE_DASH }, - { {"quiet", no_argument, NULL, OPTION_QUIET}, - '\0', NULL, N_("Run quietly"), ONE_DASH }, - { {"rational-rock", no_argument, NULL, 'r'}, - 'r', NULL, N_("Generate rationalized Rock Ridge directory information"), ONE_DASH }, - { {"rock", no_argument, NULL, 'R'}, - 'R', NULL, N_("Generate Rock Ridge directory information"), ONE_DASH }, - { {"split-output", no_argument, NULL, OPTION_SPLIT_OUTPUT}, - '\0', NULL, N_("Split output into files of approx. 1GB size"), ONE_DASH }, - { {"sysid", required_argument, NULL, OPTION_SYSID}, - '\0', N_("ID"), N_("Set System ID"), ONE_DASH }, - { {"translation-table", no_argument, NULL, 'T'}, - 'T', NULL, N_("Generate translation tables for systems that don't understand long filenames"), ONE_DASH }, - { {"verbose", no_argument, NULL, 'v'}, - 'v', NULL, N_("Verbose"), ONE_DASH }, - { {"volid", required_argument, NULL, 'V'}, - 'V', N_("ID"), N_("Set Volume ID"), ONE_DASH }, - { {"volset", required_argument, NULL, OPTION_VOLSET}, - '\0', N_("ID"), N_("Set Volume set ID"), ONE_DASH }, - { {"volset-size", required_argument, NULL, OPTION_VOLSET_SIZE}, - '\0', "#", N_("Set Volume set size"), ONE_DASH }, - { {"volset-seqno", required_argument, NULL, OPTION_VOLSET_SEQ_NUM}, - '\0', "#", N_("Set Volume set sequence number"), ONE_DASH }, - { {"old-exclude", required_argument, NULL, 'x'}, - 'x', N_("FILE"), N_("Exclude file name (deprecated)"), ONE_DASH }, -#ifdef ERIC_neverdef - { {"transparent-compression", no_argument, NULL, 'z'}, - 'z', NULL, "Enable transparent compression of files", ONE_DASH }, -#endif - { {"creation-date", required_argument, NULL, OPTION_CREAT_DATE }, - '\0', NULL, N_("Override creation date"), TWO_DASHES }, - { {"modification-date", required_argument, NULL, OPTION_MODIF_DATE }, - '\0', NULL, N_("Override modification date"), TWO_DASHES }, - { {"expiration-date", required_argument, NULL, OPTION_EXPIR_DATE }, - '\0', NULL, N_("Override expiration date"), TWO_DASHES }, - { {"effective-date", required_argument, NULL, OPTION_EFFEC_DATE }, - '\0', NULL, N_("Override effective date"), TWO_DASHES }, -}; - -#define OPTION_COUNT (sizeof ld_options / sizeof ld_options[0]) - -#if defined(ultrix) || defined(_AUX_SOURCE) -char *strdup(s) -char *s;{char *c;if(c=(char *)malloc(strlen(s)+1))strcpy(c,s);return c;} -#endif - - void read_rcfile __PR((char * appname)); - void usage __PR((void)); -static void hide_reloc_dir __PR((void)); - -void FDECL1(read_rcfile, char *, appname) -{ - FILE * rcfile; - struct rcopts * rco; - char * pnt, *pnt1; - char linebuffer[256]; - static char rcfn[] = ".mkisofsrc"; - char filename[1000]; - int linum; - - strcpy(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - - if (!rcfile) - { - pnt = getenv("MKISOFSRC"); - if (pnt && strlen(pnt) <= sizeof(filename)) - { - strcpy(filename, pnt); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - - if (!rcfile) - { - pnt = getenv("HOME"); - if (pnt && strlen(pnt) + strlen(rcfn) + 2 <= sizeof(filename)) - { - strcpy(filename, pnt); - strcat(filename, "/"); - strcat(filename, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile && strlen(appname)+sizeof(rcfn)+2 <= sizeof(filename)) - { - strcpy(filename, appname); - pnt = strrchr(filename, '/'); - if (pnt) - { - strcpy(pnt + 1, rcfn); - rcfile = fopen(filename, "r"); - if (!rcfile && errno != ENOENT) - perror(filename); - } - } - if (!rcfile) - return; - if ( verbose > 0 ) - { - fprintf (stderr, _("Using \"%s\"\n"), filename); - } - - /* OK, we got it. Now read in the lines and parse them */ - linum = 0; - while (fgets(linebuffer, sizeof(linebuffer), rcfile)) - { - char *name; - char *name_end; - ++linum; - /* skip any leading white space */ - pnt = linebuffer; - while (*pnt == ' ' || *pnt == '\t') - ++pnt; - /* If we are looking at a # character, this line is a comment. */ - if (*pnt == '#') - continue; - /* The name should begin in the left margin. Make sure it is in - upper case. Stop when we see white space or a comment. */ - name = pnt; - while (*pnt && isalpha((unsigned char)*pnt)) - { - if(islower((unsigned char)*pnt)) - *pnt = toupper((unsigned char)*pnt); - pnt++; - } - if (name == pnt) - { - fprintf(stderr, _("%s:%d: name required\n"), filename, linum); - continue; - } - name_end = pnt; - /* Skip past white space after the name */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - /* silently ignore errors in the rc file. */ - if (*pnt != '=') - { - fprintf (stderr, _("%s:%d: equals sign required\n"), filename, linum); - continue; - } - /* Skip pas the = sign, and any white space following it */ - pnt++; /* Skip past '=' sign */ - while (*pnt == ' ' || *pnt == '\t') - pnt++; - - /* now it is safe to NUL terminate the name */ - - *name_end = 0; - - /* Now get rid of trailing newline */ - - pnt1 = pnt; - while (*pnt1) - { - if (*pnt1 == '\n') - { - *pnt1 = 0; - break; - } - pnt1++; - }; - /* OK, now figure out which option we have */ - for(rco = rcopt; rco->tag; rco++) { - if(strcmp(rco->tag, name) == 0) - { - *rco->variable = strdup(pnt); - break; - }; - } - if (rco->tag == NULL) - { - fprintf (stderr, _("%s:%d: field name \"%s\" unknown\n"), filename, linum, - name); - } - } - if (ferror(rcfile)) - perror(filename); - fclose(rcfile); -} - -char * path_table_l = NULL; -char * path_table_m = NULL; - -char * jpath_table_l = NULL; -char * jpath_table_m = NULL; - -int goof = 0; - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -void usage(){ - unsigned int i; -/* const char **targets, **pp;*/ - - printf (_("Usage: %s [options] file...\n"), program_name); - - printf (_("Options:\n")); - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].doc != NULL) - { - int comma; - int len; - unsigned int j; - const char *arg; - - printf (" "); - - comma = FALSE; - len = 2; - - j = i; - do - { - if (ld_options[j].shortopt != '\0' - && ld_options[j].control != NO_HELP) - { - printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt); - len += (comma ? 2 : 0) + 2; - if (ld_options[j].arg != NULL) - { - if (ld_options[j].opt.has_arg != optional_argument) - { - putchar (' '); - ++len; - } - arg = gettext (ld_options[j].arg); - printf ("%s", arg); - len += strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - j = i; - do - { - if (ld_options[j].opt.name != NULL - && ld_options[j].control != NO_HELP) - { - printf ("%s-%s%s", - comma ? ", " : "", - ld_options[j].control == TWO_DASHES ? "-" : "", - ld_options[j].opt.name); - len += ((comma ? 2 : 0) - + 1 - + (ld_options[j].control == TWO_DASHES ? 1 : 0) - + strlen (ld_options[j].opt.name)); - if (ld_options[j].arg != NULL) - { - arg = gettext (ld_options[j].arg); - printf (" %s", arg); - len += 1 + strlen (arg); - } - comma = TRUE; - } - ++j; - } - while (j < OPTION_COUNT && ld_options[j].doc == NULL); - - if (len >= 30) - { - printf ("\n"); - len = 0; - } - - for (; len < 30; len++) - putchar (' '); - - printf ("%s\n", gettext (ld_options[i].doc)); - } - } - exit(1); -} - - -/* - * Fill in date in the iso9660 format - * - * The standards state that the timezone offset is in multiples of 15 - * minutes, and is what you add to GMT to get the localtime. The U.S. - * is always at a negative offset, from -5h to -8h (can vary a little - * with DST, I guess). The Linux iso9660 filesystem has had the sign - * of this wrong for ages (mkisofs had it wrong too for the longest time). - */ -int FDECL2(iso9660_date,char *, result, time_t, crtime){ - struct tm *local; - local = localtime(&crtime); - result[0] = local->tm_year; - result[1] = local->tm_mon + 1; - result[2] = local->tm_mday; - result[3] = local->tm_hour; - result[4] = local->tm_min; - result[5] = local->tm_sec; - - /* - * Must recalculate proper timezone offset each time, - * as some files use daylight savings time and some don't... - */ - result[6] = local->tm_yday; /* save yday 'cause gmtime zaps it */ - local = gmtime(&crtime); - local->tm_year -= result[0]; - local->tm_yday -= result[6]; - local->tm_hour -= result[3]; - local->tm_min -= result[4]; - if (local->tm_year < 0) - { - local->tm_yday = -1; - } - else - { - if (local->tm_year > 0) local->tm_yday = 1; - } - - result[6] = -(local->tm_min + 60*(local->tm_hour + 24*local->tm_yday)) / 15; - - return 0; -} - -/* hide "./rr_moved" if all its contents are hidden */ -static void -hide_reloc_dir() -{ - struct directory_entry * s_entry; - - for (s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) { - if(strcmp(s_entry->name,".")==0 || strcmp(s_entry->name,"..")==0) - continue; - - if((s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - return; - } - - /* all entries are hidden, so hide this directory */ - reloc_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - reloc_dir->self->de_flags |= INHIBIT_ISO9660_ENTRY; -} - -extern char * cdwrite_data; - -int FDECL2(main, int, argc, char **, argv){ - struct directory_entry de; -#ifdef HAVE_SBRK - unsigned long mem_start; -#endif - struct stat statbuf; - char * scan_tree; - char * merge_image = NULL; - struct iso_directory_record * mrootp = NULL; - struct output_fragment * opnt; - int longind; - char shortopts[OPTION_COUNT * 3 + 2]; - struct option longopts[OPTION_COUNT + 1]; - int c; - char *log_file = 0; - - set_program_name (argv[0]); -#if (defined(ENABLE_NLS) && ENABLE_NLS) - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - - if (argc < 2) - usage(); - - /* Get the defaults from the .mkisofsrc file */ - read_rcfile(argv[0]); - - outfile = NULL; - - /* - * Copy long option initialization from GNU-ld. - */ - /* Starting the short option string with '-' is for programs that - expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. */ - { - unsigned int i; - int is, il; - shortopts[0] = '-'; - is = 1; - il = 0; - for (i = 0; i < OPTION_COUNT; i++) - { - if (ld_options[i].shortopt != '\0') - { - shortopts[is] = ld_options[i].shortopt; - ++is; - if (ld_options[i].opt.has_arg == required_argument - || ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - if (ld_options[i].opt.has_arg == optional_argument) - { - shortopts[is] = ':'; - ++is; - } - } - } - if (ld_options[i].opt.name != NULL) - { - longopts[il] = ld_options[i].opt; - ++il; - } - } - shortopts[is] = '\0'; - longopts[il].name = NULL; - } - - while ((c = getopt_long_only (argc, argv, shortopts, longopts, &longind)) != EOF) - switch (c) - { - case 1: - /* - * A filename that we take as input. - */ - optind--; - goto parse_input_files; - case 'C': - /* - * This is a temporary hack until cdwrite gets the proper hooks in - * it. - */ - cdwrite_data = optarg; - break; - case 'i': - fprintf (stderr, _("-i option no longer supported.\n")); - exit(1); - break; - case 'J': - use_Joliet++; - break; - case 'a': - all_files++; - break; - case 'b': - use_eltorito++; - boot_image = optarg; /* pathname of the boot image on cd */ - if (boot_image == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case 'G': - use_embedded_boot = 1; - boot_image_embed = optarg; /* pathname of the boot image on host filesystem */ - if (boot_image_embed == NULL) - error (1, 0, _("Required boot image pathname missing")); - break; - case OPTION_PROTECTIVE_MSDOS_LABEL: - use_protective_msdos_label = 1; - break; - case 'c': - use_eltorito++; - boot_catalog = optarg; /* pathname of the boot image on cd */ - if (boot_catalog == NULL) - { - fprintf (stderr, _("Required boot catalog pathname missing\n")); - exit (1); - } - break; - case OPTION_BOOT_INFO_TABLE: - use_boot_info_table = 1; - break; - case OPTION_NO_EMUL_BOOT: - fprintf (stderr, _("Ignoring -no-emul-boot (no-emulation is the default behaviour)\n")); - break; - case OPTION_ELTORITO_EMUL_FLOPPY: - use_eltorito_emul_floppy = 1; - break; - case OPTION_ABSTRACT: - abstract = optarg; - if(strlen(abstract) > 37) - { - fprintf (stderr, _("Abstract filename string too long\n")); - exit (1); - }; - break; - case 'A': - appid = optarg; - if(strlen(appid) > 128) - { - fprintf (stderr, _("Application-id string too long\n")); - exit (1); - }; - break; - case OPTION_BIBLIO: - biblio = optarg; - if(strlen(biblio) > 37) - { - fprintf (stderr, _("Bibliographic filename string too long\n")); - exit (1); - }; - break; - case OPTION_COPYRIGHT: - copyright = optarg; - if(strlen(copyright) > 37) - { - fprintf (stderr, _("Copyright filename string too long\n")); - exit (1); - }; - break; - case 'd': - omit_period++; - break; - case 'D': - RR_relocation_depth = 32767; - break; - case 'f': - follow_links++; - break; - case 'l': - full_iso9660_filenames++; - break; - case 'L': - allow_leading_dots++; - break; - case OPTION_LOG_FILE: - log_file = optarg; - break; - case 'M': - merge_image = optarg; - break; - case 'N': - omit_version_number++; - break; - case 'o': - outfile = optarg; - break; - case 'p': - preparer = optarg; - if(strlen(preparer) > 128) - { - fprintf (stderr, _("Preparer string too long\n")); - exit (1); - }; - break; - case OPTION_PRINT_SIZE: - print_size++; - break; - case 'P': - publisher = optarg; - if(strlen(publisher) > 128) - { - fprintf (stderr, _("Publisher string too long\n")); - exit (1); - }; - break; - case OPTION_QUIET: - verbose = 0; - break; - case 'R': - use_RockRidge++; - break; - case 'r': - rationalize++; - use_RockRidge++; - break; - case OPTION_SPLIT_OUTPUT: - split_output++; - break; - case OPTION_SYSID: - system_id = optarg; - if(strlen(system_id) > 32) - { - fprintf (stderr, _("System ID string too long\n")); - exit (1); - }; - break; - case 'T': - generate_tables++; - break; - case 'V': - volume_id = optarg; - if(strlen(volume_id) > 32) - { - fprintf (stderr, _("Volume ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET: - volset_id = optarg; - if(strlen(volset_id) > 128) - { - fprintf (stderr, _("Volume set ID string too long\n")); - exit (1); - }; - break; - case OPTION_VOLSET_SIZE: - volume_set_size = atoi(optarg); - break; - case OPTION_VOLSET_SEQ_NUM: - volume_sequence_number = atoi(optarg); - if (volume_sequence_number > volume_set_size) - { - fprintf (stderr, _("Volume set sequence number too big\n")); - exit (1); - } - break; - case 'v': - verbose++; - break; - case 'z': - transparent_compression++; - break; - case 'x': - case 'm': - /* - * Somehow two options to do basically the same thing got added somewhere along - * the way. The 'match' code supports limited globbing, so this is the one - * that got selected. Unfortunately the 'x' switch is probably more intuitive. - */ - add_match(optarg); - break; - case OPTION_I_HIDE: - i_add_match(optarg); - break; - case OPTION_J_HIDE: - j_add_match(optarg); - break; - case OPTION_HELP: - usage (); - exit (0); - break; - case OPTION_VERSION: - printf ("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); - exit (0); - break; - case OPTION_NOSPLIT_SL_COMPONENT: - split_SL_component = 0; - break; - case OPTION_NOSPLIT_SL_FIELD: - split_SL_field = 0; - break; - case OPTION_CREAT_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (creation_date) - free(creation_date); - creation_date = strdup(optarg); - break; - case OPTION_MODIF_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (modification_date) - free(modification_date); - modification_date = strdup(optarg); - break; - case OPTION_EXPIR_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (expiration_date) - free(expiration_date); - expiration_date = strdup(optarg); - break; - case OPTION_EFFEC_DATE: - if (strlen (optarg) != 16) - { - fprintf (stderr, _("date string must be 16 characters.\n")); - exit (1); - } - if (effective_date) - free(effective_date); - effective_date = strdup(optarg); - break; - default: - usage(); - exit(1); - } - -parse_input_files: - -#ifdef __NetBSD__ - { - int resource; - struct rlimit rlp; - if (getrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: getrlimit")); - else { - rlp.rlim_cur=33554432; - if (setrlimit(RLIMIT_DATA,&rlp) == -1) - perror (_("Warning: setrlimit")); - } - } -#endif -#ifdef HAVE_SBRK - mem_start = (unsigned long) sbrk(0); -#endif - - /* if the -hide-joliet option has been given, set the Joliet option */ - if (!use_Joliet && j_ishidden()) - use_Joliet++; - - if(verbose > 1) fprintf(stderr,"%s\n", version_string); - - if(cdwrite_data == NULL && merge_image != NULL) - { - fprintf (stderr, _("Multisession usage bug: Must specify -C if -M is used.\n")); - exit (0); - } - - if(cdwrite_data != NULL && merge_image == NULL) - { - fprintf (stderr, _("Warning: -C specified without -M: old session data will not be merged.\n")); - } - - /* The first step is to scan the directory tree, and take some notes */ - - scan_tree = argv[optind]; - - - if(!scan_tree){ - usage(); - exit(1); - }; - -#ifndef VMS - if(scan_tree[strlen(scan_tree)-1] != '/') { - scan_tree = (char *) e_malloc(strlen(argv[optind])+2); - strcpy(scan_tree, argv[optind]); - strcat(scan_tree, "/"); - }; -#endif - - if(use_RockRidge){ -#if 1 - extension_record = generate_rr_extension_record("RRIP_1991A", - "THE ROCK RIDGE INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT DISC PUBLISHER FOR SPECIFICATION SOURCE. SEE PUBLISHER IDENTIFIER IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION.", &extension_record_size); -#else - extension_record = generate_rr_extension_record("IEEE_P1282", - "THE IEEE P1282 PROTOCOL PROVIDES SUPPORT FOR POSIX FILE SYSTEM SEMANTICS", - "PLEASE CONTACT THE IEEE STANDARDS DEPARTMENT, PISCATAWAY, NJ, USA FOR THE P1282 SPECIFICATION.", &extension_record_size); -#endif - } - - if (log_file) { - FILE *lfp; - int i; - - /* open log file - test that we can open OK */ - if ((lfp = fopen(log_file, "w")) == NULL) - error (1, errno, _("can't open logfile: %s"), log_file); - fclose(lfp); - - /* redirect all stderr message to log_file */ - fprintf (stderr, _("re-directing all messages to %s\n"), log_file); - fflush(stderr); - - /* associate stderr with the log file */ - if (freopen(log_file, "w", stderr) == NULL) - error (1, errno, _("can't open logfile: %s\n"), log_file); - if(verbose > 1) { - for (i=0;iextent, 8); - } - - /* - * Create an empty root directory. If we ever scan it for real, we will fill in the - * contents. - */ - find_or_create_directory(NULL, "", &de, TRUE); - - /* - * Scan the actual directory (and any we find below it) - * for files to write out to the output image. Note - we - * take multiple source directories and keep merging them - * onto the image. - */ - while(optind < argc) - { - char * node; - struct directory * graft_dir; - struct stat st; - char * short_name; - int status; - char graft_point[1024]; - - /* - * We would like a syntax like: - * - * /tmp=/usr/tmp/xxx - * - * where the user can specify a place to graft each - * component of the tree. To do this, we may have to create - * directories along the way, of course. - * Secondly, I would like to allow the user to do something - * like: - * - * /home/baz/RMAIL=/u3/users/baz/RMAIL - * - * so that normal files could also be injected into the tree - * at an arbitrary point. - * - * The idea is that the last component of whatever is being - * entered would take the name from the last component of - * whatever the user specifies. - * - * The default will be that the file is injected at the - * root of the image tree. - */ - node = strchr(argv[optind], '='); - short_name = NULL; - - if( node != NULL ) - { - char * pnt; - char * xpnt; - - *node = '\0'; - strcpy(graft_point, argv[optind]); - *node = '='; - node++; - - graft_dir = root; - xpnt = graft_point; - if( *xpnt == PATH_SEPARATOR ) - { - xpnt++; - } - - /* - * Loop down deeper and deeper until we - * find the correct insertion spot. - */ - while(1==1) - { - pnt = strchr(xpnt, PATH_SEPARATOR); - if( pnt == NULL ) - { - if( *xpnt != '\0' ) - { - short_name = xpnt; - } - break; - } - *pnt = '\0'; - graft_dir = find_or_create_directory(graft_dir, - graft_point, - NULL, TRUE); - *pnt = PATH_SEPARATOR; - xpnt = pnt + 1; - } - } - else - { - graft_dir = root; - node = argv[optind]; - } - - /* - * Now see whether the user wants to add a regular file, - * or a directory at this point. - */ - status = stat_filter(node, &st); - if( status != 0 ) - { - /* - * This is a fatal error - the user won't be getting what - * they want if we were to proceed. - */ - error (1, 0, _("Invalid node - %s\n"), node); - } - else - { - if( S_ISDIR(st.st_mode) ) - { - if (!scan_directory_tree(graft_dir, node, &de)) - { - exit(1); - } - } - else - { - if( short_name == NULL ) - { - short_name = strrchr(node, PATH_SEPARATOR); - if( short_name == NULL || short_name < node ) - { - short_name = node; - } - else - { - short_name++; - } - } - if( !insert_file_entry(graft_dir, node, short_name) ) - { - exit(1); - } - } - } - - optind++; - } - - - /* - * Now merge in any previous sessions. This is driven on the source - * side, since we may need to create some additional directories. - */ - if( merge_image != NULL ) - { - merge_previous_session(root, mrootp); - } - - /* hide "./rr_moved" if all its contents have been hidden */ - if (reloc_dir && i_ishidden()) - hide_reloc_dir(); - - /* - * Sort the directories in the required order (by ISO9660). Also, - * choose the names for the 8.3 filesystem if required, and do - * any other post-scan work. - */ - goof += sort_tree(root); - - if( use_Joliet ) - { - goof += joliet_sort_tree(root); - } - - if (goof) - error (1, 0, _("Joliet tree sort failed.\n")); - - /* - * Fix a couple of things in the root directory so that everything - * is self consistent. - */ - root->self = root->contents; /* Fix this up so that the path - tables get done right */ - - /* - * OK, ready to write the file. Open it up, and generate the thing. - */ - if (print_size){ - discimage = fopen("/dev/null", "wb"); - if (!discimage) - error (1, errno, _("Unable to open /dev/null\n")); - } else if (outfile){ - discimage = fopen(outfile, "wb"); - if (!discimage) - error (1, errno, _("Unable to open disc image file\n")); - } else { - discimage = stdout; - -#if defined(__CYGWIN32__) - setmode(fileno(stdout), O_BINARY); -#endif - } - - /* Now assign addresses on the disc for the path table. */ - - path_blocks = (path_table_size + (SECTOR_SIZE - 1)) >> 11; - if (path_blocks & 1) path_blocks++; - - jpath_blocks = (jpath_table_size + (SECTOR_SIZE - 1)) >> 11; - if (jpath_blocks & 1) jpath_blocks++; - - /* - * Start to set up the linked list that we use to track the - * contents of the disc. - */ - outputlist_insert(&padblock_desc); - - /* - * PVD for disc. - */ - outputlist_insert(&voldesc_desc); - - /* - * SVD for El Torito. MUST be immediately after the PVD! - */ - if( use_eltorito) - { - outputlist_insert(&torito_desc); - } - - /* - * SVD for Joliet. - */ - if( use_Joliet) - { - outputlist_insert(&joliet_desc); - } - - /* - * Finally the last volume desctiptor. - */ - outputlist_insert(&end_vol); - - - outputlist_insert(&pathtable_desc); - if( use_Joliet) - { - outputlist_insert(&jpathtable_desc); - } - - outputlist_insert(&dirtree_desc); - if( use_Joliet) - { - outputlist_insert(&jdirtree_desc); - } - - outputlist_insert(&dirtree_clean); - - if(extension_record) - { - outputlist_insert(&extension_desc); - } - - outputlist_insert(&files_desc); - - /* - * Allow room for the various headers we will be writing. There - * will always be a primary and an end volume descriptor. - */ - last_extent = session_start; - - /* - * Calculate the size of all of the components of the disc, and assign - * extent numbers. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_size != NULL ) - { - (*opnt->of_size)(last_extent); - } - } - - /* - * Generate the contents of any of the sections that we want to generate. - * Not all of the fragments will do anything here - most will generate the - * data on the fly when we get to the write pass. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_generate != NULL ) - { - (*opnt->of_generate)(); - } - } - - if( in_image != NULL ) - { - fclose(in_image); - } - - /* - * Now go through the list of fragments and write the data that corresponds to - * each one. - */ - for(opnt = out_list; opnt; opnt = opnt->of_next ) - { - if( opnt->of_write != NULL ) - { - (*opnt->of_write)(discimage); - } - } - - if( verbose > 0 ) - { -#ifdef HAVE_SBRK - fprintf (stderr, _("Max brk space used %x\n"), - (unsigned int)(((unsigned long)sbrk(0)) - mem_start)); -#endif - fprintf (stderr, _("%llu extents written (%llu MiB)\n"), last_extent, last_extent >> 9); - } - -#ifdef VMS - return 1; -#else - return 0; -#endif -} - -void * -FDECL1(e_malloc, size_t, size) -{ - void* pt = 0; - if( (size > 0) && ((pt = malloc (size)) == NULL)) - error (1, errno, "malloc"); -return pt; -} diff --git a/util/mkisofs/mkisofs.h b/util/mkisofs/mkisofs.h deleted file mode 100644 index b699516e9..000000000 --- a/util/mkisofs/mkisofs.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Header file mkisofs.h - assorted structure definitions and typecasts. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -/* - * $Id: mkisofs.h,v 1.20 1999/03/02 04:16:41 eric Exp $ - */ - -#include -#include -#include -#include - -#if (defined(ENABLE_NLS) && ENABLE_NLS) - -# include -# include - -#else /* ! (defined(ENABLE_NLS) && ENABLE_NLS) */ - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ - -#define _(str) gettext(str) -#define N_(str) str - -/* This symbol is used to indicate that we do not have things like - symlinks, devices, and so forth available. Just files and dirs */ - -#ifdef VMS -#define NON_UNIXFS -#endif - -#ifdef DJGPP -#define NON_UNIXFS -#endif - -#ifdef VMS -#include -#define dirent direct -#endif - -#ifdef _WIN32 -#define NON_UNIXFS -#endif /* _WIN32 */ - -#ifndef S_IROTH -#define S_IROTH 0 -#endif - -#ifndef S_IRGRP -#define S_IRGRP 0 -#endif - -#ifndef HAVE_GETUID -static inline int -getuid () -{ - return 0; -} -#endif - -#ifndef HAVE_GETGID -static inline int -getgid () -{ - return 0; -} -#endif - -#ifndef HAVE_LSTAT -static inline int -lstat (const char *filename, struct stat *buf) -{ - return stat (filename, buf); -} -#endif - -#include -#include -#include - -#if defined(HAVE_DIRENT_H) -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if defined(HAVE_SYS_NDIR_H) -# include -# endif -# if defined(HAVE_SYS_DIR_H) -# include -# endif -# if defined(HAVE_NDIR_H) -# include -# endif -#endif - -#if defined(HAVE_STRING_H) -#include -#else -#if defined(HAVE_STRINGS_H) -#include -#endif -#endif - -#ifdef ultrix -extern char *strdup(); -#endif - -#ifdef __STDC__ -#define DECL(NAME,ARGS) NAME ARGS -#define FDECL1(NAME,TYPE0, ARG0) \ - NAME(TYPE0 ARG0) -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) \ - NAME(TYPE0 ARG0, TYPE1 ARG1) -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2) -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3) -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4) -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(TYPE0 ARG0, TYPE1 ARG1, TYPE2 ARG2, TYPE3 ARG3, TYPE4 ARG4, TYPE5 ARG5) -#else -#define DECL(NAME,ARGS) NAME() -#define FDECL1(NAME,TYPE0, ARG0) NAME(ARG0) TYPE0 ARG0; -#define FDECL2(NAME,TYPE0, ARG0,TYPE1, ARG1) NAME(ARG0, ARG1) TYPE0 ARG0; TYPE1 ARG1; -#define FDECL3(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2) \ - NAME(ARG0, ARG1, ARG2) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; -#define FDECL4(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; -#define FDECL5(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; -#define FDECL6(NAME,TYPE0, ARG0,TYPE1, ARG1, TYPE2, ARG2, TYPE3, ARG3, TYPE4, ARG4, TYPE5, ARG5) \ - NAME(ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) TYPE0 ARG0; TYPE1 ARG1; TYPE2 ARG2; TYPE3 ARG3; TYPE4 ARG4; TYPE5 ARG5; -#define const -#endif - - -#ifdef __SVR4 -#include -#else -extern int optind; -extern char *optarg; -/* extern int getopt (int __argc, char **__argv, char *__optstring); */ -#endif - -#include "iso9660.h" -#include "defaults.h" - -struct directory_entry{ - struct directory_entry * next; - struct directory_entry * jnext; - struct iso_directory_record isorec; - uint64_t starting_block; - uint64_t size; - unsigned short priority; - unsigned char jreclen; /* Joliet record len */ - char * name; - char * table; - char * whole_name; - struct directory * filedir; - struct directory_entry * parent_rec; - unsigned int de_flags; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned char * rr_attributes; - unsigned int rr_attr_size; - unsigned int total_rr_attr_size; - unsigned int got_rr_name; -}; - -struct file_hash{ - struct file_hash * next; - ino_t inode; /* Used in the hash table */ - dev_t dev; /* Used in the hash table */ - unsigned int starting_block; - unsigned int size; -}; - - -/* - * This structure is used to control the output of fragments to the cdrom - * image. Everything that will be written to the output image will eventually - * go through this structure. There are two pieces - first is the sizing where - * we establish extent numbers for everything, and the second is when we actually - * generate the contents and write it to the output image. - * - * This makes it trivial to extend mkisofs to write special things in the image. - * All you need to do is hook an additional structure in the list, and the rest - * works like magic. - * - * The three passes each do the following: - * - * The 'size' pass determines the size of each component and assigns the extent number - * for that component. - * - * The 'generate' pass will adjust the contents and pointers as required now that extent - * numbers are assigned. In some cases, the contents of the record are also generated. - * - * The 'write' pass actually writes the data to the disc. - */ -struct output_fragment -{ - struct output_fragment * of_next; -#ifdef __STDC__ - int (*of_size)(int); - int (*of_generate)(void); - int (*of_write)(FILE *); -#else - int (*of_size)(); - int (*of_generate)(); - int (*of_write)(); -#endif -}; - -extern struct output_fragment * out_list; -extern struct output_fragment * out_tail; - -extern struct output_fragment padblock_desc; -extern struct output_fragment voldesc_desc; -extern struct output_fragment joliet_desc; -extern struct output_fragment torito_desc; -extern struct output_fragment end_vol; -extern struct output_fragment pathtable_desc; -extern struct output_fragment jpathtable_desc; -extern struct output_fragment dirtree_desc; -extern struct output_fragment dirtree_clean; -extern struct output_fragment jdirtree_desc; -extern struct output_fragment extension_desc; -extern struct output_fragment files_desc; - -/* - * This structure describes one complete directory. It has pointers - * to other directories in the overall tree so that it is clear where - * this directory lives in the tree, and it also must contain pointers - * to the contents of the directory. Note that subdirectories of this - * directory exist twice in this stucture. Once in the subdir chain, - * and again in the contents chain. - */ -struct directory{ - struct directory * next; /* Next directory at same level as this one */ - struct directory * subdir; /* First subdirectory in this directory */ - struct directory * parent; - struct directory_entry * contents; - struct directory_entry * jcontents; - struct directory_entry * self; - char * whole_name; /* Entire path */ - char * de_name; /* Entire path */ - unsigned int ce_bytes; /* Number of bytes of CE entries reqd for this dir */ - unsigned int depth; - unsigned int size; - unsigned int extent; - unsigned int jsize; - unsigned int jextent; - unsigned short path_index; - unsigned short jpath_index; - unsigned short dir_flags; - unsigned short dir_nlink; -}; - -extern int goof; -extern struct directory * root; -extern struct directory * reloc_dir; -extern uint64_t next_extent; -extern uint64_t last_extent; -extern uint64_t last_extent_written; -extern uint64_t session_start; - -extern unsigned int path_table_size; -extern unsigned int path_table[4]; -extern unsigned int path_blocks; -extern char * path_table_l; -extern char * path_table_m; - -extern unsigned int jpath_table_size; -extern unsigned int jpath_table[4]; -extern unsigned int jpath_blocks; -extern char * jpath_table_l; -extern char * jpath_table_m; - -extern struct iso_directory_record root_record; -extern struct iso_directory_record jroot_record; - -extern int use_eltorito; -extern int use_embedded_boot; -extern int use_protective_msdos_label; -extern int use_eltorito_emul_floppy; -extern int use_boot_info_table; -extern int use_RockRidge; -extern int use_Joliet; -extern int rationalize; -extern int follow_links; -extern int verbose; -extern int all_files; -extern int generate_tables; -extern int print_size; -extern int split_output; -extern int omit_period; -extern int omit_version_number; -extern int transparent_compression; -extern unsigned int RR_relocation_depth; -extern int full_iso9660_filenames; -extern int split_SL_component; -extern int split_SL_field; - -/* tree.c */ -extern int DECL(stat_filter, (char *, struct stat *)); -extern int DECL(lstat_filter, (char *, struct stat *)); -extern int DECL(sort_tree,(struct directory *)); -extern struct directory * - DECL(find_or_create_directory,(struct directory *, const char *, - struct directory_entry * self, int)); -extern void DECL (finish_cl_pl_entries, (void)); -extern int DECL(scan_directory_tree,(struct directory * this_dir, - char * path, - struct directory_entry * self)); -extern int DECL(insert_file_entry,(struct directory *, char *, - char *)); - -extern void DECL(generate_iso9660_directories,(struct directory *, FILE*)); -extern void DECL(dump_tree,(struct directory * node)); -extern struct directory_entry * DECL(search_tree_file, (struct - directory * node,char * filename)); -extern void DECL(update_nlink_field,(struct directory * node)); -extern void DECL (init_fstatbuf, (void)); -extern struct stat root_statbuf; - -/* eltorito.c */ -extern void DECL(init_boot_catalog, (const char * path )); -extern void DECL(get_torito_desc, (struct eltorito_boot_descriptor * path )); - -/* write.c */ -extern int DECL(get_731,(char *)); -extern int DECL(get_733,(char *)); -extern int DECL(isonum_733,(unsigned char *)); -extern void DECL(set_723,(char *, unsigned int)); -extern void DECL(set_731,(char *, unsigned int)); -extern void DECL(set_721,(char *, unsigned int)); -extern void DECL(set_733,(char *, unsigned int)); -extern int DECL(sort_directory,(struct directory_entry **)); -extern void DECL(generate_one_directory,(struct directory *, FILE*)); -extern void DECL(memcpy_max, (char *, char *, int)); -extern int DECL(oneblock_size, (int starting_extent)); -extern struct iso_primary_descriptor vol_desc; -extern void DECL(xfwrite, (void * buffer, uint64_t count, uint64_t size, FILE * file)); -extern void DECL(set_732, (char * pnt, unsigned int i)); -extern void DECL(set_722, (char * pnt, unsigned int i)); -extern void DECL(outputlist_insert, (struct output_fragment * frag)); - -/* - * Set by user command-line to override default date values - */ - -extern char *creation_date; -extern char *modification_date; -extern char *expiration_date; -extern char *effective_date; - -/* multi.c */ - -extern FILE * in_image; -extern struct iso_directory_record * - DECL(merge_isofs,(char * path)); - -extern int DECL(free_mdinfo, (struct directory_entry **, int len)); - -extern struct directory_entry ** - DECL(read_merging_directory,(struct iso_directory_record *, int*)); -extern void - DECL(merge_remaining_entries, (struct directory *, - struct directory_entry **, int)); -extern int - DECL(merge_previous_session, (struct directory *, - struct iso_directory_record *)); - -extern int DECL(get_session_start, (int *)); - -/* joliet.c */ -int DECL(joliet_sort_tree, (struct directory * node)); - -/* match.c */ -extern int DECL(matches, (char *)); -extern void DECL(add_match, (char *)); - -/* files.c */ -struct dirent * DECL(readdir_add_files, (char **, char *, DIR *)); - -/* */ - -extern int DECL(iso9660_file_length,(const char* name, - struct directory_entry * sresult, int flag)); -extern int DECL(iso9660_date,(char *, time_t)); -extern void DECL(add_hash,(struct directory_entry *)); -extern struct file_hash * DECL(find_hash,(dev_t, ino_t)); -extern void DECL(add_directory_hash,(dev_t, ino_t)); -extern struct file_hash * DECL(find_directory_hash,(dev_t, ino_t)); -extern void DECL (flush_file_hash, (void)); -extern int DECL(delete_file_hash,(struct directory_entry *)); -extern struct directory_entry * DECL(find_file_hash,(char *)); -extern void DECL(add_file_hash,(struct directory_entry *)); -extern int DECL(generate_rock_ridge_attributes,(char *, char *, - struct directory_entry *, - struct stat *, struct stat *, - int deep_flag)); -extern char * DECL(generate_rr_extension_record,(char * id, char * descriptor, - char * source, int * size)); - -extern int DECL(check_prev_session, (struct directory_entry **, int len, - struct directory_entry *, - struct stat *, - struct stat *, - struct directory_entry **)); - -#ifdef USE_SCG -/* scsi.c */ -#ifdef __STDC__ -extern int readsecs(int startsecno, void *buffer, int sectorcount); -extern int scsidev_open(char *path); -#else -extern int readsecs(); -extern int scsidev_open(); -#endif -#endif - -extern char * extension_record; -extern int extension_record_extent; -extern int n_data_extents; - -/* These are a few goodies that can be specified on the command line, and are - filled into the root record */ - -extern char *preparer; -extern char *publisher; -extern char *copyright; -extern char *biblio; -extern char *abstract; -extern char *appid; -extern char *volset_id; -extern char *system_id; -extern char *volume_id; -extern char *boot_catalog; -extern char *boot_image; -extern char *boot_image_embed; -extern int volume_set_size; -extern int volume_sequence_number; - -extern void * DECL(e_malloc,(size_t)); - - -#define SECTOR_SIZE (2048) -#define ROUND_UP(X) ((X + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1)) - -#define NEED_RE 1 -#define NEED_PL 2 -#define NEED_CL 4 -#define NEED_CE 8 -#define NEED_SP 16 - -#define PREV_SESS_DEV (sizeof(dev_t) >= 4 ? 0x7ffffffd : 0x7ffd) -#define TABLE_INODE (sizeof(ino_t) >= 4 ? 0x7ffffffe : 0x7ffe) -#define UNCACHED_INODE (sizeof(ino_t) >= 4 ? 0x7fffffff : 0x7fff) -#define UNCACHED_DEVICE (sizeof(dev_t) >= 4 ? 0x7fffffff : 0x7fff) - -#ifdef VMS -#define STAT_INODE(X) (X.st_ino[0]) -#define PATH_SEPARATOR ']' -#define SPATH_SEPARATOR "" -#else -#define STAT_INODE(X) (X.st_ino) -#define PATH_SEPARATOR '/' -#define SPATH_SEPARATOR "/" -#endif - -/* - * When using multi-session, indicates that we can reuse the - * TRANS.TBL information for this directory entry. If this flag - * is set for all entries in a directory, it means we can just - * reuse the TRANS.TBL and not generate a new one. - */ -#define SAFE_TO_REUSE_TABLE_ENTRY 0x01 -#define DIR_HAS_DOT 0x02 -#define DIR_HAS_DOTDOT 0x04 -#define INHIBIT_JOLIET_ENTRY 0x08 -#define INHIBIT_RR_ENTRY 0x10 -#define RELOCATED_DIRECTORY 0x20 -#define INHIBIT_ISO9660_ENTRY 0x40 - -/* - * Volume sequence number to use in all of the iso directory records. - */ -#define DEF_VSN 1 - -/* - * Make sure we have a definition for this. If not, take a very conservative - * guess. From what I can tell SunOS is the only one with this trouble. - */ -#ifndef NAME_MAX -#ifdef FILENAME_MAX -#define NAME_MAX FILENAME_MAX -#else -#define NAME_MAX 128 -#endif -#endif diff --git a/util/mkisofs/msdos_partition.h b/util/mkisofs/msdos_partition.h deleted file mode 100644 index 13985f7bb..000000000 --- a/util/mkisofs/msdos_partition.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc. - * - * GRUB 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. - * - * GRUB 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 GRUB. If not, see . - */ - -#ifndef MSDOS_PARTITION_H -#define MSDOS_PARTITION_H 1 - -#include - -/* The signature. */ -#define MSDOS_PARTITION_SIGNATURE ((0xaa << 8) | 0x55) - -/* This is not a flag actually, but used as if it were a flag. */ -#define MSDOS_PARTITION_TYPE_HIDDEN_FLAG 0x10 - -/* The partition entry. */ -struct msdos_partition_entry -{ - /* If active, 0x80, otherwise, 0x00. */ - uint8_t flag; - - /* The head of the start. */ - uint8_t start_head; - - /* (S | ((C >> 2) & 0xC0)) where S is the sector of the start and C - is the cylinder of the start. Note that S is counted from one. */ - uint8_t start_sector; - - /* (C & 0xFF) where C is the cylinder of the start. */ - uint8_t start_cylinder; - - /* The partition type. */ - uint8_t type; - - /* The end versions of start_head, start_sector and start_cylinder, - respectively. */ - uint8_t end_head; - uint8_t end_sector; - uint8_t end_cylinder; - - /* The start sector. Note that this is counted from zero. */ - uint32_t start; - - /* The length in sector units. */ - uint32_t length; -} __attribute__ ((packed)); - -/* The structure of MBR. */ -struct msdos_partition_mbr -{ - /* The code area (actually, including BPB). */ - uint8_t code[446]; - - /* Four partition entries. */ - struct msdos_partition_entry entries[4]; - - /* The signature 0xaa55. */ - uint16_t signature; -} __attribute__ ((packed)); - -#endif diff --git a/util/mkisofs/multi.c b/util/mkisofs/multi.c deleted file mode 100644 index d92f14530..000000000 --- a/util/mkisofs/multi.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* - * File multi.c - scan existing iso9660 image and merge into - * iso9660 filesystem. Used for multisession support. - * - * Written by Eric Youngdale (1996). - * - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * This program 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, or (at your option) - * any later version. - * - * This program 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 this program; if not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS - -#ifdef HAVE_UNISTD_H -#include -#endif - -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -#include "mkisofs.h" -#include "iso9660.h" - -#define TF_CREATE 1 -#define TF_MODIFY 2 -#define TF_ACCESS 4 -#define TF_ATTRIBUTES 8 - -static int isonum_711 __PR((unsigned char * p)); -static int isonum_721 __PR((unsigned char * p)); -static int isonum_723 __PR((unsigned char * p)); -static int isonum_731 __PR((unsigned char * p)); - -static int DECL(merge_old_directory_into_tree, (struct directory_entry *, - struct directory *)); - -#ifdef __STDC__ -static int -isonum_711 (unsigned char * p) -#else -static int -isonum_711 (p) - unsigned char * p; -#endif -{ - return (*p & 0xff); -} - -#ifdef __STDC__ -static int -isonum_721 (unsigned char * p) -#else -static int -isonum_721 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); -} - -#ifdef __STDC__ -static int -isonum_723 (unsigned char * p) -#else -static int -isonum_723 (p) - unsigned char * p; -#endif -{ -#if 0 - if (p[0] != p[3] || p[1] != p[2]) { - fprintf (stderr, "invalid format 7.2.3 number\n"); - exit (1); - } -#endif - return (isonum_721 (p)); -} - -#ifdef __STDC__ -static int -isonum_731 (unsigned char * p) -#else -static int -isonum_731 (p) - unsigned char * p; -#endif -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -#ifdef __STDC__ -int -isonum_733 (unsigned char * p) -#else -int -isonum_733 (p) - unsigned char * p; -#endif -{ - return (isonum_731 (p)); -} - -FILE * in_image = NULL; - -#ifndef USE_SCG -/* - * Don't define readsecs if mkisofs is linked with - * the SCSI library. - * readsecs() will be implemented as SCSI command in this case. - * - * Use global var in_image directly in readsecs() - * the SCSI equivalent will not use a FILE* for I/O. - * - * The main point of this pointless abstraction is that Solaris won't let - * you read 2K sectors from the cdrom driver. The fact that 99.9% of the - * discs out there have a 2K sectorsize doesn't seem to matter that much. - * Anyways, this allows the use of a scsi-generics type of interface on - * Solaris. - */ -#ifdef __STDC__ -static int -readsecs(int startsecno, void *buffer, int sectorcount) -#else -static int -readsecs(startsecno, buffer, sectorcount) - int startsecno; - void *buffer; - int sectorcount; -#endif -{ - int f = fileno(in_image); - - if (lseek(f, (off_t)startsecno * SECTOR_SIZE, 0) == (off_t)-1) - error (10, errno, _("Seek error on old image\n")); - return (read(f, buffer, sectorcount * SECTOR_SIZE)); -} -#endif - -/* - * Parse the RR attributes so we can find the file name. - */ -static int -FDECL3(parse_rr, unsigned char *, pnt, int, len, struct directory_entry *,dpnt) -{ - int cont_extent, cont_offset, cont_size; - char name_buf[256]; - - cont_extent = cont_offset = cont_size = 0; - - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - if(strncmp((char *) pnt, "NM", 2) == 0) { - strncpy(name_buf, (char *) pnt+5, pnt[2] - 5); - name_buf[pnt[2] - 5] = 0; - dpnt->name = strdup(name_buf); - dpnt->got_rr_name = 1; - return 0; - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* Fall back to the iso name if no RR name found */ - if (dpnt->name == NULL) { - char *cp; - - strcpy(name_buf, dpnt->isorec.name); - cp = strchr(name_buf, ';'); - if (cp != NULL) { - *cp = '\0'; - } - - dpnt->name = strdup(name_buf); - } - - return 0; -} /* parse_rr */ - - -static int -FDECL4(check_rr_dates, struct directory_entry *, dpnt, - struct directory_entry *, current, - struct stat *, statbuf, - struct stat *,lstatbuf) -{ - int cont_extent, cont_offset, cont_size; - int offset; - unsigned char * pnt; - int len; - int same_file; - int same_file_type; - mode_t mode; - char time_buf[7]; - - - cont_extent = cont_offset = cont_size = 0; - same_file = 1; - same_file_type = 1; - - pnt = dpnt->rr_attributes; - len = dpnt->rr_attr_size; - /* - * We basically need to parse the rr attributes again, and - * dig out the dates and file types. - */ - while(len >= 4){ - if(pnt[3] != 1) { - fprintf (stderr, _("**Bad RR version attribute")); - return -1; - }; - - /* - * If we have POSIX file modes, make sure that the file type - * is the same. If it isn't, then we must always - * write the new file. - */ - if(strncmp((char *) pnt, "PX", 2) == 0) { - mode = isonum_733(pnt + 4); - if( (lstatbuf->st_mode & S_IFMT) != (mode & S_IFMT) ) - { - same_file_type = 0; - same_file = 0; - } - } - - if(strncmp((char *) pnt, "TF", 2) == 0) { - offset = 5; - if( pnt[4] & TF_CREATE ) - { - iso9660_date((char *) time_buf, lstatbuf->st_ctime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - if( pnt[4] & TF_MODIFY ) - { - iso9660_date((char *) time_buf, lstatbuf->st_mtime); - if(memcmp(time_buf, pnt+offset, 7) == 0) - same_file = 0; - offset += 7; - } - } - - if(strncmp((char *) pnt, "CE", 2) == 0) { - cont_extent = isonum_733(pnt+4); - cont_offset = isonum_733(pnt+12); - cont_size = isonum_733(pnt+20); - }; - - len -= pnt[2]; - pnt += pnt[2]; - if(len <= 3 && cont_extent) { - unsigned char sector[SECTOR_SIZE]; - - readsecs(cont_extent, sector, 1); - parse_rr(§or[cont_offset], cont_size, dpnt); - }; - }; - - /* - * If we have the same fundamental file type, then it is clearly - * safe to reuse the TRANS.TBL entry. - */ - if( same_file_type ) - { - current->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - } - - return same_file; -} - -struct directory_entry ** -FDECL2(read_merging_directory, struct iso_directory_record *, mrootp, - int *, nent) -{ - unsigned char * cpnt; - unsigned char * cpnt1; - char * dirbuff; - int i; - struct iso_directory_record * idr; - int len; - struct directory_entry **pnt; - int rlen; - struct directory_entry **rtn; - int seen_rockridge; - unsigned char * tt_buf; - int tt_extent; - int tt_size; - - static int warning_given = 0; - - /* - * First, allocate a buffer large enough to read in the entire - * directory. - */ - dirbuff = (char *) e_malloc(isonum_733((unsigned char *)mrootp->size)); - - readsecs(isonum_733((unsigned char *)mrootp->extent), dirbuff, - isonum_733((unsigned char *)mrootp->size)/SECTOR_SIZE); - - /* - * Next look over the directory, and count up how many entries we - * have. - */ - len = isonum_733((unsigned char *)mrootp->size); - i = 0; - *nent = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - (*nent)++; - i += idr->length[0]; - } - - /* - * Now allocate the buffer which will hold the array we are - * about to return. - */ - rtn = (struct directory_entry **) e_malloc(*nent * sizeof(*rtn)); - - /* - * Finally, scan the directory one last time, and pick out the - * relevant bits of information, and store it in the relevant - * bits of the structure. - */ - i = 0; - pnt = rtn; - tt_extent = 0; - seen_rockridge = 0; - tt_size = 0; - while(i < len ) - { - idr = (struct iso_directory_record *) &dirbuff[i]; - if(idr->length[0] == 0) - { - i = (i + SECTOR_SIZE - 1) & ~(SECTOR_SIZE - 1); - continue; - } - *pnt = (struct directory_entry *) e_malloc(sizeof(**rtn)); - (*pnt)->next = NULL; - (*pnt)->isorec = *idr; - (*pnt)->starting_block = isonum_733((unsigned char *)idr->extent); - (*pnt)->size = isonum_733((unsigned char *)idr->size); - (*pnt)->priority = 0; - (*pnt)->name = NULL; - (*pnt)->got_rr_name = 0; - (*pnt)->table = NULL; - (*pnt)->whole_name = NULL; - (*pnt)->filedir = NULL; - (*pnt)->parent_rec = NULL; - /* - * Set this information so that we correctly cache previous - * session bits of information. - */ - (*pnt)->inode = (*pnt)->starting_block; - (*pnt)->dev = PREV_SESS_DEV; - (*pnt)->rr_attributes = NULL; - (*pnt)->rr_attr_size = 0; - (*pnt)->total_rr_attr_size = 0; - (*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY; - - /* - * Check for and parse any RR attributes for the file. - * All we are really looking for here is the original name - * of the file. - */ - rlen = idr->length[0] & 0xff; - cpnt = (unsigned char *) idr; - - rlen -= sizeof(struct iso_directory_record); - cpnt += sizeof(struct iso_directory_record); - - rlen += sizeof(idr->name); - cpnt -= sizeof(idr->name); - - rlen -= idr->name_len[0]; - cpnt += idr->name_len[0]; - - if((idr->name_len[0] & 1) == 0){ - cpnt++; - rlen--; - }; - - if( rlen != 0 ) - { - (*pnt)->total_rr_attr_size = (*pnt)->rr_attr_size = rlen; - (*pnt)->rr_attributes = e_malloc(rlen); - memcpy((*pnt)->rr_attributes, cpnt, rlen); - seen_rockridge = 1; - } - - /* - * Now zero out the remainder of the name field. - */ - cpnt = (unsigned char *) &(*pnt)->isorec.name; - cpnt += idr->name_len[0]; - memset(cpnt, 0, sizeof((*pnt)->isorec.name) - idr->name_len[0]); - - parse_rr((*pnt)->rr_attributes, rlen, *pnt); - - if( ((*pnt)->isorec.name_len[0] == 1) - && ( ((*pnt)->isorec.name[0] == 0) - || ((*pnt)->isorec.name[0] == 1)) ) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - if( (*pnt)->isorec.name[0] == 0 ) - { - (*pnt)->name = strdup("."); - } - else - { - (*pnt)->name = strdup(".."); - } - } - -#ifdef DEBUG - fprintf(stderr, "got DE name: %s\n", (*pnt)->name); -#endif - - if( strncmp(idr->name, "TRANS.TBL", 9) == 0) - { - if( (*pnt)->name != NULL ) - { - free((*pnt)->name); - } - if( (*pnt)->whole_name != NULL ) - { - free((*pnt)->whole_name); - } - (*pnt)->name = strdup(""); - tt_extent = isonum_733((unsigned char *)idr->extent); - tt_size = isonum_733((unsigned char *)idr->size); - } - - pnt++; - i += idr->length[0]; - } - - /* - * If there was a TRANS.TBL;1 entry, then grab it, read it, and use it - * to get the filenames of the files. Also, save the table info, just - * in case we need to use it. - */ - if( tt_extent != 0 && tt_size != 0 ) - { - tt_buf = (unsigned char *) e_malloc(tt_size); - readsecs(tt_extent, tt_buf, tt_size/SECTOR_SIZE); - - /* - * Loop through the file, examine each entry, and attempt to - * attach it to the correct entry. - */ - cpnt = tt_buf; - cpnt1 = tt_buf; - while( cpnt - tt_buf < tt_size ) - { - while(*cpnt1 != '\n' && *cpnt1 != '\0') cpnt1++; - *cpnt1 = '\0'; - - for(pnt = rtn, i = 0; i <*nent; i++, pnt++) - { - rlen = isonum_711((*pnt)->isorec.name_len); - if( strncmp((char *) cpnt + 2, (*pnt)->isorec.name, - rlen) == 0 - && cpnt[2+rlen] == ' ') - { - (*pnt)->table = e_malloc(strlen((char*)cpnt) - 33); - sprintf((*pnt)->table, "%c\t%s\n", - *cpnt, cpnt+37); - if( !(*pnt)->got_rr_name ) - { - if ((*pnt)->name != NULL) { - free((*pnt)->name); - } - (*pnt)->name = strdup((char *) cpnt+37); - } - break; - } - } - cpnt = cpnt1 + 1; - cpnt1 = cpnt; - } - - free(tt_buf); - } - else if( !seen_rockridge && !warning_given ) - { - /* - * Warn the user that iso (8.3) names were used because neither - * Rock Ridge (-R) nor TRANS.TBL (-T) name translations were found. - */ - fprintf (stderr, _("Warning: Neither Rock Ridge (-R) nor TRANS.TBL (-T) " - "name translations were found on previous session. " - "ISO (8.3) file names have been used instead.\n")); - warning_given = 1; - } - - if( dirbuff != NULL ) - { - free(dirbuff); - } - - return rtn; -} /* read_merging_directory */ - -/* - * Free any associated data related to the structures. - */ -int -FDECL2(free_mdinfo, struct directory_entry ** , ptr, int, len ) -{ - int i; - struct directory_entry **p; - - p = ptr; - for(i=0; iname != NULL ) - { - free((*p)->name); - } - - if( (*p)->whole_name != NULL ) - { - free((*p)->whole_name); - } - - if( (*p)->rr_attributes != NULL ) - { - free((*p)->rr_attributes); - } - - if( (*p)->table != NULL ) - { - free((*p)->table); - } - - free(*p); - - } - - free(ptr); - return 0; -} - -/* - * Search the list to see if we have any entries from the previous - * session that match this entry. If so, copy the extent number - * over so we don't bother to write it out to the new session. - */ - -int -FDECL6(check_prev_session, struct directory_entry ** , ptr, int, len, - struct directory_entry *, curr_entry, - struct stat *, statbuf, struct stat *, lstatbuf, - struct directory_entry **, odpnt) -{ - int i; - - for( i=0; i < len; i++ ) - { - if( ptr[i] == NULL ) - { - continue; - } - -#if 0 - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == '\0' ) - { - continue; - } - if( ptr[i]->name != NULL && ptr[i]->isorec.name_len[0] == 1 - && ptr[i]->name[0] == 1) - { - continue; - } -#else - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, ".") == 0 ) - { - continue; - } - if( ptr[i]->name != NULL && strcmp(ptr[i]->name, "..") == 0 ) - { - continue; - } -#endif - - if( ptr[i]->name != NULL - && strcmp(ptr[i]->name, curr_entry->name) != 0 ) - { - continue; - } - - /* - * We know that the files have the same name. If they also have - * the same file type (i.e. file, dir, block, etc), then we - * can safely reuse the TRANS.TBL entry for this file. - * The check_rr_dates function will do this for us. - * - * Verify that the file type and dates are consistent. - * If not, we probably have a different file, and we need - * to write it out again. - */ - if( (ptr[i]->rr_attributes != NULL) - && (check_rr_dates(ptr[i], curr_entry, statbuf, lstatbuf)) ) - { - goto found_it; - } - - - /* - * Verify size and timestamp. If rock ridge is in use, we need - * to compare dates from RR too. Directories are special, we - * calculate their size later. - */ - if( (curr_entry->isorec.flags[0] & 2) == 0 - && ptr[i]->size != curr_entry->size ) - { - goto found_it; - } - - if( memcmp(ptr[i]->isorec.date, curr_entry->isorec.date,7) != 0 ) - { - goto found_it; - } - - /* - * Never ever reuse directory extents. See comments in - * tree.c for an explaination of why this must be the case. - */ - if( (curr_entry->isorec.flags[0] & 2) != 0 ) - { - goto found_it; - } - - memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8); - curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - goto found_it; - } - return 0; - -found_it: - if( odpnt != NULL ) - { - *odpnt = ptr[i]; - } - else - { - free(ptr[i]); - } - ptr[i] = NULL; - return 0; -} - -/* - * merge_isofs: Scan an existing image, and return a pointer - * to the root directory for this image. - */ -struct iso_directory_record * FDECL1(merge_isofs, char *, path) -{ - char buffer[SECTOR_SIZE]; - int file_addr; - int i; - struct iso_primary_descriptor * pri = NULL; - struct iso_directory_record * rootp; - struct iso_volume_descriptor * vdp; - - /* - * Start by opening up the image and searching for the volume header. - * Ultimately, we need to search for volume headers in multiple places - * because we might be starting with a multisession image. - * FIXME(eric). - */ - -#ifndef USE_SCG - in_image = fopen(path, "rb"); - if( in_image == NULL ) - { - return NULL; - } -#else - if (strchr(path, '/')) { - in_image = fopen(path, "rb"); - if( in_image == NULL ) { - return NULL; - } - } else { - if (scsidev_open(path) < 0) - return NULL; - } -#endif - - get_session_start(&file_addr); - - for(i = 0; i< 100; i++) - { - if (readsecs(file_addr/SECTOR_SIZE, &buffer, - sizeof(buffer)/SECTOR_SIZE) != sizeof(buffer)) - error (10, errno, _("Read error on old image %s\n"), path); - - vdp = (struct iso_volume_descriptor *)buffer; - - if( (strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) - && (isonum_711((unsigned char *) vdp->type) == ISO_VD_PRIMARY) ) - { - break; - } - file_addr += SECTOR_SIZE; - } - - if( i == 100 ) - { - return NULL; - } - - pri = (struct iso_primary_descriptor *)vdp; - - /* - * Check the blocksize of the image to make sure it is compatible. - */ - if( (isonum_723 ((unsigned char *) pri->logical_block_size) != SECTOR_SIZE) - || (isonum_723 ((unsigned char *) pri->volume_set_size) != 1) ) - { - return NULL; - } - - /* - * Get the location and size of the root directory. - */ - rootp = (struct iso_directory_record *) - malloc(sizeof(struct iso_directory_record)); - - memcpy(rootp, pri->root_directory_record, sizeof(*rootp)); - - return rootp; -} - -void FDECL3(merge_remaining_entries, struct directory *, this_dir, - struct directory_entry **, pnt, - int, n_orig) -{ - int i; - struct directory_entry * s_entry; - unsigned int ttbl_extent = 0; - unsigned int ttbl_index = 0; - char whole_path[1024]; - - /* - * Whatever is leftover in the list needs to get merged back - * into the directory. - */ - for( i=0; i < n_orig; i++ ) - { - if( pnt[i] == NULL ) - { - continue; - } - - if( pnt[i]->name != NULL && pnt[i]->whole_name == NULL) - { - /* - * Set the name for this directory. - */ - strcpy(whole_path, this_dir->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, pnt[i]->name); - - pnt[i]->whole_name = strdup(whole_path); - } - - if( pnt[i]->name != NULL - && strcmp(pnt[i]->name, "") == 0 ) - { - ttbl_extent = isonum_733((unsigned char *) pnt[i]->isorec.extent); - ttbl_index = i; - continue; - } - /* - * Skip directories for now - these need to be treated - * differently. - */ - if( (pnt[i]->isorec.flags[0] & 2) != 0 ) - { - /* - * FIXME - we need to insert this directory into the - * tree, so that the path tables we generate will - * be correct. - */ - if( (strcmp(pnt[i]->name, ".") == 0) - || (strcmp(pnt[i]->name, "..") == 0) ) - { - free(pnt[i]); - pnt[i] = NULL; - continue; - } - else - { - merge_old_directory_into_tree(pnt[i], this_dir); - } - } - pnt[i]->next = this_dir->contents; - pnt[i]->filedir = this_dir; - this_dir->contents = pnt[i]; - pnt[i] = NULL; - } - - - /* - * If we don't have an entry for the translation table, then - * don't bother trying to copy the starting extent over. - * Note that it is possible that if we are copying the entire - * directory, the entry for the translation table will have already - * been inserted into the linked list and removed from the old - * entries list, in which case we want to leave the extent number - * as it was before. - */ - if( ttbl_extent == 0 ) - { - return; - } - - /* - * Finally, check the directory we are creating to see whether - * there are any new entries in it. If there are not, we can - * reuse the same translation table. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* - * Don't care about '.' or '..'. They are never in the table - * anyways. - */ - if( s_entry->name != NULL && strcmp(s_entry->name, ".") == 0 ) - { - continue; - } - if( s_entry->name != NULL && strcmp(s_entry->name, "..") == 0 ) - { - continue; - } - if( strcmp(s_entry->name, "") == 0) - { - continue; - } - if( (s_entry->de_flags & SAFE_TO_REUSE_TABLE_ENTRY) == 0 ) - { - return; - } - } - - /* - * Locate the translation table, and re-use the same extent. - * It isn't clear that there should ever be one in there already - * so for now we try and muddle through the best we can. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, "") == 0) - { - fprintf (stderr, "Should never get here\n"); - set_733(s_entry->isorec.extent, ttbl_extent); - return; - } - } - - pnt[ttbl_index]->next = this_dir->contents; - pnt[ttbl_index]->filedir = this_dir; - this_dir->contents = pnt[ttbl_index]; - pnt[ttbl_index] = NULL; -} - - -/* - * Here we have a case of a directory that has completely disappeared from - * the face of the earth on the tree we are mastering from. Go through and - * merge it into the tree, as well as everything beneath it. - * - * Note that if a directory has been moved for some reason, this will - * incorrectly pick it up and attempt to merge it back into the old - * location. FIXME(eric). - */ -static int -FDECL2(merge_old_directory_into_tree, struct directory_entry *, dpnt, - struct directory *, parent) -{ - struct directory_entry **contents = NULL; - int i; - int n_orig; - struct directory * this_dir, *next_brother; - char whole_path[1024]; - - this_dir = (struct directory *) e_malloc(sizeof(struct directory)); - memset(this_dir, 0, sizeof(struct directory)); - this_dir->next = NULL; - this_dir->subdir = NULL; - this_dir->self = dpnt; - this_dir->contents = NULL; - this_dir->size = 0; - this_dir->extent = 0; - this_dir->depth = parent->depth + 1; - this_dir->parent = parent; - if(!parent->subdir) - parent->subdir = this_dir; - else { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = this_dir; - } - - /* - * Set the name for this directory. - */ - strcpy(whole_path, parent->de_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, dpnt->name); - this_dir->de_name = strdup(whole_path); - this_dir->whole_name = strdup(whole_path); - - /* - * Now fill this directory using information from the previous - * session. - */ - contents = read_merging_directory(&dpnt->isorec, &n_orig); - /* - * Start by simply copying the '.', '..' and non-directory - * entries to this directory. Technically we could let - * merge_remaining_entries handle this, but it gets rather confused - * by the '.' and '..' entries. - */ - for(i=0; i < n_orig; i ++ ) - { - /* - * We can always reuse the TRANS.TBL in this particular case. - */ - contents[i]->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY; - - if( ((contents[i]->isorec.flags[0] & 2) != 0) - && (i >= 2) ) - { - continue; - } - - /* - * If we have a directory, don't reuse the extent number. - */ - if( (contents[i]->isorec.flags[0] & 2) != 0 ) - { - memset(contents[i]->isorec.extent, 0, 8); - - if( strcmp(contents[i]->name, ".") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOT; - - if( strcmp(contents[i]->name, "..") == 0 ) - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - /* - * Set the whole name for this file. - */ - strcpy(whole_path, this_dir->whole_name); - strcat(whole_path, SPATH_SEPARATOR); - strcat(whole_path, contents[i]->name); - - contents[i]->whole_name = strdup(whole_path); - - contents[i]->next = this_dir->contents; - contents[i]->filedir = this_dir; - this_dir->contents = contents[i]; - contents[i] = NULL; - } - - /* - * Zero the extent number for ourselves. - */ - memset(dpnt->isorec.extent, 0, 8); - - /* - * Anything that is left are other subdirectories that need to be merged. - */ - merge_remaining_entries(this_dir, contents, n_orig); - free_mdinfo(contents, n_orig); -#if 0 - /* - * This is no longer required. The post-scan sort will handle - * all of this for us. - */ - sort_n_finish(this_dir); -#endif - - return 0; -} - - -char * cdwrite_data = NULL; - -int -FDECL1(get_session_start, int *, file_addr) -{ - char * pnt; - -#ifdef CDWRITE_DETERMINES_FIRST_WRITABLE_ADDRESS - /* - * FIXME(eric). We need to coordinate with cdwrite to obtain - * the parameters. For now, we assume we are writing the 2nd session, - * so we start from the session that starts at 0. - */ - - *file_addr = (16 << 11); - - /* - * We need to coordinate with cdwrite to get the next writable address - * from the device. Here is where we use it. - */ - session_start = last_extent = last_extent_written = cdwrite_result(); - -#else - - if( cdwrite_data == NULL ) - error (1, 0, _("Special parameters for cdwrite not specified with -C\n")); - - /* - * Next try and find the ',' in there which delimits the two numbers. - */ - pnt = strchr(cdwrite_data, ','); - if( pnt == NULL ) - error (1, 0, _("Malformed cdwrite parameters\n")); - - *pnt = '\0'; - if (file_addr != NULL) { - *file_addr = atol(cdwrite_data) * SECTOR_SIZE; - } - pnt++; - - session_start = last_extent = last_extent_written = atol(pnt); - - pnt--; - *pnt = ','; - -#endif - return 0; -} - -/* - * This function scans the directory tree, looking for files, and it makes - * note of everything that is found. We also begin to construct the ISO9660 - * directory entries, so that we can determine how large each directory is. - */ - -int -FDECL2(merge_previous_session,struct directory *, this_dir, - struct iso_directory_record *, mrootp) -{ - struct directory_entry **orig_contents = NULL; - struct directory_entry * odpnt = NULL; - int n_orig; - struct directory_entry * s_entry; - int status, lstatus; - struct stat statbuf, lstatbuf; - - /* - * Parse the same directory in the image that we are merging - * for multisession stuff. - */ - orig_contents = read_merging_directory(mrootp, &n_orig); - if( orig_contents == NULL ) - { - return 0; - } - - -/* Now we scan the directory itself, and look at what is inside of it. */ - - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - status = stat_filter(s_entry->whole_name, &statbuf); - lstatus = lstat_filter(s_entry->whole_name, &lstatbuf); - - /* - * We always should create an entirely new directory tree whenever - * we generate a new session, unless there were *no* changes whatsoever - * to any of the directories, in which case it would be kind of pointless - * to generate a new session. - * - * I believe it is possible to rigorously prove that any change anywhere - * in the filesystem will force the entire tree to be regenerated - * because the modified directory will get a new extent number. Since - * each subdirectory of the changed directory has a '..' entry, all of - * them will need to be rewritten too, and since the parent directory - * of the modified directory will have an extent pointer to the directory - * it too will need to be rewritten. Thus we will never be able to reuse - * any directory information when writing new sessions. - * - * We still check the previous session so we can mark off the equivalent - * entry in the list we got from the original disc, however. - */ - - /* - * The check_prev_session function looks for an identical entry in - * the previous session. If we see it, then we copy the extent - * number to s_entry, and cross it off the list. - */ - check_prev_session(orig_contents, n_orig, s_entry, - &statbuf, &lstatbuf, &odpnt); - - if(S_ISDIR(statbuf.st_mode) && odpnt != NULL) - { - int dflag; - - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, - s_entry->whole_name, - s_entry, 1); - dflag = merge_previous_session(child, - &odpnt->isorec); - /* If unable to scan directory, mark this as a non-directory */ - if(!dflag) - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - free(odpnt); - odpnt = NULL; - } - } - } - - /* - * Whatever is left over, are things which are no longer in the tree - * on disk. We need to also merge these into the tree. - */ - merge_remaining_entries(this_dir, orig_contents, n_orig); - free_mdinfo(orig_contents, n_orig); - - return 1; -} - diff --git a/util/mkisofs/name.c b/util/mkisofs/name.c deleted file mode 100644 index 272471e93..000000000 --- a/util/mkisofs/name.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * File name.c - map full Unix file names to unique 8.3 names that - * would be valid on DOS. - * - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - This program 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 2, or (at your option) - any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include "config.h" -#include "mkisofs.h" - -#include - -extern int allow_leading_dots; - -/* - * Function: iso9660_file_length - * - * Purpose: Map file name to 8.3 format, return length - * of result. - * - * Arguments: name file name we need to map. - * sresult directory entry structure to contain mapped name. - * dirflag flag indicating whether this is a directory or not. - * - * Notes: This procedure probably needs to be rationalized somehow. - * New options to affect the behavior of this function - * would also be nice to have. - */ -int FDECL3(iso9660_file_length, - const char*, name, - struct directory_entry *, sresult, - int, dirflag) -{ - char * c; - int chars_after_dot = 0; - int chars_before_dot = 0; - int current_length = 0; - int extra = 0; - int ignore = 0; - char * last_dot; - const char * pnt; - int priority = 32767; - char * result; - int seen_dot = 0; - int seen_semic = 0; - int tildes = 0; - - result = sresult->isorec.name; - - /* - * For the '.' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,".") == 0) - { - if(result) - { - *result = 0; - } - return 1; - } - - /* - * For the '..' entry, generate the correct record, and return - * 1 for the length. - */ - if(strcmp(name,"..") == 0) - { - if(result) - { - *result++ = 1; - *result++ = 0; - } - return 1; - } - - /* - * Now scan the directory one character at a time, and figure out - * what to do. - */ - pnt = name; - - /* - * Find the '.' that we intend to use for the extension. Usually this - * is the last dot, but if we have . followed by nothing or a ~, we - * would consider this to be unsatisfactory, and we keep searching. - */ - last_dot = strrchr (pnt,'.'); - if( (last_dot != NULL) - && ( (last_dot[1] == '~') - || (last_dot[1] == '\0')) ) - { - c = last_dot; - *c = '\0'; - last_dot = strrchr (pnt,'.'); - *c = '.'; - } - - while(*pnt) - { -#ifdef VMS - if( strcmp(pnt,".DIR;1") == 0 ) - { - break; - } -#endif - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '#') - { - priority = 1; - pnt++; - continue; - } - - /* - * This character indicates a Unix style of backup file - * generated by some editors. Lower the priority of - * the file. - */ - if(*pnt == '~') - { - priority = 1; - tildes++; - pnt++; - continue; - } - - /* - * This might come up if we had some joker already try and put - * iso9660 version numbers into the file names. This would be - * a silly thing to do on a Unix box, but we check for it - * anyways. If we see this, then we don't have to add our - * own version number at the end. - * UNLESS the ';' is part of the filename and no version - * number is following. [VK] - */ - if(*pnt == ';') - { - /* [VK] */ - if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9')) - { - pnt++; - ignore++; - continue; - } - } - - /* - * If we have a name with multiple '.' characters, we ignore everything - * after we have gotten the extension. - */ - if(ignore) - { - pnt++; - continue; - } - - /* - * Spin past any iso9660 version number we might have. - */ - if(seen_semic) - { - if(*pnt >= '0' && *pnt <= '9') - { - *result++ = *pnt; - } - extra++; - pnt++; - continue; - } - - /* - * If we have full names, the names we generate will not - * work on a DOS machine, since they are not guaranteed - * to be 8.3. Nonetheless, in many cases this is a useful - * option. We still only allow one '.' character in the - * name, however. - */ - if(full_iso9660_filenames) - { - /* Here we allow a more relaxed syntax. */ - if(*pnt == '.') - { - if (seen_dot) - { - ignore++; - continue; - } - seen_dot++; - } - if(current_length < 30) - { - if( !isascii (*pnt)) - { - *result++ = '_'; - } - else - { - *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt); - } - } - } - else - { - /* - * Dos style filenames. We really restrict the - * names here. - */ - /* It would be nice to have .tar.gz transform to .tgz, - * .ps.gz to .psz, ... - */ - if(*pnt == '.') - { - if (!chars_before_dot && !allow_leading_dots) - { - /* DOS can't read files with dot first */ - chars_before_dot++; - if (result) - { - *result++ = '_'; /* Substitute underscore */ - } - } - else if( pnt != last_dot ) - { - /* - * If this isn't the dot that we use for the extension, - * then change the character into a '_' instead. - */ - if(chars_before_dot < 8) - { - chars_before_dot++; - if(result) - { - *result++ = '_'; - } - } - } - else - { - if (seen_dot) - { - ignore++; continue; - } - if(result) - { - *result++ = '.'; - } - seen_dot++; - } - } - else - { - if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot) - || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) ) - { - if(result) - { - switch (*pnt) - { - default: - if( !isascii (*pnt) ) - { - *result++ = '_'; - } - else - { - *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt; - } - break; - - /* - * Descriptions of DOS's 'Parse Filename' - * (function 29H) describes V1 and V2.0+ - * separator and terminator characters. - * These characters in a DOS name make - * the file visible but un-manipulable - * (all useful operations error off. - */ - /* separators */ - case '+': - case '=': - case '%': /* not legal DOS filename */ - case ':': - case ';': /* already handled */ - case '.': /* already handled */ - case ',': /* already handled */ - case '\t': - case ' ': - /* V1 only separators */ - case '/': - case '"': - case '[': - case ']': - /* terminators */ - case '>': - case '<': - case '|': - /* Hmm - what to do here? Skip? - * Win95 looks like it substitutes '_' - */ - *result++ = '_'; - break; - } /* switch (*pnt) */ - } /* if (result) */ - } /* if (chars_{after,before}_dot) ... */ - } /* else *pnt == '.' */ - } /* else DOS file names */ - current_length++; - pnt++; - } /* while (*pnt) */ - - /* - * OK, that wraps up the scan of the name. Now tidy up a few other - * things. - */ - - /* - * Look for emacs style of numbered backups, like foo.c.~3~. If - * we see this, convert the version number into the priority - * number. In case of name conflicts, this is what would end - * up being used as the 'extension'. - */ - if(tildes == 2) - { - int prio1 = 0; - pnt = name; - while (*pnt && *pnt != '~') - { - pnt++; - } - if (*pnt) - { - pnt++; - } - while(*pnt && *pnt != '~') - { - prio1 = 10*prio1 + *pnt - '0'; - pnt++; - } - priority = prio1; - } - - /* - * If this is not a directory, force a '.' in case we haven't - * seen one, and add a version number if we haven't seen one - * of those either. - */ - if (!dirflag) - { - if (!seen_dot && !omit_period) - { - if (result) *result++ = '.'; - extra++; - } - if(!omit_version_number && !seen_semic) - { - if(result) - { - *result++ = ';'; - *result++ = '1'; - }; - extra += 2; - } - } - - if(result) - { - *result++ = 0; - } - sresult->priority = priority; - - return (chars_before_dot + chars_after_dot + seen_dot + extra); -} diff --git a/util/mkisofs/rock.c b/util/mkisofs/rock.c deleted file mode 100644 index a7a39f774..000000000 --- a/util/mkisofs/rock.c +++ /dev/null @@ -1,597 +0,0 @@ -/* - * File rock.c - generate RRIP records for iso9660 filesystems. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009,2010 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#endif -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include -#include - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#endif - -#else -#include -#endif - -#define SU_VERSION 1 - -#define SL_ROOT 8 -#define SL_PARENT 4 -#define SL_CURRENT 2 -#define SL_CONTINUE 1 - -#define CE_SIZE 28 -#define CL_SIZE 12 -#define ER_SIZE 8 -#define NM_SIZE 5 -#define PL_SIZE 12 -#define PN_SIZE 20 -#define PX_SIZE 36 -#define RE_SIZE 4 -#define SL_SIZE 20 -#define ZZ_SIZE 15 -#ifdef __QNX__ -#define TF_SIZE (5 + 4 * 7) -#else -#define TF_SIZE (5 + 3 * 7) -#endif - -/* If we need to store this number of bytes, make sure we - do not box ourselves in so that we do not have room for - a CE entry for the continuation record */ - -#define MAYBE_ADD_CE_ENTRY(BYTES) \ - ((unsigned) ((BYTES) + CE_SIZE + currlen + ipnt) > (unsigned) (recstart + reclimit) ? 1 : 0) - -/* - * Buffer to build RR attributes - */ - -static unsigned char Rock[16384]; -static unsigned char symlink_buff[256]; -static int ipnt = 0; -static int recstart = 0; -static int currlen = 0; -static int mainrec = 0; -static int reclimit; - -static void add_CE_entry __PR((void)); - -static void add_CE_entry(){ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = CE_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - recstart = ipnt; - currlen = 0; - if(!mainrec) mainrec = ipnt; - reclimit = SECTOR_SIZE - 8; /* Limit to one sector */ -} - -#ifdef __STDC__ -int generate_rock_ridge_attributes (char * whole_name, char * name, - struct directory_entry * s_entry, - struct stat * statbuf, - struct stat * lstatbuf, - int deep_opt) -#else -int generate_rock_ridge_attributes (whole_name, name, - s_entry, - statbuf, - lstatbuf, - deep_opt) -char * whole_name; char * name; struct directory_entry * s_entry; -struct stat * statbuf, *lstatbuf; -int deep_opt; -#endif -{ - int flagpos, flagval; - int need_ce; - - statbuf = statbuf; /* this shuts up unreferenced compiler warnings */ - mainrec = recstart = ipnt = 0; - reclimit = 0xf8; - - /* no need to fill in the RR stuff if we won't see the file */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - return 0; - - /* Obtain the amount of space that is currently used for the directory - record. Assume max for name, since name conflicts may cause us - to rename the file later on */ - currlen = sizeof(s_entry->isorec); - - /* Identify that we are using the SUSP protocol */ - if(deep_opt & NEED_SP){ - Rock[ipnt++] ='S'; - Rock[ipnt++] ='P'; - Rock[ipnt++] = 7; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0xbe; - Rock[ipnt++] = 0xef; - Rock[ipnt++] = 0; - }; - - /* First build the posix name field */ - Rock[ipnt++] ='R'; - Rock[ipnt++] ='R'; - Rock[ipnt++] = 5; - Rock[ipnt++] = SU_VERSION; - flagpos = ipnt; - flagval = 0; - Rock[ipnt++] = 0; /* We go back and fix this later */ - - if(strcmp(name,".") && strcmp(name,"..")){ - char * npnt; - int remain, use; - - remain = strlen(name); - npnt = name; - - while(remain){ - use = remain; - need_ce = 0; - /* Can we fit this SUSP and a CE entry? */ - if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - use = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - - /* Only room for 256 per SUSP field */ - if(use > 0xf8) use = 0xf8; - - /* First build the posix name field */ - Rock[ipnt++] ='N'; - Rock[ipnt++] ='M'; - Rock[ipnt++] = NM_SIZE + use; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = (remain != use ? 1 : 0); - flagval |= (1<<3); - strncpy((char *)&Rock[ipnt], npnt, use); - npnt += use; - ipnt += use; - remain -= use; - if(remain && need_ce) add_CE_entry(); - }; - }; - - /* - * Add the posix modes - */ - if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='X'; - Rock[ipnt++] = PX_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<0); - set_733((char*)Rock + ipnt, lstatbuf->st_mode); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_nlink); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_uid); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_gid); - ipnt += 8; - - /* - * Check for special devices - */ -#ifndef NON_UNIXFS - if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) { - if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='N'; - Rock[ipnt++] = PN_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<1); -#if defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV) - set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev )); - ipnt += 8; - set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev)); - ipnt += 8; -#else - /* - * If we don't have sysmacros.h, then we have to guess as to how - * best to pick apart the device number for major/minor. - * Note: this may very well be wrong for many systems, so - * it is always best to use the major/minor macros if the - * system supports it. - */ - if(sizeof(dev_t) <= 2) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8)); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff); - ipnt += 8; - } - else if(sizeof(dev_t) <= 4) { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff); - ipnt += 8; - } - else { - set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16); - ipnt += 8; - set_733((char*)Rock + ipnt, lstatbuf->st_rdev); - ipnt += 8; - } -#endif - }; -#endif - /* - * Check for and symbolic links. VMS does not have these. - */ - if (S_ISLNK(lstatbuf->st_mode)){ - int lenpos, lenval, j0, j1; - int nchar; - unsigned char * cpnt, *cpnt1; - nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - nchar = strlen((char *) symlink_buff); - set_733(s_entry->isorec.size, 0); - cpnt = &symlink_buff[0]; - flagval |= (1<<2); - - if (! split_SL_field) - { - int sl_bytes = 0; - for (cpnt1 = cpnt; *cpnt1 != '\0'; cpnt1++) - { - if (*cpnt1 == '/') - { - sl_bytes += 4; - } - else - { - sl_bytes += 1; - } - } - if (sl_bytes > 250) - { - /* - * the symbolic link won't fit into one SL System Use Field - * print an error message and continue with splited one - */ - fprintf (stderr, _("symbolic link `%s' too long for one SL System Use Field, splitting"), cpnt); - } - if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry(); - } - - while(nchar){ - if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='S'; - Rock[ipnt++] ='L'; - lenpos = ipnt; - Rock[ipnt++] = SL_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 0; /* Flags */ - lenval = 5; - while(*cpnt){ - cpnt1 = (unsigned char *) strchr((char *) cpnt, '/'); - if(cpnt1) { - nchar--; - *cpnt1 = 0; - }; - - /* We treat certain components in a special way. */ - if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_PARENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 2; - } else if(cpnt[0] == '.' && cpnt[1] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_CURRENT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - nchar -= 1; - } else if(cpnt[0] == 0){ - if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry(); - Rock[ipnt++] = SL_ROOT; - Rock[ipnt++] = 0; /* length is zero */ - lenval += 2; - } else { - /* If we do not have enough room for a component, start - a new continuations segment now */ - if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) : - MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) - { - add_CE_entry(); - if(cpnt1) - { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - j0 = strlen((char *) cpnt); - while(j0) { - j1 = j0; - if(j1 > 0xf8) j1 = 0xf8; - need_ce = 0; - if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) { - j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart); - need_ce++; - } - Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0); - Rock[ipnt++] = j1; - strncpy((char *) Rock + ipnt, (char *) cpnt, j1); - ipnt += j1; - lenval += j1 + 2; - cpnt += j1; - nchar -= j1; /* Number we processed this time */ - j0 -= j1; - if(need_ce) { - add_CE_entry(); - if(cpnt1) { - *cpnt1 = '/'; - nchar++; - cpnt1 = NULL; /* A kluge so that we can restart properly */ - } - break; - } - } - }; - if(cpnt1) { - cpnt = cpnt1 + 1; - } else - break; - } - Rock[lenpos] = lenval; - if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */ - } /* while nchar */ - } /* Is a symbolic link */ - /* - * Add in the Rock Ridge TF time field - */ - if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry(); - Rock[ipnt++] ='T'; - Rock[ipnt++] ='F'; - Rock[ipnt++] = TF_SIZE; - Rock[ipnt++] = SU_VERSION; -#ifdef __QNX__ - Rock[ipnt++] = 0x0f; -#else - Rock[ipnt++] = 0x0e; -#endif - flagval |= (1<<7); -#ifdef __QNX__ - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime); - ipnt += 7; -#endif - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime); - ipnt += 7; - iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime); - ipnt += 7; - - /* - * Add in the Rock Ridge RE time field - */ - if(deep_opt & NEED_RE){ - if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry(); - Rock[ipnt++] ='R'; - Rock[ipnt++] ='E'; - Rock[ipnt++] = RE_SIZE; - Rock[ipnt++] = SU_VERSION; - flagval |= (1<<6); - }; - /* - * Add in the Rock Ridge PL record, if required. - */ - if(deep_opt & NEED_PL){ - if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='P'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = PL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<5); - }; - - /* - * Add in the Rock Ridge CL field, if required. - */ - if(deep_opt & NEED_CL){ - if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry(); - Rock[ipnt++] ='C'; - Rock[ipnt++] ='L'; - Rock[ipnt++] = CL_SIZE; - Rock[ipnt++] = SU_VERSION; - set_733((char*)Rock + ipnt, 0); - ipnt += 8; - flagval |= (1<<4); - }; - -#ifndef VMS - /* If transparent compression was requested, fill in the correct - field for this file */ - if(transparent_compression && - S_ISREG(lstatbuf->st_mode) && - strlen(name) > 3 && - strcmp(name + strlen(name) - 3,".gZ") == 0){ - FILE * zipfile; - char * checkname; - unsigned int file_size; - unsigned char header[8]; - int OK_flag; - - /* First open file and verify that the correct algorithm was used */ - file_size = 0; - OK_flag = 1; - - zipfile = fopen(whole_name, "rb"); - if (fread (header, 1, sizeof (header), zipfile) != sizeof(header)) - error (1, errno, "fread"); - - /* Check some magic numbers from gzip. */ - if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0; - /* Make sure file was blocksized. */ - if(((header[3] & 0x40) == 0)) OK_flag = 0; - /* OK, now go to the end of the file and get some more info */ - if(OK_flag){ - int status; - status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END); - if(status == -1) OK_flag = 0; - } - if(OK_flag){ - if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header)) - OK_flag = 0; - else { - int blocksize; - blocksize = (header[3] << 8) | header[2]; - file_size = ((unsigned int)header[7] << 24) | - ((unsigned int)header[6] << 16) | - ((unsigned int)header[5] << 8) | header[4]; -#if 0 - fprintf(stderr,"Blocksize = %d %d\n", blocksize, file_size); -#endif - if(blocksize != SECTOR_SIZE) OK_flag = 0; - } - } - fclose(zipfile); - - checkname = strdup(whole_name); - checkname[strlen(whole_name)-3] = 0; - zipfile = fopen(checkname, "rb"); - if(zipfile) { - OK_flag = 0; - fprintf (stderr, _("Unable to insert transparent compressed file - name conflict\n")); - fclose(zipfile); - } - - free(checkname); - - if(OK_flag){ - if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry(); - Rock[ipnt++] ='Z'; - Rock[ipnt++] ='Z'; - Rock[ipnt++] = ZZ_SIZE; - Rock[ipnt++] = SU_VERSION; - Rock[ipnt++] = 'g'; /* Identify compression technique used */ - Rock[ipnt++] = 'z'; - Rock[ipnt++] = 3; - set_733((char*)Rock + ipnt, file_size); /* Real file size */ - ipnt += 8; - }; - } -#endif - /* - * Add in the Rock Ridge CE field, if required. We use this for the - * extension record that is stored in the root directory. - */ - if(deep_opt & NEED_CE) add_CE_entry(); - /* - * Done filling in all of the fields. Now copy it back to a buffer for the - * file in question. - */ - - /* Now copy this back to the buffer for the file */ - Rock[flagpos] = flagval; - - /* If there was a CE, fill in the size field */ - if(recstart) - set_733((char*)Rock + recstart - 8, ipnt - recstart); - - s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt); - s_entry->total_rr_attr_size = ipnt; - s_entry->rr_attr_size = (mainrec ? mainrec : ipnt); - memcpy(s_entry->rr_attributes, Rock, ipnt); - return ipnt; -} - -/* Guaranteed to return a single sector with the relevant info */ - -char * FDECL4(generate_rr_extension_record, char *, id, char *, descriptor, - char *, source, int *, size){ - int lipnt = 0; - char * pnt; - int len_id, len_des, len_src; - - len_id = strlen(id); - len_des = strlen(descriptor); - len_src = strlen(source); - Rock[lipnt++] ='E'; - Rock[lipnt++] ='R'; - Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src; - Rock[lipnt++] = 1; - Rock[lipnt++] = len_id; - Rock[lipnt++] = len_des; - Rock[lipnt++] = len_src; - Rock[lipnt++] = 1; - - memcpy(Rock + lipnt, id, len_id); - lipnt += len_id; - - memcpy(Rock + lipnt, descriptor, len_des); - lipnt += len_des; - - memcpy(Rock + lipnt, source, len_src); - lipnt += len_src; - - if(lipnt > SECTOR_SIZE) - error (1, 0, _("Extension record too long\n")); - pnt = (char *) e_malloc(SECTOR_SIZE); - memset(pnt, 0, SECTOR_SIZE); - memcpy(pnt, Rock, lipnt); - *size = lipnt; - return pnt; -} diff --git a/util/mkisofs/tree.c b/util/mkisofs/tree.c deleted file mode 100644 index 0d9cf6143..000000000 --- a/util/mkisofs/tree.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* - * File tree.c - scan directory tree and build memory structures for iso9660 - * filesystem - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -/* ADD_FILES changes made by Ross Biro biro@yggdrasil.com 2/23/95 */ - -#include -#include -#include -#include - -#include "config.h" - -#ifndef VMS -#if defined(MAJOR_IN_SYSMACROS) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#if defined(MAJOR_IN_MKDEV) -#include -#include -#endif -#else -#include -#include -#include "vms.h" -extern char * strdup(const char *); -#endif - -/* - * Autoconf should be able to figure this one out for us and let us know - * whether the system has memmove or not. - */ -# ifndef HAVE_MEMMOVE -# define memmove(d, s, n) bcopy ((s), (d), (n)) -# endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "match.h" - -#include - -#include "exclude.h" - -#ifdef DOESNT_WORK - -#ifdef NON_UNIXFS -#define S_ISLNK(m) (0) -#define S_ISSOCK(m) (0) -#define S_ISFIFO(m) (0) -#else -#ifndef S_ISLNK -#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) -#endif -#ifndef S_ISSOCK -# ifdef S_IFSOCK -# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) -# else -# define S_ISSOCK(m) (0) -# endif -#endif -#endif - -#else -#include -#endif - - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -static unsigned char symlink_buff[256]; - -static void stat_fix __PR((struct stat * st)); -static void generate_reloc_directory __PR((void)); - -static void DECL(attach_dot_entries, (struct directory * dirnode, - struct stat * parent_stat)); -static void DECL(delete_directory, (struct directory * parent, struct directory * child)); - -extern int verbose; - -struct stat fstatbuf; /* We use this for the artificial entries we create */ - -struct stat root_statbuf; /* Stat buffer for root directory */ - -struct directory * reloc_dir = NULL; - -static void -FDECL1(stat_fix, struct stat *, st) -{ - /* Remove the uid and gid, they will only be useful on the author's - system. */ - st->st_uid = 0; - st->st_gid = 0; - - /* - * Make sure the file modes make sense. Turn on all read bits. Turn - * on all exec/search bits if any exec/search bit is set. Turn off - * all write bits, and all special mode bits (on a r/o fs lock bits - * are useless, and with uid+gid 0 don't want set-id bits, either). - */ - st->st_mode |= 0444; -#ifndef _WIN32 /* make all file "executable" */ - if (st->st_mode & 0111) -#endif /* _WIN32 */ - st->st_mode |= 0111; - st->st_mode &= ~07222; -} - -int -FDECL2(stat_filter, char *, path, struct stat *, st) -{ - int result = stat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -int -FDECL2(lstat_filter, char *, path, struct stat *, st) -{ - int result = lstat(path, st); - if (result >= 0 && rationalize) - stat_fix(st); - - if ((unsigned) st->st_size > UINT32_MAX) - result = -1; - - return result; -} - -static int FDECL1(sort_n_finish, struct directory *, this_dir) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry1; - struct directory_entry * table; - int count; - int d1; - int d2; - int d3; - int new_reclen; - char * c; - int status = 0; - int tablesize = 0; - char newname[34]; - char rootname[34]; - - /* Here we can take the opportunity to toss duplicate entries from the - directory. */ - - /* ignore if it's hidden */ - if(this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - { - return 0; - } - - table = NULL; - - init_fstatbuf(); - - /* - * If we had artificially created this directory, then we might be - * missing the required '.' entries. Create these now if we need - * them. - */ - if( (this_dir->dir_flags & (DIR_HAS_DOT | DIR_HAS_DOTDOT)) != - (DIR_HAS_DOT | DIR_HAS_DOTDOT) ) - { - attach_dot_entries(this_dir, &fstatbuf); - } - - flush_file_hash(); - s_entry = this_dir->contents; - while(s_entry) - { - /* ignore if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - s_entry = s_entry->next; - continue; - } - - /* - * First assume no conflict, and handle this case - */ - if(!(s_entry1 = find_file_hash(s_entry->isorec.name))) - { - add_file_hash(s_entry); - s_entry = s_entry->next; - continue; - } - - if(s_entry1 == s_entry) - error (1, 0, _("Fatal goof\n")); - - /* - * OK, handle the conflicts. Try substitute names until we come - * up with a winner - */ - strcpy(rootname, s_entry->isorec.name); - if(full_iso9660_filenames) - { - if(strlen(rootname) > 27) rootname[27] = 0; - } - - /* - * Strip off the non-significant part of the name so that we are left - * with a sensible root filename. If we don't find a '.', then try - * a ';'. - */ - c = strchr(rootname, '.'); - if (c) - *c = 0; - else - { - c = strchr(rootname, ';'); - if (c) *c = 0; - } - for(d1 = 0; d1 < 36; d1++) - { - for(d2 = 0; d2 < 36; d2++) - { - for(d3 = 0; d3 < 36; d3++) - { - sprintf(newname,"%s.%c%c%c%s", rootname, - (d1 <= 9 ? '0' + d1 : 'A' + d1 - 10), - (d2 <= 9 ? '0' + d2 : 'A' + d2 - 10), - (d3 <= 9 ? '0' + d3 : 'A' + d3 - 10), - (s_entry->isorec.flags[0] == 2 || - omit_version_number ? "" : ";1")); - -#ifdef VMS - /* Sigh. VAXCRTL seems to be broken here */ - { - int ijk = 0; - while(newname[ijk]) - { - if(newname[ijk] == ' ') newname[ijk] = '0'; - ijk++; - } - } -#endif - - if(!find_file_hash(newname)) goto got_valid_name; - } - } - } - - /* - * If we fell off the bottom here, we were in real trouble. - */ - error (1, 0, _("Unable to generate unique name for file %s\n"), s_entry->name); - -got_valid_name: - /* - * OK, now we have a good replacement name. Now decide which one - * of these two beasts should get the name changed - */ - if(s_entry->priority < s_entry1->priority) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry->name, s_entry1->name); - } - s_entry->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry->isorec.length[0] = new_reclen; - strcpy(s_entry->isorec.name, newname); - } - else - { - delete_file_hash(s_entry1); - if( verbose > 0 ) - { - fprintf(stderr, _("Using %s for %s%s%s (%s)\n"), newname, - this_dir->whole_name, SPATH_SEPARATOR, - s_entry1->name, s_entry->name); - } - s_entry1->isorec.name_len[0] = strlen(newname); - new_reclen = sizeof(struct iso_directory_record) - - sizeof(s_entry1->isorec.name) + - strlen(newname); - if(use_RockRidge) - { - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - new_reclen += s_entry1->rr_attr_size; - } - if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ - s_entry1->isorec.length[0] = new_reclen; - strcpy(s_entry1->isorec.name, newname); - add_file_hash(s_entry1); - } - add_file_hash(s_entry); - s_entry = s_entry->next; - } - - if(generate_tables - && !find_file_hash("TRANS.TBL") - && (reloc_dir != this_dir) - && (this_dir->extent == 0) ) - { - /* - * First we need to figure out how big this table is - */ - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - if(s_entry->table) tablesize += 35 + strlen(s_entry->table); - } - } - - if( tablesize > 0 ) - { - table = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(table, 0, sizeof(struct directory_entry)); - table->table = NULL; - table->next = this_dir->contents; - this_dir->contents = table; - - table->filedir = root; - table->isorec.flags[0] = 0; - table->priority = 32768; - iso9660_date(table->isorec.date, fstatbuf.st_mtime); - table->inode = TABLE_INODE; - table->dev = (dev_t) UNCACHED_DEVICE; - set_723(table->isorec.volume_sequence_number, volume_sequence_number); - set_733((char *) table->isorec.size, tablesize); - table->size = tablesize; - table->filedir = this_dir; -#ifdef ERIC_neverdef - table->de_flags |= INHIBIT_JOLIET_ENTRY; -#endif - table->name = strdup(""); - table->table = (char *) e_malloc(ROUND_UP(tablesize)); - memset(table->table, 0, ROUND_UP(tablesize)); - iso9660_file_length ("TRANS.TBL", table, 0); - - if(use_RockRidge) - { - fstatbuf.st_mode = 0444 | S_IFREG; - fstatbuf.st_nlink = 1; - generate_rock_ridge_attributes("", - "TRANS.TBL", table, - &fstatbuf, &fstatbuf, 0); - } - } - - /* - * We have now chosen the 8.3 names and we should now know the length - * of every entry in the directory. - */ - for(s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - continue; - } - - new_reclen = strlen(s_entry->isorec.name); - - /* - * First update the path table sizes for directories. - */ - if(s_entry->isorec.flags[0] == 2) - { - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..")) - { - path_table_size += new_reclen + sizeof(struct iso_path_table) - 1; - if (new_reclen & 1) path_table_size++; - } - else - { - new_reclen = 1; - if (this_dir == root && strlen(s_entry->name) == 1) - { - path_table_size += sizeof(struct iso_path_table); - } - } - } - if(path_table_size & 1) path_table_size++; /* For odd lengths we pad */ - s_entry->isorec.name_len[0] = new_reclen; - - new_reclen += - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name); - - if (new_reclen & 1) - new_reclen++; - - new_reclen += s_entry->rr_attr_size; - - if (new_reclen & 1) new_reclen++; - - if(new_reclen > 0xff) - error (1, 0, _("Fatal error - RR overflow for file %s\n"), - s_entry->name); - s_entry->isorec.length[0] = new_reclen; - } - - status = sort_directory(&this_dir->contents); - if( status > 0 ) - { - fprintf (stderr, _("Unable to sort directory %s\n"), - this_dir->whole_name); - } - - /* - * If we are filling out a TRANS.TBL, generate the entries that will - * go in the thing. - */ - if(table) - { - count = 0; - for (s_entry = this_dir->contents; s_entry; s_entry = s_entry->next){ - if(s_entry == table) continue; - if(!s_entry->table) continue; - if(strcmp(s_entry->name, ".") == 0 || - strcmp(s_entry->name, "..") == 0) continue; - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) continue; - /* - * Warning: we cannot use the return value of sprintf because - * old BSD based sprintf() implementations will return - * a pointer to the result instead of a count. - */ - sprintf(table->table + count, "%c %-34s%s", - s_entry->table[0], - s_entry->isorec.name, s_entry->table+1); - count += strlen(table->table + count); - free(s_entry->table); - s_entry->table = NULL; - } - - if(count != tablesize) - error (1, 0, _("Translation table size mismatch %d %d\n"), - count, tablesize); - } - - /* - * Now go through the directory and figure out how large this one will be. - * Do not split a directory entry across a sector boundary - */ - s_entry = this_dir->contents; - this_dir->ce_bytes = 0; - while(s_entry) - { - /* skip if it's hidden */ - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - new_reclen = s_entry->isorec.length[0]; - if ((this_dir->size & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE) - this_dir->size = (this_dir->size + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - this_dir->size += new_reclen; - - /* See if continuation entries were used on disc */ - if(use_RockRidge && - s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len; - int nbytes; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - - /* - * We make sure that each continuation entry record is not - * split across sectors, but each file could in theory have more - * than one CE, so we scan through and figure out what we need. - */ - while(len > 3) - { - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733((char *) pnt+20); - - if((this_dir->ce_bytes & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) this_dir->ce_bytes = - ROUND_UP(this_dir->ce_bytes); - /* Now store the block in the ce buffer */ - this_dir->ce_bytes += nbytes; - if(this_dir->ce_bytes & 1) this_dir->ce_bytes++; - } - len -= pnt[2]; - pnt += pnt[2]; - } - } - s_entry = s_entry->next; - } - return status; -} - -static void generate_reloc_directory() -{ - time_t current_time; - struct directory_entry *s_entry; - - /* Create an entry for our internal tree */ - time (¤t_time); - reloc_dir = (struct directory *) - e_malloc(sizeof(struct directory)); - memset(reloc_dir, 0, sizeof(struct directory)); - reloc_dir->parent = root; - reloc_dir->next = root->subdir; - root->subdir = reloc_dir; - reloc_dir->depth = 1; - reloc_dir->whole_name = strdup("./rr_moved"); - reloc_dir->de_name = strdup("rr_moved"); - reloc_dir->extent = 0; - - - /* Now create an actual directory entry */ - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(s_entry, 0, sizeof(struct directory_entry)); - s_entry->next = root->contents; - reloc_dir->self = s_entry; - - /* - * The rr_moved entry will not appear in the Joliet tree. - */ - reloc_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - - root->contents = s_entry; - root->contents->name = strdup(reloc_dir->de_name); - root->contents->filedir = root; - root->contents->isorec.flags[0] = 2; - root->contents->priority = 32768; - iso9660_date(root->contents->isorec.date, current_time); - root->contents->inode = UNCACHED_INODE; - root->contents->dev = (dev_t) UNCACHED_DEVICE; - set_723(root->contents->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (reloc_dir->de_name, root->contents, 1); - - if(use_RockRidge){ - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - "rr_moved", s_entry, - &fstatbuf, &fstatbuf, 0); - }; - - /* Now create the . and .. entries in rr_moved */ - /* Now create an actual directory entry */ - attach_dot_entries(reloc_dir, &root_statbuf); -} - -/* - * Function: attach_dot_entries - * - * Purpose: Create . and .. entries for a new directory. - * - * Notes: Only used for artificial directories that - * we are creating. - */ -static void FDECL2(attach_dot_entries, struct directory *, dirnode, - struct stat *, parent_stat) -{ - struct directory_entry *s_entry; - struct directory_entry *orig_contents; - int deep_flag = 0; - - init_fstatbuf(); - - orig_contents = dirnode->contents; - - if( (dirnode->dir_flags & DIR_HAS_DOTDOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup(".."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length ("..", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode->parent; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - orig_contents = s_entry; - - if(use_RockRidge) - { - if( parent_stat == NULL ) - { - parent_stat = &fstatbuf; - } - generate_rock_ridge_attributes("", - "..", s_entry, - parent_stat, - parent_stat, 0); - } - dirnode->dir_flags |= DIR_HAS_DOTDOT; - } - - if( (dirnode->dir_flags & DIR_HAS_DOT) == 0 ) - { - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry, dirnode->self, - sizeof(struct directory_entry)); - s_entry->name = strdup("."); - s_entry->whole_name = NULL; - s_entry->isorec.name_len[0] = 1; - s_entry->isorec.flags[0] = 2; /* Mark as a directory */ - iso9660_file_length (".", s_entry, 1); - iso9660_date(s_entry->isorec.date, fstatbuf.st_mtime); - s_entry->filedir = dirnode; - - dirnode->contents = s_entry; - dirnode->contents->next = orig_contents; - - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - - if( dirnode == root ) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - generate_rock_ridge_attributes("", - ".", s_entry, - &fstatbuf, &fstatbuf, deep_flag); - } - - dirnode->dir_flags |= DIR_HAS_DOT; - } - -} - -static void FDECL2(update_nlink, struct directory_entry *, s_entry, int, value) -{ - unsigned char * pnt; - int len; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - set_733((char *) pnt+12, value); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -static void FDECL1(increment_nlink, struct directory_entry *, s_entry) -{ - unsigned char * pnt; - int len, nlink; - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len) - { - if(pnt[0] == 'P' && pnt[1] == 'X') - { - nlink = get_733((char *) pnt+12); - set_733((char *) pnt+12, nlink+1); - break; - } - len -= pnt[2]; - pnt += pnt[2]; - } -} - -void finish_cl_pl_entries(){ - struct directory_entry *s_entry, *s_entry1; - struct directory * d_entry; - - /* if the reloc_dir is hidden (empty), then return */ - if (reloc_dir->dir_flags & INHIBIT_ISO9660_ENTRY) - return; - - s_entry = reloc_dir->contents; - s_entry = s_entry->next->next; /* Skip past . and .. */ - for(; s_entry; s_entry = s_entry->next){ - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - continue; - } - d_entry = reloc_dir->subdir; - while(d_entry){ - if(d_entry->self == s_entry) break; - d_entry = d_entry->next; - }; - if(!d_entry) - error (1, 0, _("Unable to locate directory parent\n")); - - /* First fix the PL pointer in the directory in the rr_reloc dir */ - s_entry1 = d_entry->contents->next; - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - s_entry->filedir->extent); - - /* Now fix the CL pointer */ - s_entry1 = s_entry->parent_rec; - - set_733((char *) s_entry1->rr_attributes + s_entry1->total_rr_attr_size - 8, - d_entry->extent); - - s_entry->filedir = reloc_dir; /* Now we can fix this */ - } - /* Next we need to modify the NLINK terms in the assorted root directory records - to account for the presence of the RR_MOVED directory */ - - increment_nlink(root->self); - increment_nlink(root->self->next); - d_entry = root->subdir; - while(d_entry){ - increment_nlink(d_entry->contents->next); - d_entry = d_entry->next; - }; -} - -/* - * Function: scan_directory_tree - * - * Purpose: Walk through a directory on the local machine - * filter those things we don't want to include - * and build our representation of a dir. - * - * Notes: - */ -int -FDECL3(scan_directory_tree,struct directory *, this_dir, - char *, path, - struct directory_entry *, de) -{ - DIR * current_dir; - char whole_path[1024]; - struct dirent * d_entry; - struct directory * parent; - int dflag; - char * old_path; - - if (verbose > 1) - { - fprintf (stderr, _("Scanning %s\n"), path); - } - - current_dir = opendir(path); - d_entry = NULL; - - /* Apparently NFS sometimes allows you to open the directory, but - then refuses to allow you to read the contents. Allow for this */ - - old_path = path; - - if(current_dir) d_entry = readdir(current_dir); - - if(!current_dir || !d_entry) - { - fprintf (stderr, _("Unable to open directory %s\n"), path); - de->isorec.flags[0] &= ~2; /* Mark as not a directory */ - if(current_dir) closedir(current_dir); - return 0; - } - - parent = de->filedir; - /* Set up the struct for the current directory, and insert it into the - tree */ - -#ifdef VMS - vms_path_fixup(path); -#endif - - /* - * if entry for this sub-directory is hidden, then hide this directory - */ - if (de->de_flags & INHIBIT_ISO9660_ENTRY) - this_dir->dir_flags |= INHIBIT_ISO9660_ENTRY; - - if (de->de_flags & INHIBIT_JOLIET_ENTRY) - this_dir->dir_flags |= INHIBIT_JOLIET_ENTRY; - - /* - * Now we scan the directory itself, and look at what is inside of it. - */ - dflag = 0; - while(1==1){ - - /* The first time through, skip this, since we already asked for - the first entry when we opened the directory. */ - if(dflag) d_entry = readdir(current_dir); - dflag++; - - if(!d_entry) break; - - /* OK, got a valid entry */ - - /* If we do not want all files, then pitch the backups. */ - if(!all_files){ - if( strchr(d_entry->d_name,'~') - || strchr(d_entry->d_name,'#')) - { - if( verbose > 0 ) - { - fprintf (stderr, _("Ignoring file %s\n"), d_entry->d_name); - } - continue; - } - } - - if(strlen(path)+strlen(d_entry->d_name) + 2 > sizeof(whole_path)) - error (1, 0, _("Overflow of stat buffer\n")); - - /* Generate the complete ASCII path for this file */ - strcpy(whole_path, path); -#ifndef VMS - if(whole_path[strlen(whole_path)-1] != '/') - strcat(whole_path, "/"); -#endif - strcat(whole_path, d_entry->d_name); - - /** Should we exclude this file ? */ - if (matches(d_entry->d_name) || matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Excluded by match: %s\n"), whole_path); - } - continue; - } - - if( generate_tables - && strcmp(d_entry->d_name, "TRANS.TBL") == 0 ) - { - /* - * Ignore this entry. We are going to be generating new - * versions of these files, and we need to ignore any - * originals that we might have found. - */ - if (verbose > 1) - { - fprintf (stderr, _("Excluded: %s\n"), whole_path); - } - continue; - } - - /* - * If we already have a '.' or a '..' entry, then don't - * insert new ones. - */ - if( strcmp(d_entry->d_name, ".") == 0 - && this_dir->dir_flags & DIR_HAS_DOT ) - { - continue; - } - - if( strcmp(d_entry->d_name, "..") == 0 - && this_dir->dir_flags & DIR_HAS_DOTDOT ) - { - continue; - } - -#if 0 - if (verbose > 1) fprintf(stderr, "%s\n",whole_path); -#endif - /* - * This actually adds the entry to the directory in question. - */ - insert_file_entry(this_dir, whole_path, d_entry->d_name); - } - closedir(current_dir); - - return 1; -} - - -/* - * Function: insert_file_entry - * - * Purpose: Insert one entry into our directory node. - * - * Note: - * This function inserts a single entry into the directory. It - * is assumed that all filtering and decision making regarding what - * we want to include has already been made, so the purpose of this - * is to insert one entry (file, link, dir, etc), into this directory. - * Note that if the entry is a dir (or if we are following links, - * and the thing it points to is a dir), then we will scan those - * trees before we return. - */ -int -FDECL3(insert_file_entry,struct directory *, this_dir, - char *, whole_path, - char *, short_name) -{ - struct stat statbuf, lstatbuf; - struct directory_entry * s_entry, *s_entry1; - int lstatus; - int status; - int deep_flag; - - status = stat_filter(whole_path, &statbuf); - - lstatus = lstat_filter(whole_path, &lstatbuf); - - if( (status == -1) && (lstatus == -1) ) - { - /* - * This means that the file doesn't exist, or isn't accessible. - * Sometimes this is because of NFS permissions problems. - */ - fprintf (stderr, _("Non-existant or inaccessible: %s\n"),whole_path); - return 0; - } - - if(this_dir == root && strcmp(short_name, ".") == 0) - root_statbuf = statbuf; /* Save this for later on */ - - /* We do this to make sure that the root entries are consistent */ - if(this_dir == root && strcmp(short_name, "..") == 0) - { - statbuf = root_statbuf; - lstatbuf = root_statbuf; - } - - if(S_ISLNK(lstatbuf.st_mode)) - { - - /* Here we decide how to handle the symbolic links. Here - we handle the general case - if we are not following - links or there is an error, then we must change - something. If RR is in use, it is easy, we let RR - describe the file. If not, then we punt the file. */ - - if((status || !follow_links)) - { - if(use_RockRidge) - { - status = 0; - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } else { - if(follow_links) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - } - else - { - fprintf (stderr, - _("Symlink %s ignored - continuing.\n"), - whole_path); - return 0; /* Non Rock Ridge discs - ignore all symlinks */ - } - } - } - - /* Here we handle a different kind of case. Here we have - a symlink, but we want to follow symlinks. If we run - across a directory loop, then we need to pretend that - we are not following symlinks for this file. If this - is the first time we have seen this, then make this - seem as if there was no symlink there in the first - place */ - - if( follow_links - && S_ISDIR(statbuf.st_mode) ) - { - if( strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - { - if(!use_RockRidge) - { - fprintf (stderr, _("Already cached directory seen (%s)\n"), - whole_path); - return 0; - } - statbuf.st_size = 0; - STAT_INODE(statbuf) = UNCACHED_INODE; - statbuf.st_dev = (dev_t) UNCACHED_DEVICE; - statbuf.st_mode = (statbuf.st_mode & ~S_IFMT) | S_IFREG; - } - else - { - lstatbuf = statbuf; - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - } - } - - /* - * For non-directories, we just copy the stat information over - * so we correctly include this file. - */ - if( follow_links - && !S_ISDIR(statbuf.st_mode) ) - { - lstatbuf = statbuf; - } - } - - /* - * Add directories to the cache so that we don't waste space even - * if we are supposed to be following symlinks. - */ - if( follow_links - && strcmp(short_name, ".") - && strcmp(short_name, "..") - && S_ISDIR(statbuf.st_mode) ) - { - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if(S_ISREG(lstatbuf.st_mode) && (status = access(whole_path, R_OK))) - { - fprintf (stderr, _("File %s is not readable (%s) - ignoring\n"), - whole_path, strerror (errno)); - return 0; - } - - /* Add this so that we can detect directory loops with hard links. - If we are set up to follow symlinks, then we skip this checking. */ - if( !follow_links - && S_ISDIR(lstatbuf.st_mode) - && strcmp(short_name, ".") - && strcmp(short_name, "..") ) - { - if(find_directory_hash(statbuf.st_dev, STAT_INODE(statbuf))) - error (1, 0, _("Directory loop - fatal goof (%s %lx %lu).\n"), - whole_path, (unsigned long) statbuf.st_dev, - (unsigned long) STAT_INODE(statbuf)); - add_directory_hash(statbuf.st_dev, STAT_INODE(statbuf)); - } - - if (!S_ISCHR(lstatbuf.st_mode) && !S_ISBLK(lstatbuf.st_mode) && - !S_ISFIFO(lstatbuf.st_mode) && !S_ISSOCK(lstatbuf.st_mode) - && !S_ISLNK(lstatbuf.st_mode) && !S_ISREG(lstatbuf.st_mode) && - !S_ISDIR(lstatbuf.st_mode)) { - fprintf (stderr, _("Unknown file type %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* Who knows what trash this is - ignore and continue */ - - if(status) - { - fprintf (stderr, - _("Unable to stat file %s - ignoring and continuing.\n"), - whole_path); - return 0; - } - - /* - * Check to see if we have already seen this directory node. - * If so, then we don't create a new entry for it, but we do want - * to recurse beneath it and add any new files we do find. - */ - if (S_ISDIR(statbuf.st_mode)) - { - int dflag; - - for( s_entry = this_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - if ( s_entry != NULL - && strcmp(short_name,".") - && strcmp(short_name,"..")) - { - struct directory * child; - - if ( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0) - { - for( s_entry = reloc_dir->contents; s_entry; s_entry = s_entry->next) - { - if( strcmp(s_entry->name, short_name) == 0 ) - { - break; - } - } - child = find_or_create_directory(reloc_dir, whole_path, - s_entry, 1); - } - else - { - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - /* If unable to scan directory, mark this as a non-directory */ - } - dflag = scan_directory_tree(child, whole_path, s_entry); - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - } - return 0; - } - } - - s_entry = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - s_entry->next = this_dir->contents; - memset(s_entry->isorec.extent, 0, 8); - this_dir->contents = s_entry; - deep_flag = 0; - s_entry->table = NULL; - - s_entry->name = strdup(short_name); - s_entry->whole_name = strdup (whole_path); - - s_entry->de_flags = 0; - - /* - * If the current directory is hidden, then hide all it's members - * otherwise check if this entry needs to be hidden as well */ - if (this_dir->dir_flags & INHIBIT_ISO9660_ENTRY) { - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (i_matches(short_name) || i_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from ISO9660 tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_ISO9660_ENTRY; - } - } - - if (this_dir != reloc_dir && this_dir->dir_flags & INHIBIT_JOLIET_ENTRY) { - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - else if (strcmp(short_name,".") && strcmp(short_name,"..")) { - if (j_matches(short_name) || j_matches(whole_path)) { - if (verbose > 1) { - fprintf (stderr, _("Hidden from Joliet tree: %s\n"), whole_path); - } - s_entry->de_flags |= INHIBIT_JOLIET_ENTRY; - } - } - - s_entry->filedir = this_dir; - s_entry->isorec.flags[0] = 0; - s_entry->isorec.ext_attr_length[0] = 0; - iso9660_date(s_entry->isorec.date, statbuf.st_mtime); - s_entry->isorec.file_unit_size[0] = 0; - s_entry->isorec.interleave[0] = 0; - - if( strcmp(short_name, ".") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOT; - } - - if( strcmp(short_name, "..") == 0) - { - this_dir->dir_flags |= DIR_HAS_DOTDOT; - } - - if( this_dir->parent - && this_dir->parent == reloc_dir - && strcmp(short_name, "..") == 0) - { - s_entry->inode = UNCACHED_INODE; - s_entry->dev = (dev_t) UNCACHED_DEVICE; - deep_flag = NEED_PL; - } - else - { - s_entry->inode = STAT_INODE(statbuf); - s_entry->dev = statbuf.st_dev; - } - set_723(s_entry->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length(short_name, s_entry, S_ISDIR(statbuf.st_mode)); - s_entry->rr_attr_size = 0; - s_entry->total_rr_attr_size = 0; - s_entry->rr_attributes = NULL; - - /* Directories are assigned sizes later on */ - if (!S_ISDIR(statbuf.st_mode)) - { - if (S_ISCHR(lstatbuf.st_mode) || S_ISBLK(lstatbuf.st_mode) || - S_ISFIFO(lstatbuf.st_mode) || S_ISSOCK(lstatbuf.st_mode) - || S_ISLNK(lstatbuf.st_mode)) - { - s_entry->size = 0; - statbuf.st_size = 0; - } - else - { - s_entry->size = statbuf.st_size; - } - - set_733((char *) s_entry->isorec.size, statbuf.st_size); - } - else - { - s_entry->isorec.flags[0] = 2; - } - - if (strcmp(short_name,".") && strcmp(short_name,"..") && - S_ISDIR(statbuf.st_mode) && this_dir->depth > RR_relocation_depth) - { - struct directory * child; - - if(!reloc_dir) generate_reloc_directory(); - - /* - * Replicate the entry for this directory. The old one will stay where it - * is, and it will be neutered so that it no longer looks like a directory. - * The new one will look like a directory, and it will be put in the reloc_dir. - */ - s_entry1 = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memcpy(s_entry1, s_entry, sizeof(struct directory_entry)); - s_entry1->table = NULL; - s_entry1->name = strdup(this_dir->contents->name); - s_entry1->whole_name = strdup(this_dir->contents->whole_name); - s_entry1->next = reloc_dir->contents; - reloc_dir->contents = s_entry1; - s_entry1->priority = 32768; - s_entry1->parent_rec = this_dir->contents; - - deep_flag = NEED_RE; - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry1, - &statbuf, &lstatbuf, deep_flag); - } - - deep_flag = 0; - - /* We need to set this temporarily so that the parent to this - is correctly determined. */ - s_entry1->filedir = reloc_dir; - child = find_or_create_directory(reloc_dir, whole_path, - s_entry1, 0); - scan_directory_tree(child, whole_path, s_entry1); - s_entry1->filedir = this_dir; - - statbuf.st_size = 0; - statbuf.st_mode &= 0777; - set_733((char *) s_entry->isorec.size, 0); - s_entry->size = 0; - s_entry->isorec.flags[0] = 0; - s_entry->inode = UNCACHED_INODE; - s_entry->de_flags |= RELOCATED_DIRECTORY; - deep_flag = NEED_CL; - } - - if(generate_tables - && strcmp(s_entry->name, ".") - && strcmp(s_entry->name, "..")) - { - char buffer[2048]; - int nchar; - switch(lstatbuf.st_mode & S_IFMT) - { - case S_IFDIR: - sprintf(buffer,"D\t%s\n", - s_entry->name); - break; -#ifdef S_IFBLK -/* extra for WIN32 - if it doesn't have the major/minor defined, then - S_IFBLK and S_IFCHR type files are unlikely to exist anyway ... - code similar to that in rock.c */ - -/* for some reason, MAJOR_IN_SYSMACROS isn't defined on a SunOS when - it should be, so see if major() is defined instead */ -/* -#if !(defined(MAJOR_IN_SYSMACROS) || defined(MAJOR_IN_MKDEV)) -*/ -#ifndef major -#define major(dev) (sizeof(dev_t) <= 2 ? ((dev) >> 8) : \ - (sizeof(dev_t) <= 4 ? (((dev) >> 8) >> 8) : \ - (((dev) >> 16) >> 16))) -#define minor(dev) (sizeof(dev_t) <= 2 ? (dev) & 0xff : \ - (sizeof(dev_t) <= 4 ? (dev) & 0xffff : \ - (dev) & 0xffffffff)) -#endif - case S_IFBLK: - sprintf(buffer,"B\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFIFO - case S_IFIFO: - sprintf(buffer,"P\t%s\n", - s_entry->name); - break; -#endif -#ifdef S_IFCHR - case S_IFCHR: - sprintf(buffer,"C\t%s\t%lu %lu\n", - s_entry->name, - (unsigned long) major(statbuf.st_rdev), - (unsigned long) minor(statbuf.st_rdev)); - break; -#endif -#ifdef S_IFLNK - case S_IFLNK: - nchar = readlink(whole_path, - (char *)symlink_buff, - sizeof(symlink_buff)); - symlink_buff[nchar < 0 ? 0 : nchar] = 0; - sprintf(buffer,"L\t%s\t%s\n", - s_entry->name, symlink_buff); - break; -#endif -#ifdef S_IFSOCK - case S_IFSOCK: - sprintf(buffer,"S\t%s\n", - s_entry->name); - break; -#endif - case S_IFREG: - default: - sprintf(buffer,"F\t%s\n", - s_entry->name); - break; - }; - s_entry->table = strdup(buffer); - } - - if(S_ISDIR(statbuf.st_mode)) - { - int dflag; - if (strcmp(short_name,".") && strcmp(short_name,"..")) - { - struct directory * child; - - child = find_or_create_directory(this_dir, whole_path, - s_entry, 1); - dflag = scan_directory_tree(child, whole_path, s_entry); - - if(!dflag) - { - lstatbuf.st_mode = (lstatbuf.st_mode & ~S_IFMT) | S_IFREG; - if( child->contents == NULL ) - { - delete_directory(this_dir, child); - } - } - } - /* If unable to scan directory, mark this as a non-directory */ - } - - if(use_RockRidge && this_dir == root && strcmp(s_entry->name, ".") == 0) - { - deep_flag |= NEED_CE | NEED_SP; /* For extension record */ - } - - /* Now figure out how much room this file will take in the - directory */ - - if(use_RockRidge) - { - generate_rock_ridge_attributes(whole_path, - short_name, s_entry, - &statbuf, &lstatbuf, deep_flag); - - } - - return 1; -} - - -void FDECL2(generate_iso9660_directories, struct directory *, node, FILE*, outfile){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - if( dpnt->extent > session_start ) - { - generate_one_directory(dpnt, outfile); - } - if(dpnt->subdir) generate_iso9660_directories(dpnt->subdir, outfile); - dpnt = dpnt->next; - } -} - -/* - * Function: find_or_create_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -struct directory * FDECL4(find_or_create_directory, struct directory *, parent, - const char *, path, - struct directory_entry *, de, int, flag) -{ - struct directory * dpnt; - struct directory_entry * orig_de; - struct directory * next_brother; - const char * cpnt; - const char * pnt; - - orig_de = de; - - pnt = strrchr(path, PATH_SEPARATOR); - if( pnt == NULL ) - { - pnt = path; - } - else - { - pnt++; - } - - if( parent != NULL ) - { - dpnt = parent->subdir; - - while (dpnt) - { - /* - * Weird hack time - if there are two directories by the - * same name in the reloc_dir, they are not treated as the - * same thing unless the entire path matches completely. - */ - if( flag && strcmp(dpnt->de_name, pnt) == 0 ) - { - return dpnt; - } - dpnt = dpnt->next; - } - } - - /* - * We don't know if we have a valid directory entry for this one - * yet. If not, we need to create one. - */ - if( de == NULL ) - { - de = (struct directory_entry *) - e_malloc(sizeof (struct directory_entry)); - memset(de, 0, sizeof(struct directory_entry)); - de->next = parent->contents; - parent->contents = de; - de->name = strdup(pnt); - de->filedir = parent; - de->isorec.flags[0] = 2; - de->priority = 32768; - de->inode = UNCACHED_INODE; - de->dev = (dev_t) UNCACHED_DEVICE; - set_723(de->isorec.volume_sequence_number, volume_sequence_number); - iso9660_file_length (pnt, de, 1); - - init_fstatbuf(); - /* - * It doesn't exist for real, so we cannot add any Rock Ridge. - */ - if(use_RockRidge) - { - fstatbuf.st_mode = 0555 | S_IFDIR; - fstatbuf.st_nlink = 2; - generate_rock_ridge_attributes("", - (char *) pnt, de, - &fstatbuf, - &fstatbuf, 0); - } - iso9660_date(de->isorec.date, fstatbuf.st_mtime); - - } - - /* - * If we don't have a directory for this one yet, then allocate it - * now, and patch it into the tree in the appropriate place. - */ - dpnt = (struct directory *) e_malloc(sizeof(struct directory)); - memset(dpnt, 0, sizeof(struct directory)); - dpnt->next = NULL; - dpnt->subdir = NULL; - dpnt->self = de; - dpnt->contents = NULL; - dpnt->whole_name = strdup(path); - cpnt = strrchr(path, PATH_SEPARATOR); - if(cpnt) - cpnt++; - else - cpnt = path; - dpnt->de_name = strdup(cpnt); - dpnt->size = 0; - dpnt->extent = 0; - dpnt->jextent = 0; - dpnt->jsize = 0; - - if( orig_de == NULL ) - { - struct stat xstatbuf; - int sts; - - /* - * Now add a . and .. entry in the directory itself. - * This is a little tricky - if the real directory - * exists, we need to stat it first. Otherwise, we - * use the fictitious fstatbuf which points to the time - * at which mkisofs was started. - */ - sts = stat_filter(parent->whole_name, &xstatbuf); - if( sts == 0 ) - { - attach_dot_entries(dpnt, &xstatbuf); - } - else - { - attach_dot_entries(dpnt, &fstatbuf); - } - } - - if(!parent || parent == root) - { - if (!root) - { - root = dpnt; /* First time through for root directory only */ - root->depth = 0; - root->parent = root; - } else { - dpnt->depth = 1; - if(!root->subdir) - { - root->subdir = dpnt; - } - else - { - next_brother = root->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - dpnt->parent = parent; - } - } - else - { - /* Come through here for normal traversal of tree */ -#ifdef DEBUG - fprintf(stderr,"%s(%d) ", path, dpnt->depth); -#endif - if(parent->depth > RR_relocation_depth) - error (1, 0, _("Directories too deep %s\n"), path); - - dpnt->parent = parent; - dpnt->depth = parent->depth + 1; - - if(!parent->subdir) - { - parent->subdir = dpnt; - } - else - { - next_brother = parent->subdir; - while(next_brother->next) next_brother = next_brother->next; - next_brother->next = dpnt; - } - } - - return dpnt; -} - -/* - * Function: delete_directory - * - * Purpose: Locate a directory entry in the tree, create if needed. - * - * Arguments: - */ -static void FDECL2(delete_directory, struct directory *, parent, struct directory *, child) -{ - struct directory * tdir; - - if( child->contents != NULL ) - error (1, 0, _("Unable to delete non-empty directory\n")); - - free(child->whole_name); - child->whole_name = NULL; - - free(child->de_name); - child->de_name = NULL; - - if( parent->subdir == child ) - { - parent->subdir = child->next; - } - else - { - for( tdir = parent->subdir; tdir->next != NULL; tdir = tdir->next ) - { - if( tdir->next == child ) - { - tdir->next = child->next; - break; - } - } - if( tdir == NULL ) - error (1, 0, _("Unable to locate child directory in parent list\n")); - } - free(child); - return; -} - -int FDECL1(sort_tree, struct directory *, node){ - struct directory * dpnt; - int ret = 0; - - dpnt = node; - - while (dpnt){ - ret = sort_n_finish(dpnt); - if( ret ) - { - break; - } - - if(dpnt->subdir) sort_tree(dpnt->subdir); - dpnt = dpnt->next; - } - return ret; -} - -void FDECL1(dump_tree, struct directory *, node){ - struct directory * dpnt; - - dpnt = node; - - while (dpnt){ - fprintf(stderr,"%4d %5d %s\n",dpnt->extent, dpnt->size, dpnt->de_name); - if(dpnt->subdir) dump_tree(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL1(update_nlink_field, struct directory *, node) -{ - struct directory * dpnt; - struct directory * xpnt; - struct directory_entry * s_entry; - int i; - - dpnt = node; - - while (dpnt) - { - if (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * First, count up the number of subdirectories this guy has. - */ - for(i=0, xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - if ((xpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0) - i++; - /* - * Next check to see if we have any relocated directories - * in this directory. The nlink field will include these - * as real directories when they are properly relocated. - * - * In the non-rockridge disk, the relocated entries appear - * as zero length files. - */ - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - if( (s_entry->de_flags & RELOCATED_DIRECTORY) != 0 && - (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) == 0) - { - i++; - } - } - /* - * Now update the field in the Rock Ridge entry. - */ - update_nlink(dpnt->self, i + 2); - - /* - * Update the '.' entry for this directory. - */ - update_nlink(dpnt->contents, i + 2); - - /* - * Update all of the '..' entries that point to this guy. - */ - for(xpnt = dpnt->subdir; xpnt; xpnt = xpnt->next) - update_nlink(xpnt->contents->next, i + 2); - - if(dpnt->subdir) update_nlink_field(dpnt->subdir); - dpnt = dpnt->next; - } -} - -/* - * something quick and dirty to locate a file given a path - * recursively walks down path in filename until it finds the - * directory entry for the desired file - */ -struct directory_entry * FDECL2(search_tree_file, struct directory *, - node,char *, filename) -{ - struct directory_entry * depnt; - struct directory * dpnt; - char * p1; - char * rest; - char * subdir; - - /* - * strip off next directory name from filename - */ - subdir = strdup(filename); - - if( (p1=strchr(subdir, '/')) == subdir ) - { - fprintf (stderr, _("call to search_tree_file with an absolute path, stripping\n")); - fprintf (stderr, _("initial path separator. Hope this was intended...\n")); - memmove(subdir, subdir+1, strlen(subdir)-1); - p1 = strchr(subdir, '/'); - } - - /* - * do we need to find a subdirectory - */ - if (p1) - { - *p1 = '\0'; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Looking for subdir called %s\n",p1); -#endif - - rest = p1+1; - -#ifdef DEBUG_TORITO - fprintf(stderr,"Remainder of path name is now %s\n", rest); -#endif - - dpnt = node->subdir; - while( dpnt ) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n", dpnt->extent, dpnt->size, - dpnt->de_name); -#endif - if (!strcmp(subdir, dpnt->de_name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Calling next level with filename = %s", rest); -#endif - return(search_tree_file( dpnt, rest )); - } - dpnt = dpnt->next; - } - - /* if we got here means we couldnt find the subdir */ - return (NULL); - } - else - { - /* - * look for a normal file now - */ - depnt = node->contents; - while (depnt) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"%4d %5d %s\n",depnt->isorec.extent, - depnt->size, depnt->name); -#endif - if (!strcmp(filename, depnt->name)) - { -#ifdef DEBUG_TORITO - fprintf(stderr,"Found our file %s", filename); -#endif - return(depnt); - } - depnt = depnt->next; - } - /* - * if we got here means we couldnt find the subdir - */ - return (NULL); - } - fprintf (stderr, "We cant get here in search_tree_file :-/ \n"); -} - -void init_fstatbuf() -{ - time_t current_time; - - if(fstatbuf.st_ctime == 0) - { - time (¤t_time); - if( rationalize ) - { - fstatbuf.st_uid = 0; - fstatbuf.st_gid = 0; - } - else - { - fstatbuf.st_uid = getuid(); - fstatbuf.st_gid = getgid(); - } - fstatbuf.st_ctime = current_time; - fstatbuf.st_mtime = current_time; - fstatbuf.st_atime = current_time; - } -} diff --git a/util/mkisofs/write.c b/util/mkisofs/write.c deleted file mode 100644 index e1cdd213e..000000000 --- a/util/mkisofs/write.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* - * Program write.c - dump memory structures to file for iso9660 filesystem. - - Written by Eric Youngdale (1993). - - Copyright 1993 Yggdrasil Computing, Incorporated - - Copyright (C) 2009 Free Software Foundation, Inc. - - This program 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, or (at your option) - any later version. - - This program 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 this program; if not, see . - */ - -#include "config.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "mkisofs.h" -#include "iso9660.h" -#include "msdos_partition.h" - -#ifdef __SVR4 -extern char * strdup(const char *); -#endif - -#ifdef VMS -extern char * strdup(const char *); -#endif - - -/* Max number of sectors we will write at one time */ -#define NSECT 16 - -/* Counters for statistics */ - -static int table_size = 0; -static int total_dir_size = 0; -static int rockridge_size = 0; -static struct directory ** pathlist; -static int next_path_index = 1; -static int sort_goof; - -struct output_fragment * out_tail; -struct output_fragment * out_list; - -struct iso_primary_descriptor vol_desc; - -static int root_gen __PR((void)); -static int generate_path_tables __PR((void)); -static int file_gen __PR((void)); -static int dirtree_dump __PR((void)); - -/* Routines to actually write the disc. We write sequentially so that - we could write a tape, or write the disc directly */ - - -#define FILL_SPACE(X) memset(vol_desc.X, ' ', sizeof(vol_desc.X)) - -void FDECL2(set_721, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_722, char *, pnt, unsigned int, i) -{ - pnt[0] = (i >> 8) & 0xff; - pnt[1] = i & 0xff; -} - -void FDECL2(set_723, char *, pnt, unsigned int, i) -{ - pnt[3] = pnt[0] = i & 0xff; - pnt[2] = pnt[1] = (i >> 8) & 0xff; -} - -void FDECL2(set_731, char *, pnt, unsigned int, i) -{ - pnt[0] = i & 0xff; - pnt[1] = (i >> 8) & 0xff; - pnt[2] = (i >> 16) & 0xff; - pnt[3] = (i >> 24) & 0xff; -} - -void FDECL2(set_732, char *, pnt, unsigned int, i) -{ - pnt[3] = i & 0xff; - pnt[2] = (i >> 8) & 0xff; - pnt[1] = (i >> 16) & 0xff; - pnt[0] = (i >> 24) & 0xff; -} - -int FDECL1(get_731, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -int FDECL1(get_733, char *, p) -{ - return ((p[0] & 0xff) - | ((p[1] & 0xff) << 8) - | ((p[2] & 0xff) << 16) - | ((p[3] & 0xff) << 24)); -} - -void FDECL2(set_733, char *, pnt, unsigned int, i) -{ - pnt[7] = pnt[0] = i & 0xff; - pnt[6] = pnt[1] = (i >> 8) & 0xff; - pnt[5] = pnt[2] = (i >> 16) & 0xff; - pnt[4] = pnt[3] = (i >> 24) & 0xff; -} - -void FDECL4(xfwrite, void *, buffer, uint64_t, count, uint64_t, size, FILE *, file) -{ - /* - * This is a hack that could be made better. XXXIs this the only place? - * It is definitely needed on Operating Systems that do not - * allow to write files that are > 2GB. - * If the system is fast enough to be able to feed 1400 KB/s - * writing speed of a DVD-R drive, use stdout. - * If the system cannot do this reliable, you need to use this - * hacky option. - */ - static int idx = 0; - if (split_output != 0 && - (idx == 0 || ftell(file) >= (1024 * 1024 * 1024) )) { - char nbuf[512]; - extern char *outfile; - - if (idx == 0) - unlink(outfile); - sprintf(nbuf, "%s_%02d", outfile, idx++); - file = freopen(nbuf, "wb", file); - if (file == NULL) - error (1, errno, _("Cannot open `%s'"), nbuf); - - } - while(count) - { - size_t got = fwrite (buffer, size, count, file); - - if (got != count) - error (1, errno, _("cannot fwrite %llu*%llu\n"), size, count); - count-=got,*(char**)&buffer+=size*got; - } -} - -struct deferred_write -{ - struct deferred_write * next; - char * table; - uint64_t extent; - uint64_t size; - char * name; -}; - -static struct deferred_write * dw_head = NULL, * dw_tail = NULL; - -uint64_t last_extent_written = 0; -static unsigned int path_table_index; -static time_t begun; - -/* We recursively walk through all of the directories and assign extent - numbers to them. We have already assigned extent numbers to everything that - goes in front of them */ - -static int FDECL1(assign_directory_addresses, struct directory *, node) -{ - int dir_size; - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if(dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) { - dpnt = dpnt->next; - continue; - } - - /* - * If we already have an extent for this (i.e. it came from - * a multisession disc), then don't reassign a new extent. - */ - dpnt->path_index = next_path_index++; - if( dpnt->extent == 0 ) - { - dpnt->extent = last_extent; - dir_size = (dpnt->size + (SECTOR_SIZE - 1)) >> 11; - - last_extent += dir_size; - - /* - * Leave room for the CE entries for this directory. Keep them - * close to the reference directory so that access will be - * quick. - */ - if(dpnt->ce_bytes) - { - last_extent += ROUND_UP(dpnt->ce_bytes) >> 11; - } - } - - if(dpnt->subdir) - { - assign_directory_addresses(dpnt->subdir); - } - - dpnt = dpnt->next; - } - return 0; -} - -static void FDECL3(write_one_file, char *, filename, - uint64_t, size, FILE *, outfile) -{ - char buffer[SECTOR_SIZE * NSECT]; - FILE * infile; - int64_t remain; - size_t use; - - - if ((infile = fopen(filename, "rb")) == NULL) - error (1, errno, _("cannot open %s\n"), filename); - remain = size; - - while(remain > 0) - { - use = (remain > SECTOR_SIZE * NSECT - 1 ? NSECT*SECTOR_SIZE : remain); - use = ROUND_UP(use); /* Round up to nearest sector boundary */ - memset(buffer, 0, use); - if (fread(buffer, 1, use, infile) == 0) - error (1, errno, _("cannot read %llu bytes from %s"), use, filename); - xfwrite(buffer, 1, use, outfile); - last_extent_written += use/SECTOR_SIZE; -#if 0 - if((last_extent_written % 1000) < use/SECTOR_SIZE) - { - fprintf(stderr,"%d..", last_extent_written); - } -#else - if((last_extent_written % 5000) < use/SECTOR_SIZE) - { - time_t now; - time_t the_end; - double frac; - - time(&now); - frac = last_extent_written / (double)last_extent; - the_end = begun + (now - begun) / frac; - fprintf (stderr, _("%6.2f%% done, estimate finish %s"), - frac * 100., ctime(&the_end)); - } -#endif - remain -= use; - } - fclose(infile); -} /* write_one_file(... */ - -static void FDECL1(write_files, FILE *, outfile) -{ - struct deferred_write * dwpnt, *dwnext; - dwpnt = dw_head; - while(dwpnt) - { - if(dwpnt->table) - { - write_one_file (dwpnt->table, dwpnt->size, outfile); - table_size += dwpnt->size; - free (dwpnt->table); - } - else - { - -#ifdef VMS - vms_write_one_file(dwpnt->name, dwpnt->size, outfile); -#else - write_one_file(dwpnt->name, dwpnt->size, outfile); -#endif - free(dwpnt->name); - } - - dwnext = dwpnt; - dwpnt = dwpnt->next; - free(dwnext); - } -} /* write_files(... */ - -#if 0 -static void dump_filelist() -{ - struct deferred_write * dwpnt; - dwpnt = dw_head; - while(dwpnt) - { - fprintf(stderr, "File %s\n",dwpnt->name); - dwpnt = dwpnt->next; - } - fprintf(stderr,"\n"); -} -#endif - -static int FDECL2(compare_dirs, const void *, rr, const void *, ll) -{ - char * rpnt, *lpnt; - struct directory_entry ** r, **l; - - r = (struct directory_entry **) rr; - l = (struct directory_entry **) ll; - rpnt = (*r)->isorec.name; - lpnt = (*l)->isorec.name; - - /* - * If the entries are the same, this is an error. - */ - if( strcmp(rpnt, lpnt) == 0 ) - { - sort_goof++; - } - - /* - * Put the '.' and '..' entries on the head of the sorted list. - * For normal ASCII, this always happens to be the case, but out of - * band characters cause this not to be the case sometimes. - * - * FIXME(eric) - these tests seem redundant, in taht the name is - * never assigned these values. It will instead be \000 or \001, - * and thus should always be sorted correctly. I need to figure - * out why I thought I needed this in the first place. - */ -#if 0 - if( strcmp(rpnt, ".") == 0 ) return -1; - if( strcmp(lpnt, ".") == 0 ) return 1; - - if( strcmp(rpnt, "..") == 0 ) return -1; - if( strcmp(lpnt, "..") == 0 ) return 1; -#else - /* - * The code above is wrong (as explained in Eric's comment), leading to incorrect - * sort order iff the -L option ("allow leading dots") is in effect and a directory - * contains entries that start with a dot. - * - * (TF, Tue Dec 29 13:49:24 CET 1998) - */ - if((*r)->isorec.name_len[0] == 1 && *rpnt == 0) return -1; /* '.' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 0) return 1; - - if((*r)->isorec.name_len[0] == 1 && *rpnt == 1) return -1; /* '..' */ - if((*l)->isorec.name_len[0] == 1 && *lpnt == 1) return 1; -#endif - - while(*rpnt && *lpnt) - { - if(*rpnt == ';' && *lpnt != ';') return -1; - if(*rpnt != ';' && *lpnt == ';') return 1; - - if(*rpnt == ';' && *lpnt == ';') return 0; - - if(*rpnt == '.' && *lpnt != '.') return -1; - if(*rpnt != '.' && *lpnt == '.') return 1; - - if((unsigned char)*rpnt < (unsigned char)*lpnt) return -1; - if((unsigned char)*rpnt > (unsigned char)*lpnt) return 1; - rpnt++; lpnt++; - } - if(*rpnt) return 1; - if(*lpnt) return -1; - return 0; -} - -/* - * Function: sort_directory - * - * Purpose: Sort the directory in the appropriate ISO9660 - * order. - * - * Notes: Returns 0 if OK, returns > 0 if an error occurred. - */ -int FDECL1(sort_directory, struct directory_entry **, sort_dir) -{ - int dcount = 0; - int xcount = 0; - int j; - int i, len; - struct directory_entry * s_entry; - struct directory_entry ** sortlist; - - /* need to keep a count of how many entries are hidden */ - s_entry = *sort_dir; - while(s_entry) - { - if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - xcount++; - dcount++; - s_entry = s_entry->next; - } - - if( dcount == 0 ) - { - return 0; - } - - /* - * OK, now we know how many there are. Build a vector for sorting. - */ - sortlist = (struct directory_entry **) - e_malloc(sizeof(struct directory_entry *) * dcount); - - j = dcount - 1; - dcount = 0; - s_entry = *sort_dir; - while(s_entry) - { - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) - { - /* put any hidden entries at the end of the vector */ - sortlist[j--] = s_entry; - } - else - { - sortlist[dcount] = s_entry; - dcount++; - } - len = s_entry->isorec.name_len[0]; - s_entry->isorec.name[len] = 0; - s_entry = s_entry->next; - } - - /* - * Each directory is required to contain at least . and .. - */ - if( dcount < 2 ) - { - sort_goof = 1; - - } - else - { - /* only sort the non-hidden entries */ - sort_goof = 0; -#ifdef __STDC__ - qsort(sortlist, dcount, sizeof(struct directory_entry *), - (int (*)(const void *, const void *))compare_dirs); -#else - qsort(sortlist, dcount, sizeof(struct directory_entry *), - compare_dirs); -#endif - - /* - * Now reassemble the linked list in the proper sorted order - * We still need the hidden entries, as they may be used in the - * Joliet tree. - */ - for(i=0; inext = sortlist[i+1]; - } - - sortlist[dcount+xcount-1]->next = NULL; - *sort_dir = sortlist[0]; - } - - free(sortlist); - return sort_goof; -} - -static int root_gen() -{ - init_fstatbuf(); - - root_record.length[0] = 1 + sizeof(struct iso_directory_record) - - sizeof(root_record.name); - root_record.ext_attr_length[0] = 0; - set_733((char *) root_record.extent, root->extent); - set_733((char *) root_record.size, ROUND_UP(root->size)); - iso9660_date(root_record.date, root_statbuf.st_mtime); - root_record.flags[0] = 2; - root_record.file_unit_size[0] = 0; - root_record.interleave[0] = 0; - set_723(root_record.volume_sequence_number, volume_sequence_number); - root_record.name_len[0] = 1; - return 0; -} - -static void FDECL1(assign_file_addresses, struct directory *, dpnt) -{ - struct directory * finddir; - struct directory_entry * s_entry; - struct file_hash *s_hash; - struct deferred_write * dwpnt; - char whole_path[1024]; - - while (dpnt) - { - s_entry = dpnt->contents; - for(s_entry = dpnt->contents; s_entry; s_entry = s_entry->next) - { - /* - * If we already have an extent for this entry, - * then don't assign a new one. It must have come - * from a previous session on the disc. Note that - * we don't end up scheduling the thing for writing - * either. - */ - if( isonum_733((unsigned char *) s_entry->isorec.extent) != 0 ) - { - continue; - } - - /* - * This saves some space if there are symlinks present - */ - s_hash = find_hash(s_entry->dev, s_entry->inode); - if(s_hash) - { - if(verbose > 2) - { - fprintf (stderr, _("Cache hit for %s%s%s\n"), s_entry->filedir->de_name, - SPATH_SEPARATOR, s_entry->name); - } - set_733((char *) s_entry->isorec.extent, s_hash->starting_block); - set_733((char *) s_entry->isorec.size, s_hash->size); - continue; - } - - /* - * If this is for a directory that is not a . or a .. entry, - * then look up the information for the entry. We have already - * assigned extents for directories, so we just need to - * fill in the blanks here. - */ - if (strcmp(s_entry->name,".") && strcmp(s_entry->name,"..") && - s_entry->isorec.flags[0] == 2) - { - finddir = dpnt->subdir; - while(1==1) - { - if(finddir->self == s_entry) break; - finddir = finddir->next; - if (!finddir) - error (1, 0, _("Fatal goof\n")); - } - set_733((char *) s_entry->isorec.extent, finddir->extent); - s_entry->starting_block = finddir->extent; - s_entry->size = ROUND_UP(finddir->size); - total_dir_size += s_entry->size; - add_hash(s_entry); - set_733((char *) s_entry->isorec.size, ROUND_UP(finddir->size)); - continue; - } - - - /* - * If this is . or .., then look up the relevant info from the - * tables. - */ - if(strcmp(s_entry->name,".") == 0) - { - set_733((char *) s_entry->isorec.extent, dpnt->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->extent; - s_entry->size = ROUND_UP(dpnt->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->size)); - continue; - } - - if(strcmp(s_entry->name,"..") == 0) - { - if(dpnt == root) - { - total_dir_size += root->size; - } - set_733((char *) s_entry->isorec.extent, dpnt->parent->extent); - - /* - * Set these so that the hash table has the - * correct information - */ - s_entry->starting_block = dpnt->parent->extent; - s_entry->size = ROUND_UP(dpnt->parent->size); - - add_hash(s_entry); - s_entry->starting_block = dpnt->parent->extent; - set_733((char *) s_entry->isorec.size, ROUND_UP(dpnt->parent->size)); - continue; - } - - /* - * Some ordinary non-directory file. Just schedule the - * file to be written. This is all quite - * straightforward, just make a list and assign extents - * as we go. Once we get through writing all of the - * directories, we should be ready write out these - * files - */ - if(s_entry->size) - { - dwpnt = (struct deferred_write *) - e_malloc(sizeof(struct deferred_write)); - if(dw_tail) - { - dw_tail->next = dwpnt; - dw_tail = dwpnt; - } - else - { - dw_head = dwpnt; - dw_tail = dwpnt; - } - if(s_entry->inode == TABLE_INODE) - { - dwpnt->table = s_entry->table; - dwpnt->name = NULL; - sprintf(whole_path,"%s%sTRANS.TBL", - s_entry->filedir->whole_name, SPATH_SEPARATOR); - } - else - { - dwpnt->table = NULL; - strcpy(whole_path, s_entry->whole_name); - dwpnt->name = strdup(whole_path); - } - dwpnt->next = NULL; - dwpnt->size = s_entry->size; - dwpnt->extent = last_extent; - set_733((char *) s_entry->isorec.extent, last_extent); - s_entry->starting_block = last_extent; - add_hash(s_entry); - last_extent += ROUND_UP(s_entry->size) >> 11; - if(verbose > 2) - { - fprintf(stderr,"%llu %llu %s\n", s_entry->starting_block, - last_extent-1, whole_path); - } -#ifdef DBG_ISO - if((ROUND_UP(s_entry->size) >> 11) > 500) - { - fprintf (stderr, "Warning: large file %s\n", whole_path); - fprintf (stderr, "Starting block is %d\n", s_entry->starting_block); - fprintf (stderr, "Reported file size is %d extents\n", s_entry->size); - - } -#endif -#ifdef NOT_NEEDED /* Never use this code if you like to create a DVD */ - - if(last_extent > (800000000 >> 11)) - { - /* - * More than 800Mb? Punt - */ - fprintf(stderr,"Extent overflow processing file %s\n", whole_path); - fprintf(stderr,"Starting block is %d\n", s_entry->starting_block); - fprintf(stderr,"Reported file size is %d extents\n", s_entry->size); - exit(1); - } -#endif - continue; - } - - /* - * This is for zero-length files. If we leave the extent 0, - * then we get screwed, because many readers simply drop files - * that have an extent of zero. Thus we leave the size 0, - * and just assign the extent number. - */ - set_733((char *) s_entry->isorec.extent, last_extent); - } - if(dpnt->subdir) - { - assign_file_addresses(dpnt->subdir); - } - dpnt = dpnt->next; - } -} /* assign_file_addresses(... */ - -static void FDECL1(free_one_directory, struct directory *, dpnt) -{ - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - - s_entry = dpnt->contents; - while(s_entry) - { - s_entry_d = s_entry; - s_entry = s_entry->next; - - if( s_entry_d->name != NULL ) - { - free (s_entry_d->name); - } - if( s_entry_d->whole_name != NULL ) - { - free (s_entry_d->whole_name); - } - free (s_entry_d); - } - dpnt->contents = NULL; -} /* free_one_directory(... */ - -static void FDECL1(free_directories, struct directory *, dpnt) -{ - while (dpnt) - { - free_one_directory(dpnt); - if(dpnt->subdir) free_directories(dpnt->subdir); - dpnt = dpnt->next; - } -} - -void FDECL2(generate_one_directory, struct directory *, dpnt, FILE *, outfile) -{ - unsigned int ce_address = 0; - char * ce_buffer; - unsigned int ce_index = 0; - unsigned int ce_size; - unsigned int dir_index; - char * directory_buffer; - int new_reclen; - struct directory_entry * s_entry; - struct directory_entry * s_entry_d; - unsigned int total_size; - - total_size = (dpnt->size + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - directory_buffer = (char *) e_malloc(total_size); - memset(directory_buffer, 0, total_size); - dir_index = 0; - - ce_size = (dpnt->ce_bytes + (SECTOR_SIZE - 1)) & ~(SECTOR_SIZE - 1); - ce_buffer = NULL; - - if(ce_size) - { - ce_buffer = (char *) e_malloc(ce_size); - memset(ce_buffer, 0, ce_size); - - ce_index = 0; - - /* - * Absolute byte address of CE entries for this directory - */ - ce_address = last_extent_written + (total_size >> 11); - ce_address = ce_address << 11; - } - - s_entry = dpnt->contents; - while(s_entry) - { - /* skip if it's hidden */ - if(s_entry->de_flags & INHIBIT_ISO9660_ENTRY) { - s_entry = s_entry->next; - continue; - } - - /* - * We do not allow directory entries to cross sector boundaries. - * Simply pad, and then start the next entry at the next sector - */ - new_reclen = s_entry->isorec.length[0]; - if( (dir_index & (SECTOR_SIZE - 1)) + new_reclen >= SECTOR_SIZE ) - { - dir_index = (dir_index + (SECTOR_SIZE - 1)) & - ~(SECTOR_SIZE - 1); - } - - memcpy(directory_buffer + dir_index, &s_entry->isorec, - sizeof(struct iso_directory_record) - - sizeof(s_entry->isorec.name) + s_entry->isorec.name_len[0]); - dir_index += sizeof(struct iso_directory_record) - - sizeof (s_entry->isorec.name)+ s_entry->isorec.name_len[0]; - - /* - * Add the Rock Ridge attributes, if present - */ - if(s_entry->rr_attr_size) - { - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - /* - * If the RR attributes were too long, then write the - * CE records, as required. - */ - if(s_entry->rr_attr_size != s_entry->total_rr_attr_size) - { - unsigned char * pnt; - int len, nbytes; - - /* - * Go through the entire record and fix up the CE entries - * so that the extent and offset are correct - */ - - pnt = s_entry->rr_attributes; - len = s_entry->total_rr_attr_size; - while(len > 3) - { -#ifdef DEBUG - if (!ce_size) - { - fprintf(stderr,"Warning: ce_index(%d) && ce_address(%d) not initialized\n", - ce_index, ce_address); - } -#endif - - if(pnt[0] == 'C' && pnt[1] == 'E') - { - nbytes = get_733( (char *) pnt+20); - - if((ce_index & (SECTOR_SIZE - 1)) + nbytes >= - SECTOR_SIZE) - { - ce_index = ROUND_UP(ce_index); - } - - set_733( (char *) pnt+4, - (ce_address + ce_index) >> 11); - set_733( (char *) pnt+12, - (ce_address + ce_index) & (SECTOR_SIZE - 1)); - - - /* - * Now store the block in the ce buffer - */ - memcpy(ce_buffer + ce_index, - pnt + pnt[2], nbytes); - ce_index += nbytes; - if(ce_index & 1) - { - ce_index++; - } - } - len -= pnt[2]; - pnt += pnt[2]; - } - - } - - rockridge_size += s_entry->total_rr_attr_size; - memcpy(directory_buffer + dir_index, s_entry->rr_attributes, - s_entry->rr_attr_size); - dir_index += s_entry->rr_attr_size; - } - if(dir_index & 1) - { - directory_buffer[dir_index++] = 0; - } - - s_entry_d = s_entry; - s_entry = s_entry->next; - - /* - * Joliet doesn't use the Rock Ridge attributes, so we free it here. - */ - if (s_entry_d->rr_attributes) - { - free(s_entry_d->rr_attributes); - s_entry_d->rr_attributes = NULL; - } - } - - if(dpnt->size != dir_index) - { - fprintf (stderr, _("Unexpected directory length %d %d %s\n"), dpnt->size, - dir_index, dpnt->de_name); - } - - xfwrite(directory_buffer, 1, total_size, outfile); - last_extent_written += total_size >> 11; - free(directory_buffer); - - if(ce_size) - { - if(ce_index != dpnt->ce_bytes) - { - fprintf (stderr, _("Continuation entry record length mismatch (%d %d).\n"), - ce_index, dpnt->ce_bytes); - } - xfwrite(ce_buffer, 1, ce_size, outfile); - last_extent_written += ce_size >> 11; - free(ce_buffer); - } - -} /* generate_one_directory(... */ - -static -void FDECL1(build_pathlist, struct directory *, node) -{ - struct directory * dpnt; - - dpnt = node; - - while (dpnt) - { - /* skip if it's hidden */ - if( (dpnt->dir_flags & INHIBIT_ISO9660_ENTRY) == 0 ) - pathlist[dpnt->path_index] = dpnt; - - if(dpnt->subdir) build_pathlist(dpnt->subdir); - dpnt = dpnt->next; - } -} /* build_pathlist(... */ - -static int FDECL2(compare_paths, void const *, r, void const *, l) -{ - struct directory const *ll = *(struct directory * const *)l; - struct directory const *rr = *(struct directory * const *)r; - - if (rr->parent->path_index < ll->parent->path_index) - { - return -1; - } - - if (rr->parent->path_index > ll->parent->path_index) - { - return 1; - } - - return strcmp(rr->self->isorec.name, ll->self->isorec.name); - -} /* compare_paths(... */ - -static int generate_path_tables() -{ - struct directory_entry * de; - struct directory * dpnt; - int fix; - int i; - int j; - int namelen; - char * npnt; - char * npnt1; - int tablesize; - - /* - * First allocate memory for the tables and initialize the memory - */ - tablesize = path_blocks << 11; - path_table_m = (char *) e_malloc(tablesize); - path_table_l = (char *) e_malloc(tablesize); - memset(path_table_l, 0, tablesize); - memset(path_table_m, 0, tablesize); - - /* - * Now start filling in the path tables. Start with root directory - */ - if( next_path_index > 0xffff ) - { - error (1, 0, _("Unable to generate sane path tables - too many directories (%d)\n"), - next_path_index); - } - - path_table_index = 0; - pathlist = (struct directory **) e_malloc(sizeof(struct directory *) - * next_path_index); - memset(pathlist, 0, sizeof(struct directory *) * next_path_index); - build_pathlist(root); - - do - { - fix = 0; -#ifdef __STDC__ - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - (int (*)(const void *, const void *))compare_paths); -#else - qsort(&pathlist[1], next_path_index-1, sizeof(struct directory *), - compare_paths); -#endif - - for(j=1; jpath_index != j) - { - pathlist[j]->path_index = j; - fix++; - } - } - } while(fix); - - for(j=1; jde_name; - - /* - * So the root comes out OK - */ - if( (*npnt == 0) || (dpnt == root) ) - { - npnt = "."; - } - npnt1 = strrchr(npnt, PATH_SEPARATOR); - if(npnt1) - { - npnt = npnt1 + 1; - } - - de = dpnt->self; - if(!de) - { - error (1, 0, _("Fatal goof\n")); - } - - - namelen = de->isorec.name_len[0]; - - path_table_l[path_table_index] = namelen; - path_table_m[path_table_index] = namelen; - path_table_index += 2; - - set_731(path_table_l + path_table_index, dpnt->extent); - set_732(path_table_m + path_table_index, dpnt->extent); - path_table_index += 4; - - set_721(path_table_l + path_table_index, - dpnt->parent->path_index); - set_722(path_table_m + path_table_index, - dpnt->parent->path_index); - path_table_index += 2; - - for(i =0; iisorec.name[i]; - path_table_m[path_table_index] = de->isorec.name[i]; - path_table_index++; - } - if(path_table_index & 1) - { - path_table_index++; /* For odd lengths we pad */ - } - } - - free(pathlist); - if(path_table_index != path_table_size) - { - fprintf (stderr, _("Path table lengths do not match %d %d\n"), - path_table_index, - path_table_size); - } - return 0; -} /* generate_path_tables(... */ - -void -FDECL3(memcpy_max, char *, to, char *, from, int, max) -{ - int n = strlen(from); - if (n > max) - { - n = max; - } - memcpy(to, from, n); - -} /* memcpy_max(... */ - -void FDECL1(outputlist_insert, struct output_fragment *, frag) -{ - if( out_tail == NULL ) - { - out_list = out_tail = frag; - } - else - { - out_tail->of_next = frag; - out_tail = frag; - } -} - -static int FDECL1(file_write, FILE *, outfile) -{ - int should_write; - - /* - * OK, all done with that crap. Now write out the directories. - * This is where the fur starts to fly, because we need to keep track of - * each file as we find it and keep track of where we put it. - */ - - should_write = last_extent - session_start; - - if( print_size > 0 ) - { - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - exit (0); - } - if( verbose > 2 ) - { -#ifdef DBG_ISO - fprintf(stderr,"Total directory extents being written = %llu\n", last_extent); -#endif - - fprintf (stderr, _("Total extents scheduled to be written = %llu\n"), - last_extent - session_start); - } - - /* - * Now write all of the files that we need. - */ - write_files(outfile); - - /* - * The rest is just fluff. - */ - if( verbose == 0 ) - { - return 0; - } - - fprintf (stderr, _("Total extents actually written = %llu\n"), - last_extent_written - session_start); - - /* - * Hard links throw us off here - */ - assert (last_extent > session_start); - if(should_write + session_start != last_extent) - { - fprintf (stderr, _("Number of extents written different than what was predicted. Please fix.\n")); - fprintf (stderr, _("Predicted = %d, written = %llu\n"), should_write, last_extent); - } - - fprintf (stderr, _("Total translation table size: %d\n"), table_size); - fprintf (stderr, _("Total rockridge attributes bytes: %d\n"), rockridge_size); - fprintf (stderr, _("Total directory bytes: %d\n"), total_dir_size); - fprintf (stderr, _("Path table size(bytes): %d\n"), path_table_size); - -#ifdef DEBUG - fprintf(stderr, "next extent, last_extent, last_extent_written %d %d %d\n", - next_extent, last_extent, last_extent_written); -#endif - - return 0; - -} /* iso_write(... */ - -char *creation_date = NULL; -char *modification_date = NULL; -char *expiration_date = NULL; -char *effective_date = NULL; - -/* - * Function to write the PVD for the disc. - */ -static int FDECL1(pvd_write, FILE *, outfile) -{ - char iso_time[17]; - int should_write; - struct tm local; - struct tm gmt; - - - time(&begun); - - local = *localtime(&begun); - gmt = *gmtime(&begun); - - /* - * This will break in the year 2000, I supose, but there is no good way - * to get the top two digits of the year. - */ - sprintf(iso_time, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d00", 1900 + local.tm_year, - local.tm_mon+1, local.tm_mday, - local.tm_hour, local.tm_min, local.tm_sec); - - local.tm_min -= gmt.tm_min; - local.tm_hour -= gmt.tm_hour; - local.tm_yday -= gmt.tm_yday; - iso_time[16] = (local.tm_min + 60*(local.tm_hour + 24*local.tm_yday)) / 15; - - /* - * Next we write out the primary descriptor for the disc - */ - memset(&vol_desc, 0, sizeof(vol_desc)); - vol_desc.type[0] = ISO_VD_PRIMARY; - memcpy(vol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - vol_desc.version[0] = 1; - - memset(vol_desc.system_id, ' ', sizeof(vol_desc.system_id)); - memcpy_max(vol_desc.system_id, system_id, strlen(system_id)); - - memset(vol_desc.volume_id, ' ', sizeof(vol_desc.volume_id)); - memcpy_max(vol_desc.volume_id, volume_id, strlen(volume_id)); - - should_write = last_extent - session_start; - set_733((char *) vol_desc.volume_space_size, should_write); - set_723(vol_desc.volume_set_size, volume_set_size); - set_723(vol_desc.volume_sequence_number, volume_sequence_number); - set_723(vol_desc.logical_block_size, 2048); - - /* - * The path tables are used by DOS based machines to cache directory - * locations - */ - - set_733((char *) vol_desc.path_table_size, path_table_size); - set_731(vol_desc.type_l_path_table, path_table[0]); - set_731(vol_desc.opt_type_l_path_table, path_table[1]); - set_732(vol_desc.type_m_path_table, path_table[2]); - set_732(vol_desc.opt_type_m_path_table, path_table[3]); - - /* - * Now we copy the actual root directory record - */ - memcpy(vol_desc.root_directory_record, &root_record, - sizeof(struct iso_directory_record) + 1); - - /* - * The rest is just fluff. It looks nice to fill in many of these fields, - * though. - */ - FILL_SPACE(volume_set_id); - if(volset_id) memcpy_max(vol_desc.volume_set_id, volset_id, strlen(volset_id)); - - FILL_SPACE(publisher_id); - if(publisher) memcpy_max(vol_desc.publisher_id, publisher, strlen(publisher)); - - FILL_SPACE(preparer_id); - if(preparer) memcpy_max(vol_desc.preparer_id, preparer, strlen(preparer)); - - FILL_SPACE(application_id); - if(appid) memcpy_max(vol_desc.application_id, appid, strlen(appid)); - - FILL_SPACE(copyright_file_id); - if(copyright) memcpy_max(vol_desc.copyright_file_id, copyright, - strlen(copyright)); - - FILL_SPACE(abstract_file_id); - if(abstract) memcpy_max(vol_desc.abstract_file_id, abstract, - strlen(abstract)); - - FILL_SPACE(bibliographic_file_id); - if(biblio) memcpy_max(vol_desc.bibliographic_file_id, biblio, - strlen(biblio)); - - FILL_SPACE(creation_date); - FILL_SPACE(modification_date); - FILL_SPACE(expiration_date); - FILL_SPACE(effective_date); - vol_desc.file_structure_version[0] = 1; - FILL_SPACE(application_data); - - memcpy(vol_desc.creation_date, creation_date ? creation_date : iso_time, 17); - memcpy(vol_desc.modification_date, modification_date ? modification_date : iso_time, 17); - memcpy(vol_desc.expiration_date, expiration_date ? expiration_date : "0000000000000000", 17); - memcpy(vol_desc.effective_date, effective_date ? effective_date : iso_time, 17); - - /* - * if not a bootable cd do it the old way - */ - xfwrite(&vol_desc, 1, 2048, outfile); - last_extent_written++; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(evd_write, FILE *, outfile) -{ - struct iso_primary_descriptor evol_desc; - - /* - * Now write the end volume descriptor. Much simpler than the other one - */ - memset(&evol_desc, 0, sizeof(evol_desc)); - evol_desc.type[0] = ISO_VD_END; - memcpy(evol_desc.id, ISO_STANDARD_ID, sizeof(ISO_STANDARD_ID)); - evol_desc.version[0] = 1; - xfwrite(&evol_desc, 1, 2048, outfile); - last_extent_written += 1; - return 0; -} - -/* - * Function to write the EVD for the disc. - */ -static int FDECL1(pathtab_write, FILE *, outfile) -{ - /* - * Next we write the path tables - */ - xfwrite(path_table_l, 1, path_blocks << 11, outfile); - xfwrite(path_table_m, 1, path_blocks << 11, outfile); - last_extent_written += 2*path_blocks; - free(path_table_l); - free(path_table_m); - path_table_l = NULL; - path_table_m = NULL; - return 0; -} - -static int FDECL1(exten_write, FILE *, outfile) -{ - xfwrite(extension_record, 1, SECTOR_SIZE, outfile); - last_extent_written++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ -int FDECL1(oneblock_size, int, starting_extent) -{ - last_extent++; - return 0; -} - -/* - * Functions to describe padding block at the start of the disc. - */ - -#define PADBLOCK_SIZE 16 - -static int FDECL1(pathtab_size, int, starting_extent) -{ - path_table[0] = starting_extent; - - path_table[1] = 0; - path_table[2] = path_table[0] + path_blocks; - path_table[3] = 0; - last_extent += 2*path_blocks; - return 0; -} - -static int FDECL1(padblock_size, int, starting_extent) -{ - last_extent += PADBLOCK_SIZE; - return 0; -} - -static int file_gen() -{ - assign_file_addresses(root); - return 0; -} - -static int dirtree_dump() -{ - if (verbose > 2) - { - dump_tree(root); - } - return 0; -} - -static int FDECL1(dirtree_fixup, int, starting_extent) -{ - if (use_RockRidge && reloc_dir) - finish_cl_pl_entries(); - - if (use_RockRidge ) - update_nlink_field(root); - return 0; -} - -static int FDECL1(dirtree_size, int, starting_extent) -{ - assign_directory_addresses(root); - return 0; -} - -static int FDECL1(ext_size, int, starting_extent) -{ - extern int extension_record_size; - struct directory_entry * s_entry; - extension_record_extent = starting_extent; - s_entry = root->contents; - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 24, - extension_record_extent); - set_733((char *) s_entry->rr_attributes + s_entry->rr_attr_size - 8, - extension_record_size); - last_extent++; - return 0; -} - -static int FDECL1(dirtree_write, FILE *, outfile) -{ - generate_iso9660_directories(root, outfile); - return 0; -} - -static int FDECL1(dirtree_cleanup, FILE *, outfile) -{ - free_directories(root); - return 0; -} - -static int FDECL1(padblock_write, FILE *, outfile) -{ - char *buffer; - - buffer = e_malloc (2048 * PADBLOCK_SIZE); - memset (buffer, 0, 2048 * PADBLOCK_SIZE); - - if (use_embedded_boot) - { - FILE *fp = fopen (boot_image_embed, "rb"); - if (! fp) - error (1, errno, _("Unable to open %s"), boot_image_embed); - - if (fread (buffer, 1, 2048 * PADBLOCK_SIZE, fp) == 0) - error (1, errno, _("cannot read %d bytes from %s"), - 2048 * PADBLOCK_SIZE, boot_image_embed); - if (fgetc (fp) != EOF) - error (1, 0, _("%s is too big for embed area"), boot_image_embed); - } - - if (use_protective_msdos_label) - { - struct msdos_partition_mbr *mbr = (void *) buffer; - - memset (mbr->entries, 0, sizeof(mbr->entries)); - - /* Some idiotic BIOSes refuse to boot if they don't find at least - one partition with active bit set. */ - mbr->entries[0].flag = 0x80; - - /* Doesn't really matter, as long as it's non-zero. It seems that - 0xCD is used elsewhere, so we follow suit. */ - mbr->entries[0].type = 0xcd; - - /* Start immediately (sector 1). */ - mbr->entries[0].start = 1; - - /* We don't know yet. Let's keep it safe. */ - mbr->entries[0].length = UINT32_MAX; - - mbr->signature = MSDOS_PARTITION_SIGNATURE; - } - - xfwrite (buffer, 1, 2048 * PADBLOCK_SIZE, outfile); - last_extent_written += PADBLOCK_SIZE; - - return 0; -} - -struct output_fragment padblock_desc = {NULL, padblock_size, NULL, padblock_write}; -struct output_fragment voldesc_desc = {NULL, oneblock_size, root_gen, pvd_write}; -struct output_fragment end_vol = {NULL, oneblock_size, NULL, evd_write}; -struct output_fragment pathtable_desc = {NULL, pathtab_size, generate_path_tables, pathtab_write}; -struct output_fragment dirtree_desc = {NULL, dirtree_size, NULL, dirtree_write}; -struct output_fragment dirtree_clean = {NULL, dirtree_fixup, dirtree_dump, dirtree_cleanup}; -struct output_fragment extension_desc = {NULL, ext_size, NULL, exten_write}; -struct output_fragment files_desc = {NULL, NULL, file_gen, file_write}; diff --git a/util/powerpc/ieee1275/grub-mkrescue.in b/util/powerpc/ieee1275/grub-mkrescue.in index 0110e799c..16658505b 100644 --- a/util/powerpc/ieee1275/grub-mkrescue.in +++ b/util/powerpc/ieee1275/grub-mkrescue.in @@ -30,7 +30,7 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` -grub_mkimage=${bindir}/`echo grub-mkelfimage | sed ${transform}` +grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage # Print the usage. @@ -104,7 +104,7 @@ boot_dir=${iso_dir}/boot/grub mkdir ${iso_dir}/boot mkdir ${boot_dir} core_img=${boot_dir}/grub.img -${grub_mkimage} -n -d ${input_dir}/ -o ${core_img} ${modules} +${grub_mkimage} -O powerpc-ieee1275 -n -d ${input_dir}/ -o ${core_img} ${modules} genisoimage -hfs -part -no-desktop -r -J -o ${output_image} \ -map ${map_file} -hfs-bless ${boot_dir} -chrp-boot -sysid PPC \ ${iso_dir} diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index b511a96b2..8a2d30ba1 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ #include #include #include -#include +#include #define _GNU_SOURCE 1 #include @@ -76,6 +76,13 @@ #define DEFAULT_BOOT_FILE "boot.img" #define DEFAULT_CORE_FILE "core.img" +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) + /* This is the blocklist used in the diskboot image. */ struct boot_blocklist { @@ -627,7 +634,8 @@ main (int argc, char *argv[]) find_dest_dev (&ginfo, argv); - ginfo.prefix = grub_get_prefix (ginfo.dir ? : DEFAULT_DIRECTORY); + ginfo.prefix = grub_make_system_path_relative_to_its_root (ginfo.dir ? + : DEFAULT_DIRECTORY); check_root_dev (&ginfo); diff --git a/util/sdl.c b/video/emu/sdl.c similarity index 100% rename from util/sdl.c rename to video/emu/sdl.c diff --git a/video/i386/pc/vga.c b/video/i386/pc/vga.c new file mode 100644 index 000000000..222a71272 --- /dev/null +++ b/video/i386/pc/vga.c @@ -0,0 +1,412 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#define grub_video_render_target grub_video_fbrender_target + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VGA_WIDTH 640 +#define VGA_HEIGHT 350 +#define VGA_MEM ((grub_uint8_t *) GRUB_MEMORY_MACHINE_VGA_ADDR) +#define PAGE_OFFSET(x) ((x) * (VGA_WIDTH * VGA_HEIGHT / 8)) + +static unsigned char text_mode; +static unsigned char saved_map_mask; + +static struct +{ + struct grub_video_mode_info mode_info; + struct grub_video_render_target *render_target; + grub_uint8_t *temporary_buffer; + int front_page; + int back_page; +} framebuffer; + +#define SEQUENCER_ADDR_PORT 0x3C4 +#define SEQUENCER_DATA_PORT 0x3C5 +#define MAP_MASK_REGISTER 0x02 + +#define CRTC_ADDR_PORT 0x3D4 +#define CRTC_DATA_PORT 0x3D5 +#define START_ADDR_HIGH_REGISTER 0x0C +#define START_ADDR_LOW_REGISTER 0x0D + +#define GRAPHICS_ADDR_PORT 0x3CE +#define GRAPHICS_DATA_PORT 0x3CF +#define READ_MAP_REGISTER 0x04 + +#define INPUT_STATUS1_REGISTER 0x3DA +#define INPUT_STATUS1_VERTR_BIT 0x08 + +static inline void +wait_vretrace (void) +{ + /* Wait until there is a vertical retrace. */ + while (! (grub_inb (INPUT_STATUS1_REGISTER) & INPUT_STATUS1_VERTR_BIT)); +} + +/* Get Map Mask Register. */ +static unsigned char +get_map_mask (void) +{ + unsigned char old_addr; + unsigned char old_data; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + old_data = grub_inb (SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); + + return old_data; +} + +/* Set Map Mask Register. */ +static void +set_map_mask (unsigned char mask) +{ + unsigned char old_addr; + + old_addr = grub_inb (SEQUENCER_ADDR_PORT); + grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT); + + grub_outb (mask, SEQUENCER_DATA_PORT); + + grub_outb (old_addr, SEQUENCER_ADDR_PORT); +} + +#if 0 +/* Set Read Map Register. */ +static void +set_read_map (unsigned char map) +{ + unsigned char old_addr; + + old_addr = grub_inb (GRAPHICS_ADDR_PORT); + + grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT); + grub_outb (map, GRAPHICS_DATA_PORT); + + grub_outb (old_addr, GRAPHICS_ADDR_PORT); +} +#endif + +/* Set start address. */ +static void +set_start_address (unsigned int start) +{ + unsigned char old_addr; + + old_addr = grub_inb (CRTC_ADDR_PORT); + + grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT); + grub_outb (start & 0xFF, CRTC_DATA_PORT); + + grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT); + grub_outb (start >> 8, CRTC_DATA_PORT); + + grub_outb (old_addr, CRTC_ADDR_PORT); +} + +static int setup = 0; +static int is_target = 0; + +static grub_err_t +grub_video_vga_init (void) +{ + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_setup (unsigned int width, unsigned int height, + unsigned int mode_type, unsigned int mode_mask) +{ + grub_err_t err; + + if ((width && width != VGA_WIDTH) || (height && height != VGA_HEIGHT)) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); + + framebuffer.temporary_buffer = grub_malloc (VGA_HEIGHT * VGA_WIDTH); + framebuffer.front_page = 0; + framebuffer.back_page = 0; + if (!framebuffer.temporary_buffer) + return grub_errno; + + saved_map_mask = get_map_mask (); + + text_mode = grub_vga_set_mode (0x10); + setup = 1; + set_map_mask (0x0f); + set_start_address (PAGE_OFFSET (framebuffer.front_page)); + + framebuffer.mode_info.width = VGA_WIDTH; + framebuffer.mode_info.height = VGA_HEIGHT; + + framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR; + + if (grub_video_check_mode_flag (mode_type, mode_mask, + GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED, 1)) + { + framebuffer.back_page = 1; + framebuffer.mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED; + } + + framebuffer.mode_info.bpp = 8; + framebuffer.mode_info.bytes_per_pixel = 1; + framebuffer.mode_info.pitch = VGA_WIDTH; + framebuffer.mode_info.number_of_colors = 16; + framebuffer.mode_info.red_mask_size = 0; + framebuffer.mode_info.red_field_pos = 0; + framebuffer.mode_info.green_mask_size = 0; + framebuffer.mode_info.green_field_pos = 0; + framebuffer.mode_info.blue_mask_size = 0; + framebuffer.mode_info.blue_field_pos = 0; + framebuffer.mode_info.reserved_mask_size = 0; + framebuffer.mode_info.reserved_field_pos = 0; + + framebuffer.mode_info.blit_format + = grub_video_get_blit_format (&framebuffer.mode_info); + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, + &framebuffer.mode_info, + framebuffer.temporary_buffer); + + if (err) + { + grub_dprintf ("video", "Couldn't create FB target\n"); + return err; + } + + is_target = 1; + err = grub_video_fb_set_active_render_target (framebuffer.render_target); + + if (err) + return err; + + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, + grub_video_fbstd_colors); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_fini (void) +{ + if (setup) + { + set_map_mask (saved_map_mask); + grub_vga_set_mode (text_mode); + } + setup = 0; + grub_free (framebuffer.temporary_buffer); + framebuffer.temporary_buffer = 0; + return GRUB_ERR_NONE; +} + +static inline void +update_target (void) +{ + int plane; + + if (!is_target) + return; + + for (plane = 0x01; plane <= 0x08; plane <<= 1) + { + grub_uint8_t *ptr; + volatile grub_uint8_t *ptr2; + unsigned cbyte = 0; + int shift = 7; + set_map_mask (plane); + for (ptr = framebuffer.temporary_buffer, + ptr2 = VGA_MEM + PAGE_OFFSET (framebuffer.back_page); + ptr < framebuffer.temporary_buffer + VGA_WIDTH * VGA_HEIGHT; ptr++) + { + cbyte |= (!!(plane & *ptr)) << shift; + shift--; + if (shift == -1) + { + *ptr2++ = cbyte; + shift = 7; + cbyte = 0; + } + } + } +} + +static grub_err_t +grub_video_vga_blit_bitmap (struct grub_video_bitmap *bitmap, + enum grub_video_blit_operators oper, int x, int y, + int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + grub_err_t ret; + ret = grub_video_fb_blit_bitmap (bitmap, oper, x, y, offset_x, offset_y, + width, height); + update_target (); + return ret; +} + +static grub_err_t +grub_video_vga_blit_render_target (struct grub_video_fbrender_target *source, + enum grub_video_blit_operators oper, + int x, int y, int offset_x, int offset_y, + unsigned int width, unsigned int height) +{ + grub_err_t ret; + + ret = grub_video_fb_blit_render_target (source, oper, x, y, + offset_x, offset_y, width, height); + update_target (); + + return ret; +} + +static grub_err_t +grub_video_vga_set_active_render_target (struct grub_video_render_target *target) +{ + if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY) + { + is_target = 1; + target = framebuffer.render_target; + } + else + is_target = 0; + + return grub_video_fb_set_active_render_target (target); +} + +static grub_err_t +grub_video_vga_get_active_render_target (struct grub_video_render_target **target) +{ + grub_err_t err; + err = grub_video_fb_get_active_render_target (target); + if (err) + return err; + + if (*target == framebuffer.render_target) + *target = GRUB_VIDEO_RENDER_TARGET_DISPLAY; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_swap_buffers (void) +{ + if (!(framebuffer.mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)) + return GRUB_ERR_NONE; + + /* Activate the other page. */ + framebuffer.front_page = !framebuffer.front_page; + framebuffer.back_page = !framebuffer.back_page; + wait_vretrace (); + set_start_address (PAGE_OFFSET (framebuffer.front_page)); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_video_vga_set_palette (unsigned int start __attribute__ ((unused)), + unsigned int count __attribute__ ((unused)), + struct grub_video_palette_data *palette_data __attribute__ ((unused))) +{ + return grub_error (GRUB_ERR_IO, "can't change palette"); +} + +static grub_err_t +grub_video_vga_get_info_and_fini (struct grub_video_mode_info *mode_info, + void **framebuf) +{ + set_map_mask (0xf); + + grub_memcpy (mode_info, &(framebuffer.mode_info), sizeof (*mode_info)); + mode_info->bpp = 1; + mode_info->bytes_per_pixel = 0; + mode_info->pitch = VGA_WIDTH / 8; + mode_info->number_of_colors = 1; + + mode_info->bg_red = 0; + mode_info->bg_green = 0; + mode_info->bg_blue = 0; + mode_info->bg_alpha = 255; + + mode_info->fg_red = 255; + mode_info->fg_green = 255; + mode_info->fg_blue = 255; + mode_info->fg_alpha = 255; + + *framebuf = VGA_MEM + PAGE_OFFSET (framebuffer.front_page); + + grub_video_fb_fini (); + grub_free (framebuffer.temporary_buffer); + framebuffer.temporary_buffer = 0; + setup = 0; + + return GRUB_ERR_NONE; +} + + +static struct grub_video_adapter grub_video_vga_adapter = + { + .name = "VGA Video Driver", + .id = GRUB_VIDEO_DRIVER_VGA, + + .init = grub_video_vga_init, + .fini = grub_video_vga_fini, + .setup = grub_video_vga_setup, + .get_info = grub_video_fb_get_info, + .get_info_and_fini = grub_video_vga_get_info_and_fini, + .set_palette = grub_video_vga_set_palette, + .get_palette = grub_video_fb_get_palette, + .set_viewport = grub_video_fb_set_viewport, + .get_viewport = grub_video_fb_get_viewport, + .map_color = grub_video_fb_map_color, + .map_rgb = grub_video_fb_map_rgb, + .map_rgba = grub_video_fb_map_rgba, + .unmap_color = grub_video_fb_unmap_color, + .fill_rect = grub_video_fb_fill_rect, + .blit_bitmap = grub_video_vga_blit_bitmap, + .blit_render_target = grub_video_vga_blit_render_target, + .scroll = grub_video_fb_scroll, + .swap_buffers = grub_video_vga_swap_buffers, + .create_render_target = grub_video_fb_create_render_target, + .delete_render_target = grub_video_fb_delete_render_target, + .set_active_render_target = grub_video_vga_set_active_render_target, + .get_active_render_target = grub_video_vga_get_active_render_target, + + .next = 0 + }; + +GRUB_MOD_INIT(vga) +{ + grub_video_register (&grub_video_vga_adapter); +} + +GRUB_MOD_FINI(vga) +{ + grub_video_unregister (&grub_video_vga_adapter); +} diff --git a/video/readers/jpeg.c b/video/readers/jpeg.c index 5e749b8fd..9d88163bd 100644 --- a/video/readers/jpeg.c +++ b/video/readers/jpeg.c @@ -153,10 +153,11 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num) static int grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id) { - int code, i; + int code; + unsigned i; code = 0; - for (i = 0; i < 16; i++) + for (i = 0; i < ARRAY_SIZE (data->huff_maxval[id]); i++) { code <<= 1; if (grub_jpeg_get_bit (data)) @@ -171,47 +172,51 @@ grub_jpeg_get_huff_code (struct grub_jpeg_data *data, int id) static grub_err_t grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) { - int id, ac, i, n, base, ofs; + int id, ac, n, base, ofs; grub_uint32_t next_marker; grub_uint8_t count[16]; + unsigned i; next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); - id = grub_jpeg_get_byte (data); - ac = (id >> 4); - id &= 0xF; - if (id > 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: too many huffman tables"); - - if (grub_file_read (data->file, &count, sizeof (count)) != - sizeof (count)) - return grub_errno; - - n = 0; - for (i = 0; i < 16; i++) - n += count[i]; - - id += ac * 2; - data->huff_value[id] = grub_malloc (n); - if (grub_errno) - return grub_errno; - - if (grub_file_read (data->file, data->huff_value[id], n) != n) - return grub_errno; - - base = 0; - ofs = 0; - for (i = 0; i < 16; i++) + while (data->file->offset + sizeof (count) + 1 <= next_marker) { - base += count[i]; - ofs += count[i]; + id = grub_jpeg_get_byte (data); + ac = (id >> 4) & 1; + id &= 0xF; + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many huffman tables"); - data->huff_maxval[id][i] = base; - data->huff_offset[id][i] = ofs - base; + if (grub_file_read (data->file, &count, sizeof (count)) != + sizeof (count)) + return grub_errno; - base <<= 1; + n = 0; + for (i = 0; i < ARRAY_SIZE (count); i++) + n += count[i]; + + id += ac * 2; + data->huff_value[id] = grub_malloc (n); + if (grub_errno) + return grub_errno; + + if (grub_file_read (data->file, data->huff_value[id], n) != n) + return grub_errno; + + base = 0; + ofs = 0; + for (i = 0; i < ARRAY_SIZE (count); i++) + { + base += count[i]; + ofs += count[i]; + + data->huff_maxval[id][i] = base; + data->huff_offset[id][i] = ofs - base; + + base <<= 1; + } } if (data->file->offset != next_marker) @@ -229,17 +234,24 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) next_marker = data->file->offset; next_marker += grub_jpeg_get_word (data); - id = grub_jpeg_get_byte (data); - if (id >= 0x10) /* Upper 4-bit is precision. */ - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); + while (data->file->offset + sizeof (data->quan_table[id]) + 1 + <= next_marker) + { + id = grub_jpeg_get_byte (data); + if (id >= 0x10) /* Upper 4-bit is precision. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: only 8-bit precision is supported"); - if (id > 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: too many quantization tables"); + if (id > 1) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, + "jpeg: too many quantization tables"); - if (grub_file_read (data->file, &data->quan_table[id], 64) != 64) - return grub_errno; + if (grub_file_read (data->file, &data->quan_table[id], + sizeof (data->quan_table[id])) + != sizeof (data->quan_table[id])) + return grub_errno; + + } if (data->file->offset != next_marker) grub_error (GRUB_ERR_BAD_FILE_TYPE, @@ -444,7 +456,8 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du) static void grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) { - int pos, h1, h2, qt; + int h1, h2, qt; + unsigned pos; grub_memset (du, 0, sizeof (jpeg_data_unit_t)); @@ -457,7 +470,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; pos = 1; - while (pos < 64) + while (pos < ARRAY_SIZE (data->quan_table[qt])) { int num, val; @@ -700,7 +713,7 @@ grub_video_reader_jpeg (struct grub_video_bitmap **bitmap, #if defined(JPEG_DEBUG) static grub_err_t grub_cmd_jpegtest (grub_command_t cmd __attribute__ ((unused)), - int argc, char **args) + int argc, char **args) { struct grub_video_bitmap *bitmap = 0; @@ -735,8 +748,7 @@ GRUB_MOD_INIT (jpeg) grub_video_bitmap_reader_register (&jpeg_reader); #if defined(JPEG_DEBUG) cmd = grub_register_command ("jpegtest", grub_cmd_jpegtest, - "FILE", - "Tests loading of JPEG bitmap."); + "FILE", "Tests loading of JPEG bitmap."); #endif }