Merge branch 'mainline' into zfs
[grub2/phcoder.git] / util / hostfs.c
blob1b963bb67e4dce19b8f23b44f3a1c57e806ca98c
1 /* hostfs.c - Dummy filesystem to provide access to the hosts filesystem */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2007,2008 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/>.
19 #define _BSD_SOURCE
20 #include <grub/fs.h>
21 #include <grub/file.h>
22 #include <grub/disk.h>
23 #include <grub/misc.h>
24 #include <grub/dl.h>
25 #include <grub/util/misc.h>
27 #include <dirent.h>
28 #include <stdio.h>
31 #ifndef DT_DIR
32 /* dirent.d_type is a BSD extension, not part of POSIX */
33 #include <sys/stat.h>
34 #include <string.h>
36 static int
37 is_dir (const char *path, const char *name)
39 int len1 = strlen(path);
40 int len2 = strlen(name);
42 char pathname[len1 + 1 + len2 + 1 + 13];
43 strcpy (pathname, path);
45 /* Avoid UNC-path "//name" on Cygwin. */
46 if (len1 > 0 && pathname[len1 - 1] != '/')
47 strcat (pathname, "/");
49 strcat (pathname, name);
51 struct stat st;
52 if (stat (pathname, &st))
53 return 0;
54 return S_ISDIR (st.st_mode);
56 #endif
58 static grub_err_t
59 grub_hostfs_dir (grub_device_t device, const char *path,
60 int (*hook) (const char *filename,
61 const struct grub_dirhook_info *info))
63 DIR *dir;
65 /* Check if the disk is our dummy disk. */
66 if (grub_strcmp (device->disk->name, "host"))
67 return grub_error (GRUB_ERR_BAD_FS, "not a hostfs");
69 dir = opendir (path);
70 if (! dir)
71 return grub_error (GRUB_ERR_BAD_FILENAME,
72 "can't open the hostfs directory `%s'", path);
74 while (1)
76 struct dirent *de;
77 struct grub_dirhook_info info;
78 grub_memset (&info, 0, sizeof (info));
80 de = readdir (dir);
81 if (! de)
82 break;
84 #ifdef DT_DIR
85 info.dir = (de->d_type == DT_DIR);
86 #else
87 info.dir = !! is_dir (path, de->d_name);
88 #endif
89 hook (de->d_name, &info);
93 closedir (dir);
95 return GRUB_ERR_NONE;
98 /* Open a file named NAME and initialize FILE. */
99 static grub_err_t
100 grub_hostfs_open (struct grub_file *file, const char *name)
102 FILE *f;
104 f = fopen (name, "rb");
105 if (! f)
106 return grub_error (GRUB_ERR_BAD_FILENAME,
107 "can't open `%s'", name);
108 file->data = f;
110 #ifdef __MINGW32__
111 file->size = grub_util_get_disk_size (name);
112 #else
113 fseeko (f, 0, SEEK_END);
114 file->size = ftello (f);
115 fseeko (f, 0, SEEK_SET);
116 #endif
118 return GRUB_ERR_NONE;
121 static grub_ssize_t
122 grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len)
124 FILE *f;
126 f = (FILE *) file->data;
127 fseeko (f, file->offset, SEEK_SET);
128 int s = fread (buf, 1, len, f);
130 return s;
133 static grub_err_t
134 grub_hostfs_close (grub_file_t file)
136 FILE *f;
138 f = (FILE *) file->data;
139 fclose (f);
141 return GRUB_ERR_NONE;
144 static grub_err_t
145 grub_hostfs_label (grub_device_t device __attribute ((unused)),
146 char **label __attribute ((unused)))
148 *label = 0;
149 return GRUB_ERR_NONE;
152 static struct grub_fs grub_hostfs_fs =
154 .name = "hostfs",
155 .dir = grub_hostfs_dir,
156 .open = grub_hostfs_open,
157 .read = grub_hostfs_read,
158 .close = grub_hostfs_close,
159 .label = grub_hostfs_label,
160 .next = 0
165 GRUB_MOD_INIT(hostfs)
167 grub_fs_register (&grub_hostfs_fs);
170 GRUB_MOD_FINI(hostfs)
172 grub_fs_unregister (&grub_hostfs_fs);