1 /* hostfs.c - Dummy filesystem to provide access to the hosts filesystem */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007,2008,2009,2010 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/>.
21 #include <grub/file.h>
22 #include <grub/disk.h>
23 #include <grub/misc.h>
26 #include <grub/util/misc.h>
27 #include <grub/emu/hostdisk.h>
28 #include <grub/i18n.h>
35 /* dirent.d_type is a BSD extension, not part of POSIX */
40 is_dir (const char *path
, const char *name
)
42 int len1
= strlen(path
);
43 int len2
= strlen(name
);
45 char pathname
[len1
+ 1 + len2
+ 1 + 13];
46 strcpy (pathname
, path
);
48 /* Avoid UNC-path "//name" on Cygwin. */
49 if (len1
> 0 && pathname
[len1
- 1] != '/')
50 strcat (pathname
, "/");
52 strcat (pathname
, name
);
55 if (stat (pathname
, &st
))
57 return S_ISDIR (st
.st_mode
);
60 struct grub_hostfs_data
67 grub_hostfs_dir (grub_device_t device
, const char *path
,
68 int (*hook
) (const char *filename
,
69 const struct grub_dirhook_info
*info
))
73 /* Check if the disk is our dummy disk. */
74 if (grub_strcmp (device
->disk
->name
, "host"))
75 return grub_error (GRUB_ERR_BAD_FS
, "not a hostfs");
79 return grub_error (GRUB_ERR_BAD_FILENAME
,
80 N_("can't open `%s': %s"), path
,
86 struct grub_dirhook_info info
;
87 grub_memset (&info
, 0, sizeof (info
));
93 info
.dir
= !! is_dir (path
, de
->d_name
);
94 hook (de
->d_name
, &info
);
100 return GRUB_ERR_NONE
;
103 /* Open a file named NAME and initialize FILE. */
105 grub_hostfs_open (struct grub_file
*file
, const char *name
)
108 struct grub_hostfs_data
*data
;
110 f
= fopen (name
, "rb");
112 return grub_error (GRUB_ERR_BAD_FILENAME
,
113 N_("can't open `%s': %s"), name
,
115 data
= grub_malloc (sizeof (*data
));
121 data
->filename
= grub_strdup (name
);
134 file
->size
= grub_util_get_disk_size (name
);
136 file
->size
= grub_util_get_fd_size (fileno (f
), name
, NULL
);
139 return GRUB_ERR_NONE
;
143 grub_hostfs_read (grub_file_t file
, char *buf
, grub_size_t len
)
145 struct grub_hostfs_data
*data
;
148 if (fseeko (data
->f
, file
->offset
, SEEK_SET
) != 0)
150 grub_error (GRUB_ERR_OUT_OF_RANGE
, N_("cannot seek `%s': %s"),
151 data
->filename
, strerror (errno
));
155 unsigned int s
= fread (buf
, 1, len
, data
->f
);
157 grub_error (GRUB_ERR_FILE_READ_ERROR
, N_("cannot read `%s': %s"),
158 data
->filename
, strerror (errno
));
164 grub_hostfs_close (grub_file_t file
)
166 struct grub_hostfs_data
*data
;
170 grub_free (data
->filename
);
173 return GRUB_ERR_NONE
;
177 grub_hostfs_label (grub_device_t device
__attribute ((unused
)),
178 char **label
__attribute ((unused
)))
181 return GRUB_ERR_NONE
;
184 static struct grub_fs grub_hostfs_fs
=
187 .dir
= grub_hostfs_dir
,
188 .open
= grub_hostfs_open
,
189 .read
= grub_hostfs_read
,
190 .close
= grub_hostfs_close
,
191 .label
= grub_hostfs_label
,
197 GRUB_MOD_INIT(hostfs
)
199 grub_fs_register (&grub_hostfs_fs
);
202 GRUB_MOD_FINI(hostfs
)
204 grub_fs_unregister (&grub_hostfs_fs
);