(search_file): Improve error message.
[grub2/phcoder/solaris.git] / disk / fs_file.c
blobe09568250f4112879ba208e05a96a88e78e4c675
1 /* fs_file.c - Access partition by a file it contains. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/disk.h>
21 #include <grub/dl.h>
22 #include <grub/file.h>
23 #include <grub/misc.h>
24 #include <grub/mm.h>
25 #include <grub/partition.h>
27 static grub_device_t
28 search_fs_file (const char *key, unsigned long *count)
30 char *filename = NULL;
31 grub_device_t ret = NULL;
32 *count = 0;
34 auto int iterate_device (const char *name);
35 int iterate_device (const char *name)
37 int len;
38 grub_file_t file;
40 (*count)++;
42 len = grub_strlen (name) + 2 + grub_strlen (key) + 1;
43 filename = grub_realloc (filename, len);
44 if (! filename)
45 return 1;
47 grub_sprintf (filename, "(%s)%s", name, key);
48 file = grub_file_open (filename);
49 if (file)
51 grub_file_close (file);
52 ret = grub_device_open (name);
53 return 1;
56 grub_errno = GRUB_ERR_NONE;
57 return 0;
60 grub_device_iterate (iterate_device);
61 grub_free (filename);
63 return ret;
66 static grub_err_t
67 grub_fs_file_open (const char *name, grub_disk_t disk)
69 grub_device_t dev;
71 if (grub_strncmp (name, "FILE=", sizeof ("FILE=") - 1))
72 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a FILE virtual volume");
74 dev = search_fs_file (name + sizeof ("FILE=") - 1, &disk->id);
75 if (! dev)
76 return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file found");
78 disk->total_sectors = dev->disk->total_sectors;
79 disk->has_partitions = 0;
80 if (dev->disk->partition)
82 disk->partition = grub_malloc (sizeof (*disk->partition));
83 if (disk->partition)
84 grub_memcpy (disk->partition, dev->disk->partition,
85 sizeof (*disk->partition));
87 else
88 disk->partition = NULL;
90 disk->data = dev;
92 return GRUB_ERR_NONE;
95 static void
96 grub_fs_file_close (grub_disk_t disk)
98 grub_device_t parent = disk->data;
99 grub_device_close (parent);
102 static grub_err_t
103 grub_fs_file_read (grub_disk_t disk, grub_disk_addr_t sector,
104 grub_size_t size, char *buf)
106 grub_device_t parent = disk->data;
107 return parent->disk->dev->read (parent->disk, sector, size, buf);
110 static grub_err_t
111 grub_fs_file_write (grub_disk_t disk, grub_disk_addr_t sector,
112 grub_size_t size, const char *buf)
114 grub_device_t parent = disk->data;
115 return parent->disk->dev->write (parent->disk, sector, size, buf);
118 static struct grub_disk_dev grub_fs_file_dev = {
119 .name = "fs_file",
120 .id = GRUB_DISK_DEVICE_FILE_ID,
121 .open = grub_fs_file_open,
122 .close = grub_fs_file_close,
123 .read = grub_fs_file_read,
124 .write = grub_fs_file_write,
125 .next = 0
128 GRUB_MOD_INIT (fs_file)
130 grub_disk_dev_register (&grub_fs_file_dev);
133 GRUB_MOD_FINI (fs_file)
135 grub_disk_dev_unregister (&grub_fs_file_dev);