static char * grub_ext2_read_symlink (grub_fshelp_node_t node) { char *symlink; struct grub_fshelp_node *diro = node; if (! diro->inode_read) { grub_ext2_read_inode (diro->data, diro->ino, &diro->inode); if (grub_errno) return 0; } symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1); if (! symlink) return 0; /* If the filesize of the symlink is bigger than 60 the symlink is stored in a separate block, otherwise it is stored in the inode. */ if (grub_le_to_cpu32 (diro->inode.size) <= 60) grub_strncpy (symlink, diro->inode.symlink, grub_le_to_cpu32 (diro->inode.size)); else { grub_ext2_read_file (diro, 0, 0, grub_le_to_cpu32 (diro->inode.size), symlink); if (grub_errno) { grub_free (symlink); return 0; } } symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0'; return symlink; }
/* Write devtree in XNU format at curptr assuming the head is named NAME.*/ static void * grub_xnu_writetree_toheap_real (void *curptr, struct grub_xnu_devtree_key *start, char *name) { struct grub_xnu_devtree_key *cur; int nkeys = 0, nvals = 0; for (cur = start; cur; cur = cur->next) { if (cur->datasize == -1) nkeys++; else nvals++; } /* For the name. */ nvals++; *((grub_uint32_t *) curptr) = nvals; curptr = ((grub_uint32_t *) curptr) + 1; *((grub_uint32_t *) curptr) = nkeys; curptr = ((grub_uint32_t *) curptr) + 1; /* First comes "name" value. */ grub_memset (curptr, 0, 32); grub_memcpy (curptr, "name", 4); curptr = ((grub_uint8_t *) curptr) + 32; *((grub_uint32_t *)curptr) = grub_strlen (name) + 1; curptr = ((grub_uint32_t *) curptr) + 1; grub_memcpy (curptr, name, grub_strlen (name)); curptr = ((grub_uint8_t *) curptr) + grub_strlen (name); grub_memset (curptr, 0, 4 - (grub_strlen (name) % 4)); curptr = ((grub_uint8_t *) curptr) + (4 - (grub_strlen (name) % 4)); /* Then the other values. */ for (cur = start; cur; cur = cur->next) if (cur->datasize != -1) { int align_overhead; align_overhead = 4 - (cur->datasize % 4); if (align_overhead == 4) align_overhead = 0; grub_memset (curptr, 0, 32); grub_strncpy (curptr, cur->name, 31); curptr = ((grub_uint8_t *) curptr) + 32; *((grub_uint32_t *) curptr) = cur->datasize; curptr = ((grub_uint32_t *) curptr) + 1; grub_memcpy (curptr, cur->data, cur->datasize); curptr = ((grub_uint8_t *) curptr) + cur->datasize; grub_memset (curptr, 0, align_overhead); curptr = ((grub_uint8_t *) curptr) + align_overhead; } /* And then the keys. Recursively use this function. */ for (cur = start; cur; cur = cur->next) if (cur->datasize == -1) if (!(curptr = grub_xnu_writetree_toheap_real (curptr, cur->first_child, cur->name))) return 0; return curptr; }
static grub_err_t grub_cmd_pxechain (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) { grub_file_t file = 0; grub_err_t err; void *image; grub_size_t imagesize; char *fname; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); grub_dl_ref (my_mod); rel = grub_relocator_new (); if (!rel) goto fail; file = grub_file_open (argv[0]); if (! file) goto fail; if (file->device->net && file->device->net->name) fname = file->device->net->name; else { fname = argv[0]; if (fname[0] == '(') { fname = grub_strchr (fname, ')'); if (fname) fname++; else fname = argv[0]; } } grub_memset (boot_file, 0, sizeof (boot_file)); grub_strncpy (boot_file, fname, sizeof (boot_file)); grub_memset (server_name, 0, sizeof (server_name)); if (file->device->net && file->device->net->server) grub_strncpy (server_name, file->device->net->server, sizeof (server_name)); edx = grub_get_root_biosnumber (); imagesize = grub_file_size (file); { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7c00, imagesize); if (err) goto fail; image = get_virtual_current_address (ch); } if (grub_file_read (file, image, imagesize) != (grub_ssize_t) imagesize) goto fail; grub_loader_set (grub_pxechain_boot, grub_pxechain_unload, GRUB_LOADER_FLAG_NORETURN | GRUB_LOADER_FLAG_PXE_NOT_UNLOAD); return GRUB_ERR_NONE; fail: if (file) grub_file_close (file); grub_pxechain_unload (); return grub_errno; }