Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / kern / file.c
blob495326f1259b81240b4216a2db1aa5864f5c73ca
1 /* file.c - file I/O functions */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2006,2007,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/misc.h>
21 #include <grub/err.h>
22 #include <grub/file.h>
23 #include <grub/net.h>
24 #include <grub/mm.h>
25 #include <grub/fs.h>
26 #include <grub/device.h>
27 #include <grub/i18n.h>
29 void (*EXPORT_VAR (grub_grubnet_fini)) (void);
31 grub_file_filter_t grub_file_filters_all[GRUB_FILE_FILTER_MAX];
32 grub_file_filter_t grub_file_filters_enabled[GRUB_FILE_FILTER_MAX];
34 /* Get the device part of the filename NAME. It is enclosed by parentheses. */
35 char *
36 grub_file_get_device_name (const char *name)
38 if (name[0] == '(')
40 char *p = grub_strchr (name, ')');
41 char *ret;
43 if (! p)
45 grub_error (GRUB_ERR_BAD_FILENAME, N_("missing `%c' symbol"), ')');
46 return 0;
49 ret = (char *) grub_malloc (p - name);
50 if (! ret)
51 return 0;
53 grub_memcpy (ret, name + 1, p - name - 1);
54 ret[p - name - 1] = '\0';
55 return ret;
58 return 0;
61 grub_file_t
62 grub_file_open (const char *name)
64 grub_device_t device = 0;
65 grub_file_t file = 0, last_file = 0;
66 char *device_name;
67 char *file_name;
68 grub_file_filter_id_t filter;
70 device_name = grub_file_get_device_name (name);
71 if (grub_errno)
72 goto fail;
74 /* Get the file part of NAME. */
75 file_name = (name[0] == '(') ? grub_strchr (name, ')') : NULL;
76 if (file_name)
77 file_name++;
78 else
79 file_name = (char *) name;
81 device = grub_device_open (device_name);
82 grub_free (device_name);
83 if (! device)
84 goto fail;
86 file = (grub_file_t) grub_zalloc (sizeof (*file));
87 if (! file)
88 goto fail;
90 file->device = device;
92 if (device->disk && file_name[0] != '/')
93 /* This is a block list. */
94 file->fs = &grub_fs_blocklist;
95 else
97 file->fs = grub_fs_probe (device);
98 if (! file->fs)
99 goto fail;
102 if ((file->fs->open) (file, file_name) != GRUB_ERR_NONE)
103 goto fail;
105 for (filter = 0; file && filter < ARRAY_SIZE (grub_file_filters_enabled);
106 filter++)
107 if (grub_file_filters_enabled[filter])
109 last_file = file;
110 file = grub_file_filters_enabled[filter] (file);
112 if (!file)
113 grub_file_close (last_file);
115 grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
116 sizeof (grub_file_filters_enabled));
118 return file;
120 fail:
121 if (device)
122 grub_device_close (device);
124 /* if (net) grub_net_close (net); */
126 grub_free (file);
128 grub_memcpy (grub_file_filters_enabled, grub_file_filters_all,
129 sizeof (grub_file_filters_enabled));
131 return 0;
134 grub_ssize_t
135 grub_file_read (grub_file_t file, void *buf, grub_size_t len)
137 grub_ssize_t res;
139 if (file->offset > file->size)
141 grub_error (GRUB_ERR_OUT_OF_RANGE,
142 N_("attempt to read past the end of file"));
143 return -1;
146 if (len == 0)
147 return 0;
149 if (len > file->size - file->offset)
150 len = file->size - file->offset;
152 /* Prevent an overflow. */
153 if ((grub_ssize_t) len < 0)
154 len >>= 1;
156 if (len == 0)
157 return 0;
158 res = (file->fs->read) (file, buf, len);
159 if (res > 0)
160 file->offset += res;
162 return res;
165 grub_err_t
166 grub_file_close (grub_file_t file)
168 if (file->fs->close)
169 (file->fs->close) (file);
171 if (file->device)
172 grub_device_close (file->device);
173 grub_free (file);
174 return grub_errno;
177 grub_off_t
178 grub_file_seek (grub_file_t file, grub_off_t offset)
180 grub_off_t old;
182 if (offset > file->size)
184 grub_error (GRUB_ERR_OUT_OF_RANGE,
185 N_("attempt to seek outside of the file"));
186 return -1;
189 old = file->offset;
190 file->offset = offset;
192 return old;