static inline char * get_name_ptr (char *name) { char *p = name, *p2; /* Skip Info.plist. */ p2 = grub_strrchr (p, '/'); if (!p2) return name; if (p2 == name) return name + 1; p = p2 - 1; p2 = grub_strrchr (p, '/'); if (!p2) return name; if (p2 == name) return name + 1; if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0) return p2 + 1; p = p2 - 1; p2 = grub_strrchr (p, '/'); if (!p2) return name; return p2 + 1; }
void grub_efi_set_prefix (void) { grub_efi_loaded_image_t *image = NULL; char *device = NULL; char *path = NULL; { 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 *p; path = grub_efi_get_filename (image->file_path); /* 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 grub_machine_get_bootlocation (char **device, char **path) { grub_efi_loaded_image_t *image = NULL; char *p; image = grub_efi_get_loaded_image (grub_efi_image_handle); if (!image) return; *device = grub_efidisk_get_device_name (image->device_handle); if (!*device && grub_efi_net_config) { grub_efi_net_config (image->device_handle, device, path); return; } *path = grub_efi_get_filename (image->file_path); if (*path) { /* Get the directory. */ p = grub_strrchr (*path, '/'); if (p) *p = '\0'; } }
int is_directory(const char *filename) { char *basename; char *dirname; size_t i; char *copy; if (grub_strcmp(filename, "/") == 0) return 1; copy = grub_strdup(filename); if (!copy) return 0; dirname = copy; i = grub_strlen(dirname); while (i && dirname[i - 1] == '/') dirname[--i] = '\0'; basename = grub_strrchr(dirname, '/'); if (basename) *basename++ = '\0'; else basename = "/"; if (*dirname == '\0') dirname = "/"; is_directory_filename = basename; is_directory_result = 0; iterate_directory(dirname, is_directory_callback); grub_free(copy); return is_directory_result; }
grub_uitree_t grub_uitree_load_file (grub_uitree_t root, const char *name, int flags) { grub_uitree_t result = 0; grub_file_t file; int size; const char *prefix; file = grub_file_open (name); if (! file) return 0; prefix = grub_strrchr (name, '/'); if (! prefix) prefix = name; size = file->size; if (size) { char *buf; buf = grub_malloc (size); if (buf) { grub_file_read (file, buf, size); result = grub_uitree_load_buf (name, prefix - name, root, buf, size, flags); } grub_free (buf); } grub_file_close (file); return result; }
void grub_machine_set_prefix (void) { #ifndef __i386__ char bootpath[64]; /* XXX check length */ char *filename; char *prefix; #endif if (grub_prefix[0]) { grub_env_set ("prefix", grub_prefix); /* Prefix is hardcoded in the core image. */ return; } #ifdef __i386__ grub_env_set ("prefix", "(sd,1)/"); #else if (grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", &bootpath, sizeof (bootpath), 0)) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); grub_env_set ("prefix", ""); return; } /* Transform an OF device path to a GRUB path. */ prefix = grub_ieee1275_encode_devname (bootpath); filename = grub_ieee1275_get_filename (bootpath); if (filename) { char *newprefix; char *lastslash = grub_strrchr (filename, '\\'); /* Truncate at last directory. */ if (lastslash) { *lastslash = '\0'; grub_translate_ieee1275_path (filename); newprefix = grub_xasprintf ("%s%s", prefix, filename); if (newprefix) { grub_free (prefix); prefix = newprefix; } } } grub_env_set ("prefix", prefix); grub_free (filename); grub_free (prefix); #endif }
static int check_string_removable (const char *str) { const char *ptr = grub_strrchr (str, '/'); if (ptr) ptr++; else ptr = str; return (grub_strncmp (ptr, "cdrom", 5) == 0 || grub_strncmp (ptr, "fd", 2) == 0); }
void grub_efi_set_prefix (void) { grub_efi_loaded_image_t *image; image = grub_efi_get_loaded_image (grub_efi_image_handle); if (image) { char *device; char *file; char *prefix; device = grub_efidisk_get_device_name (image->device_handle); file = grub_efi_get_filename (image->file_path); if (file) { char *p; /* Get the directory. */ p = grub_strrchr (file, '/'); if (p) *p = '\0'; } prefix = grub_xasprintf ("(%s)%s", (device) ? device : "net0", (file) ? file : ""); if (prefix) { grub_env_set ("prefix", prefix); grub_free (prefix); } grub_free (device); grub_free (file); } }
/* Parse a test expression starting from *argn. */ static int test_parse (char **args, int *argn, int argc) { int ret = 0, discard = 0, invert = 0; int file_exists; struct grub_dirhook_info file_info; auto void update_val (int val); auto void get_fileinfo (char *pathname); /* Take care of discarding and inverting. */ void update_val (int val) { if (! discard) ret = invert ? ! val : val; invert = discard = 0; } /* Check if file exists and fetch its information. */ void get_fileinfo (char *path) { char *filename, *pathname; char *device_name; grub_fs_t fs; grub_device_t dev; /* A hook for iterating directories. */ auto int find_file (const char *cur_filename, const struct grub_dirhook_info *info); int find_file (const char *cur_filename, const struct grub_dirhook_info *info) { if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename) : grub_strcmp (cur_filename, filename)) == 0) { file_info = *info; file_exists = 1; return 1; } return 0; } file_exists = 0; device_name = grub_file_get_device_name (path); dev = grub_device_open (device_name); if (! dev) { grub_free (device_name); return; } fs = grub_fs_probe (dev); if (! fs) { grub_free (device_name); grub_device_close (dev); return; } pathname = grub_strchr (path, ')'); if (! pathname) pathname = path; else pathname++; /* Remove trailing '/'. */ while (*pathname && pathname[grub_strlen (pathname) - 1] == '/') pathname[grub_strlen (pathname) - 1] = 0; /* Split into path and filename. */ filename = grub_strrchr (pathname, '/'); if (! filename) { path = grub_strdup ("/"); filename = pathname; } else { filename++; path = grub_strdup (pathname); path[filename - pathname] = 0; } /* It's the whole device. */ if (! *pathname) { file_exists = 1; grub_memset (&file_info, 0, sizeof (file_info)); /* Root is always a directory. */ file_info.dir = 1; /* Fetch writing time. */ file_info.mtimeset = 0; if (fs->mtime) { if (! fs->mtime (dev, &file_info.mtime)) file_info.mtimeset = 1; grub_errno = GRUB_ERR_NONE; } } else (fs->dir) (dev, path, find_file); grub_device_close (dev); grub_free (path); grub_free (device_name); }
static grub_err_t grub_ls_list_files (char *dirname, int longlist, int all, int human) { char *device_name; grub_fs_t fs; const char *path; grub_device_t dev; device_name = grub_file_get_device_name (dirname); dev = grub_device_open (device_name); if (! dev) goto fail; fs = grub_fs_probe (dev); path = grub_strchr (dirname, ')'); if (! path) path = dirname; else path++; if (! path && ! device_name) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); goto fail; } if (! *path) { if (grub_errno == GRUB_ERR_UNKNOWN_FS) grub_errno = GRUB_ERR_NONE; grub_normal_print_device_info (device_name); } else if (fs) { struct grub_ls_list_files_ctx ctx = { .dirname = dirname, .all = all, .human = human }; if (longlist) (fs->dir) (dev, path, print_files_long, &ctx); else (fs->dir) (dev, path, print_files, &ctx); if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && path[grub_strlen (path) - 1] != '/') { /* PATH might be a regular file. */ char *p; grub_file_t file; struct grub_dirhook_info info; grub_errno = 0; grub_file_filter_disable_compression (); file = grub_file_open (dirname); if (! file) goto fail; grub_file_close (file); p = grub_strrchr (dirname, '/') + 1; dirname = grub_strndup (dirname, p - dirname); if (! dirname) goto fail; all = 1; grub_memset (&info, 0, sizeof (info)); if (longlist) print_files_long (p, &info, &ctx); else print_files (p, &info, &ctx); grub_free (dirname); } if (grub_errno == GRUB_ERR_NONE) grub_xputs ("\n"); grub_refresh (); } fail: if (dev) grub_device_close (dev); grub_free (device_name); return 0; }
static int grub_iso9660_iterate_dir (grub_fshelp_node_t dir, grub_fshelp_iterate_dir_hook_t hook, void *hook_data) { struct grub_iso9660_dir dirent; grub_off_t offset = 0; grub_off_t len; struct iterate_dir_ctx ctx; len = get_node_size (dir); for (; offset < len; offset += dirent.len) { ctx.symlink = 0; ctx.was_continue = 0; if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) return 0; /* The end of the block, skip to the next one. */ if (!dirent.len) { offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ; continue; } { char name[MAX_NAMELEN + 1]; int nameoffset = offset + sizeof (dirent); struct grub_fshelp_node *node; int sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)); int sua_size = dirent.len - sua_off; sua_off += offset + dir->data->susp_skip; ctx.filename = 0; ctx.filename_alloc = 0; ctx.type = GRUB_FSHELP_UNKNOWN; if (dir->data->rockridge && grub_iso9660_susp_iterate (dir, sua_off, sua_size, susp_iterate_dir, &ctx)) return 0; /* Read the name. */ if (read_node (dir, nameoffset, dirent.namelen, (char *) name)) return 0; node = grub_malloc (sizeof (struct grub_fshelp_node)); if (!node) return 0; node->alloc_dirents = ARRAY_SIZE (node->dirents); node->have_dirents = 1; /* Setup a new node. */ node->data = dir->data; node->have_symlink = 0; /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ if (ctx.type == GRUB_FSHELP_UNKNOWN) { if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) ctx.type = GRUB_FSHELP_DIR; else ctx.type = GRUB_FSHELP_REG; } /* . and .. */ if (!ctx.filename && dirent.namelen == 1 && name[0] == 0) ctx.filename = (char *) "."; if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) ctx.filename = (char *) ".."; /* The filename was not stored in a rock ridge entry. Read it from the iso9660 filesystem. */ if (!dir->data->joliet && !ctx.filename) { char *ptr; name[dirent.namelen] = '\0'; ctx.filename = grub_strrchr (name, ';'); if (ctx.filename) *ctx.filename = '\0'; /* ISO9660 names are not case-preserving. */ ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; for (ptr = name; *ptr; ptr++) *ptr = grub_tolower (*ptr); if (ptr != name && *(ptr - 1) == '.') *(ptr - 1) = 0; ctx.filename = name; } if (dir->data->joliet && !ctx.filename) { char *semicolon; ctx.filename = grub_iso9660_convert_string ((grub_uint8_t *) name, dirent.namelen >> 1); semicolon = grub_strrchr (ctx.filename, ';'); if (semicolon) *semicolon = '\0'; ctx.filename_alloc = 1; } node->dirents[0] = dirent; while (dirent.flags & FLAG_MORE_EXTENTS) { offset += dirent.len; if (read_node (dir, offset, sizeof (dirent), (char *) &dirent)) { if (ctx.filename_alloc) grub_free (ctx.filename); grub_free (node); return 0; } if (node->have_dirents >= node->alloc_dirents) { struct grub_fshelp_node *new_node; node->alloc_dirents *= 2; new_node = grub_realloc (node, sizeof (struct grub_fshelp_node) + ((node->alloc_dirents - ARRAY_SIZE (node->dirents)) * sizeof (node->dirents[0]))); if (!new_node) { if (ctx.filename_alloc) grub_free (ctx.filename); grub_free (node); return 0; } node = new_node; } node->dirents[node->have_dirents++] = dirent; } if (ctx.symlink) { if ((node->alloc_dirents - node->have_dirents) * sizeof (node->dirents[0]) < grub_strlen (ctx.symlink) + 1) { struct grub_fshelp_node *new_node; new_node = grub_realloc (node, sizeof (struct grub_fshelp_node) + ((node->alloc_dirents - ARRAY_SIZE (node->dirents)) * sizeof (node->dirents[0])) + grub_strlen (ctx.symlink) + 1); if (!new_node) { if (ctx.filename_alloc) grub_free (ctx.filename); grub_free (node); return 0; } node = new_node; } node->have_symlink = 1; grub_strcpy (node->symlink + node->have_dirents * sizeof (node->dirents[0]) - sizeof (node->dirents), ctx.symlink); grub_free (ctx.symlink); ctx.symlink = 0; ctx.was_continue = 0; } if (hook (ctx.filename, ctx.type, node, hook_data)) { if (ctx.filename_alloc) grub_free (ctx.filename); return 1; } if (ctx.filename_alloc) grub_free (ctx.filename); } }
static grub_err_t grub_ls_list_files (char *dirname, int longlist, int all, int human) { char *device_name; grub_fs_t fs; const char *path; grub_device_t dev; auto int print_files (const char *filename, const struct grub_dirhook_info *info); auto int print_files_long (const char *filename, const struct grub_dirhook_info *info); int print_files (const char *filename, const struct grub_dirhook_info *info) { if (all || filename[0] != '.') grub_printf ("%s%s ", filename, info->dir ? "/" : ""); return 0; } int print_files_long (const char *filename, const struct grub_dirhook_info *info) { if ((! all) && (filename[0] == '.')) return 0; if (! info->dir) { grub_file_t file; char *pathname; if (dirname[grub_strlen (dirname) - 1] == '/') pathname = grub_xasprintf ("%s%s", dirname, filename); else pathname = grub_xasprintf ("%s/%s", dirname, filename); if (!pathname) return 1; /* XXX: For ext2fs symlinks are detected as files while they should be reported as directories. */ grub_file_filter_disable_compression (); file = grub_file_open (pathname); if (! file) { grub_errno = 0; grub_free (pathname); return 0; } if (! human) grub_printf ("%-12llu", (unsigned long long) file->size); else { grub_uint64_t fsize = file->size * 100ULL; grub_uint64_t fsz = file->size; int units = 0; char buf[20]; while (fsz / 1024) { fsize = (fsize + 512) / 1024; fsz /= 1024; units++; } if (units) { grub_uint64_t whole, fraction; whole = grub_divmod64 (fsize, 100, &fraction); grub_snprintf (buf, sizeof (buf), "%" PRIuGRUB_UINT64_T ".%02" PRIuGRUB_UINT64_T "%c", whole, fraction, grub_human_sizes[units]); grub_printf ("%-12s", buf); } else grub_printf ("%-12llu", (unsigned long long) file->size); } grub_file_close (file); grub_free (pathname); } else grub_printf ("%-12s", _("DIR")); if (info->mtimeset) { struct grub_datetime datetime; grub_unixtime2datetime (info->mtime, &datetime); if (human) grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second, grub_get_weekday_name (&datetime)); else grub_printf (" %04d%02d%02d%02d%02d%02d ", datetime.year, datetime.month, datetime.day, datetime.hour, datetime.minute, datetime.second); } grub_printf ("%s%s\n", filename, info->dir ? "/" : ""); return 0; } device_name = grub_file_get_device_name (dirname); dev = grub_device_open (device_name); if (! dev) goto fail; fs = grub_fs_probe (dev); path = grub_strchr (dirname, ')'); if (! path) path = dirname; else path++; if (! path && ! device_name) { grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); goto fail; } if (! *path) { if (grub_errno == GRUB_ERR_UNKNOWN_FS) grub_errno = GRUB_ERR_NONE; grub_normal_print_device_info (device_name); } else if (fs) { if (longlist) (fs->dir) (dev, path, print_files_long); else (fs->dir) (dev, path, print_files); if (grub_errno == GRUB_ERR_BAD_FILE_TYPE && path[grub_strlen (path) - 1] != '/') { /* PATH might be a regular file. */ char *p; grub_file_t file; struct grub_dirhook_info info; grub_errno = 0; grub_file_filter_disable_compression (); file = grub_file_open (dirname); if (! file) goto fail; grub_file_close (file); p = grub_strrchr (dirname, '/') + 1; dirname = grub_strndup (dirname, p - dirname); if (! dirname) goto fail; all = 1; grub_memset (&info, 0, sizeof (info)); if (longlist) print_files_long (p, &info); else print_files (p, &info); grub_free (dirname); } if (grub_errno == GRUB_ERR_NONE) grub_xputs ("\n"); grub_refresh (); } fail: if (dev) grub_device_close (dev); grub_free (device_name); return 0; }
struct grub_net_network_level_interface * grub_net_configure_by_dhcp_ack (const char *name, struct grub_net_card *card, grub_net_interface_flags_t flags, const struct grub_net_bootp_packet *bp, grub_size_t size, int is_def, char **device, char **path) { grub_net_network_level_address_t addr; grub_net_link_level_address_t hwaddr; struct grub_net_network_level_interface *inter; int mask = -1; addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; addr.ipv4 = bp->your_ip; if (device) *device = 0; if (path) *path = 0; grub_memcpy (hwaddr.mac, bp->mac_addr, bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len : sizeof (hwaddr.mac)); hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); #if 0 /* This is likely based on misunderstanding. gateway_ip refers to address of BOOTP relay and should not be used after BOOTP transaction is complete. See RFC1542, 3.4 Interpretation of the 'giaddr' field */ if (bp->gateway_ip) { grub_net_network_level_netaddress_t target; grub_net_network_level_address_t gw; char *rname; target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = bp->server_ip; target.ipv4.masksize = 32; gw.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; gw.ipv4 = bp->gateway_ip; rname = grub_xasprintf ("%s:gw", name); if (rname) grub_net_add_route_gw (rname, target, gw); grub_free (rname); target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; target.ipv4.base = bp->gateway_ip; target.ipv4.masksize = 32; grub_net_add_route (name, target, inter); } #endif if (size > OFFSET_OF (boot_file, bp)) grub_env_set_net_property (name, "boot_file", bp->boot_file, sizeof (bp->boot_file)); if (is_def) grub_net_default_server = 0; if (is_def && !grub_net_default_server && bp->server_ip) { grub_net_default_server = grub_xasprintf ("%d.%d.%d.%d", ((grub_uint8_t *) &bp->server_ip)[0], ((grub_uint8_t *) &bp->server_ip)[1], ((grub_uint8_t *) &bp->server_ip)[2], ((grub_uint8_t *) &bp->server_ip)[3]); grub_print_error (); } if (is_def) { grub_env_set ("net_default_interface", name); grub_env_export ("net_default_interface"); } if (device && !*device && bp->server_ip) { *device = grub_xasprintf ("tftp,%d.%d.%d.%d", ((grub_uint8_t *) &bp->server_ip)[0], ((grub_uint8_t *) &bp->server_ip)[1], ((grub_uint8_t *) &bp->server_ip)[2], ((grub_uint8_t *) &bp->server_ip)[3]); grub_print_error (); } if (size > OFFSET_OF (server_name, bp) && bp->server_name[0]) { grub_env_set_net_property (name, "dhcp_server_name", bp->server_name, sizeof (bp->server_name)); if (is_def && !grub_net_default_server) { grub_net_default_server = grub_strdup (bp->server_name); grub_print_error (); } if (device && !*device) { *device = grub_xasprintf ("tftp,%s", bp->server_name); grub_print_error (); } } if (size > OFFSET_OF (boot_file, bp) && path) { *path = grub_strndup (bp->boot_file, sizeof (bp->boot_file)); grub_print_error (); if (*path) { char *slash; slash = grub_strrchr (*path, '/'); if (slash) *slash = 0; else **path = 0; } } if (size > OFFSET_OF (vendor, bp)) parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp), &mask); grub_net_add_ipv4_local (inter, mask); inter->dhcp_ack = grub_malloc (size); if (inter->dhcp_ack) { grub_memcpy (inter->dhcp_ack, bp, size); inter->dhcp_acklen = size; } else grub_errno = GRUB_ERR_NONE; return inter; }
void grub_machine_get_bootlocation (char **device, char **path) { char *bootpath; grub_ssize_t bootpath_size; char *filename; char *type; if (grub_ieee1275_get_property_length (grub_ieee1275_chosen, "bootpath", &bootpath_size) || bootpath_size <= 0) { /* Should never happen. */ grub_printf ("/chosen/bootpath property missing!\n"); return; } bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); if (! bootpath) { grub_print_error (); return; } grub_ieee1275_get_property (grub_ieee1275_chosen, "bootpath", bootpath, (grub_size_t) bootpath_size + 1, 0); bootpath[bootpath_size] = '\0'; /* Transform an OF device path to a GRUB path. */ type = grub_ieee1275_get_device_type (bootpath); if (type && grub_strcmp (type, "network") == 0) { char *dev, *canon; char *ptr; dev = grub_ieee1275_get_aliasdevname (bootpath); canon = grub_ieee1275_canonicalise_devname (dev); ptr = canon + grub_strlen (canon) - 1; while (ptr > canon && (*ptr == ',' || *ptr == ':')) ptr--; ptr++; *ptr = 0; if (grub_ieee1275_net_config) grub_ieee1275_net_config (canon, device, path, bootpath); grub_free (dev); grub_free (canon); } else *device = grub_ieee1275_encode_devname (bootpath); grub_free (type); filename = grub_ieee1275_get_filename (bootpath); if (filename) { char *lastslash = grub_strrchr (filename, '\\'); /* Truncate at last directory. */ if (lastslash) { *lastslash = '\0'; grub_translate_ieee1275_path (filename); *path = filename; } } grub_free (bootpath); }
char *strrchr(const char *s, int c) { grub_errno = GRUB_ERR_NONE; return grub_strrchr(s, c); }