1 /* file.c - file I/O functions */
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>
22 #include <grub/file.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. */
36 grub_file_get_device_name (const char *name
)
40 char *p
= grub_strchr (name
, ')');
45 grub_error (GRUB_ERR_BAD_FILENAME
, N_("missing `%c' symbol"), ')');
49 ret
= (char *) grub_malloc (p
- name
);
53 grub_memcpy (ret
, name
+ 1, p
- name
- 1);
54 ret
[p
- name
- 1] = '\0';
62 grub_file_open (const char *name
)
64 grub_device_t device
= 0;
65 grub_file_t file
= 0, last_file
= 0;
68 grub_file_filter_id_t filter
;
70 device_name
= grub_file_get_device_name (name
);
74 /* Get the file part of NAME. */
75 file_name
= (name
[0] == '(') ? grub_strchr (name
, ')') : NULL
;
79 file_name
= (char *) name
;
81 device
= grub_device_open (device_name
);
82 grub_free (device_name
);
86 file
= (grub_file_t
) grub_zalloc (sizeof (*file
));
90 file
->device
= device
;
92 if (device
->disk
&& file_name
[0] != '/')
93 /* This is a block list. */
94 file
->fs
= &grub_fs_blocklist
;
97 file
->fs
= grub_fs_probe (device
);
102 if ((file
->fs
->open
) (file
, file_name
) != GRUB_ERR_NONE
)
105 for (filter
= 0; file
&& filter
< ARRAY_SIZE (grub_file_filters_enabled
);
107 if (grub_file_filters_enabled
[filter
])
110 file
= grub_file_filters_enabled
[filter
] (file
);
113 grub_file_close (last_file
);
115 grub_memcpy (grub_file_filters_enabled
, grub_file_filters_all
,
116 sizeof (grub_file_filters_enabled
));
122 grub_device_close (device
);
124 /* if (net) grub_net_close (net); */
128 grub_memcpy (grub_file_filters_enabled
, grub_file_filters_all
,
129 sizeof (grub_file_filters_enabled
));
135 grub_file_read (grub_file_t file
, void *buf
, grub_size_t len
)
139 if (file
->offset
> file
->size
)
141 grub_error (GRUB_ERR_OUT_OF_RANGE
,
142 N_("attempt to read past the end of file"));
149 if (len
> file
->size
- file
->offset
)
150 len
= file
->size
- file
->offset
;
152 /* Prevent an overflow. */
153 if ((grub_ssize_t
) len
< 0)
158 res
= (file
->fs
->read
) (file
, buf
, len
);
166 grub_file_close (grub_file_t file
)
169 (file
->fs
->close
) (file
);
172 grub_device_close (file
->device
);
178 grub_file_seek (grub_file_t file
, grub_off_t offset
)
182 if (offset
> file
->size
)
184 grub_error (GRUB_ERR_OUT_OF_RANGE
,
185 N_("attempt to seek outside of the file"));
190 file
->offset
= offset
;