Initial Commit
[Projects.git] / pkgbuilds / wiifuse / src / wiifuse-0.2.0 / fs_tree.c
blob4d47eb5cf795c1349a65c9b821c63cb9cef9de47
1 /*
2 * Copyright (C) 2008 dhewg, #wiidev efnet
3 * based on code by:
4 * Copyright (C) 2006 Mike Melanson (mike at multimedia.cx)
6 * this file is part of wiifuse
7 * http://wiibrew.org/index.php?title=Wiifuse
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <sys/types.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include <errno.h>
31 #include "global.h"
32 #include "io.h"
33 #include "tree.h"
34 #include "fs_tree.h"
36 int fs_tree_getattr (const char *path, struct stat *stbuf) {
37 struct image_file *image = (struct image_file *)
38 fuse_get_context ()->private_data;
39 struct tree *node;
41 node = tree_find_entry (image->tree, path);
42 if (!node)
43 return -ENOENT;
45 memset (stbuf, 0, sizeof (struct stat));
47 switch (node->type) {
48 case TREE_DIR:
49 stbuf->st_mode = S_IFDIR |
50 S_IRUSR | S_IRGRP | S_IROTH |
51 S_IXUSR | S_IXGRP | S_IXOTH;
52 stbuf->st_nlink = 2 + node->nsubdirs;
53 break;
55 case TREE_RAW_FILE:
56 case TREE_FILE:
57 case TREE_MEM:
58 case TREE_UINT:
59 case TREE_HEX_UINT8:
60 case TREE_HEX_UINT16:
61 case TREE_HEX_UINT32:
62 case TREE_HEX_UINT64:
63 case TREE_CHAR:
64 case TREE_STRING:
65 stbuf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
66 stbuf->st_nlink = 1;
67 stbuf->st_size = node->v2;
68 stbuf->st_blocks = node->v2 / 512;
69 break;
71 case TREE_SYMLINK:
72 stbuf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
73 stbuf->st_nlink = 1;
74 stbuf->st_size = node->v2;
75 break;
78 stbuf->st_uid = image->st.st_uid;
79 stbuf->st_gid = image->st.st_gid;
80 stbuf->st_atime = image->st.st_atime;
81 stbuf->st_mtime = image->st.st_mtime;
82 stbuf->st_ctime = image->st.st_ctime;
84 return 0;
87 int fs_tree_open (const char *path, struct fuse_file_info *fi) {
88 struct image_file *image = (struct image_file *)
89 fuse_get_context ()->private_data;
90 struct tree *node;
92 if (fi->flags & O_WRONLY)
93 return -EROFS;
95 node = tree_find_entry (image->tree, path);
97 if (!node)
98 return -ENOENT;
100 return 0;
103 int fs_tree_read (const char *path, char *buf, size_t size,
104 off_t offset, struct fuse_file_info *fi) {
105 struct image_file *image = (struct image_file *)
106 fuse_get_context ()->private_data;
107 struct tree *node;
108 u64 pos;
109 int ret = 0;
111 (void) fi;
113 node = tree_find_entry (image->tree, path);
114 if (!node)
115 return -ENOENT;
117 if (node->type == TREE_DIR)
118 return -EISDIR;
120 if (offset >= node->v2)
121 return 0;
123 pos = node->v1 + offset;
125 if (offset + size > node->v2)
126 size = node->v2 - offset;
128 switch (node->type) {
129 case TREE_RAW_FILE:
130 pthread_mutex_lock (&image->mutex);
131 ret = io_read (buf, size, image,
132 image->parts[node->part].offset + pos);
133 pthread_mutex_unlock (&image->mutex);
134 break;
136 case TREE_FILE:
137 pthread_mutex_lock (&image->mutex);
138 ret = io_read_part (buf, size, image, node->part, pos);
139 pthread_mutex_unlock (&image->mutex);
140 break;
142 case TREE_UINT:
143 sprintf (buf, "%llu\n", node->v1);
144 ret = strlen (buf);
145 break;
147 case TREE_HEX_UINT8:
148 sprintf (buf, "0x%02x\n", (u8) node->v1);
149 ret = strlen (buf);
150 break;
152 case TREE_HEX_UINT16:
153 sprintf (buf, "0x%04x\n", (u16) node->v1);
154 ret = strlen (buf);
155 break;
157 case TREE_HEX_UINT32:
158 sprintf (buf, "0x%08x\n", (u32) node->v1);
159 ret = strlen (buf);
160 break;
162 case TREE_HEX_UINT64:
163 sprintf (buf, "0x%016llx\n", node->v1);
164 ret = strlen (buf);
165 break;
167 case TREE_MEM:
168 memcpy (buf, pos, size);
169 ret = size;
170 break;
172 case TREE_CHAR:
173 buf[0] = (char) node->v1;
174 buf[1] = '\n';
175 ret = 2;
176 break;
178 case TREE_STRING:
179 memcpy (buf, pos, size);
180 buf[size - 1] = '\n';
181 ret = size;
182 break;
184 case TREE_SYMLINK:
185 strcpy (buf, pos);
186 ret = 5;
187 break;
189 case TREE_DIR:
190 break;
193 return ret;
196 int fs_tree_readlink (const char *path, char *buf, size_t size) {
197 struct image_file *image = (struct image_file *)
198 fuse_get_context ()->private_data;
199 struct tree *node;
201 node = tree_find_entry (image->tree, path);
202 if (!node)
203 return -ENOENT;
205 if (node->type != TREE_SYMLINK)
206 return -EINVAL;
208 strncpy (buf, node->v1, size);
209 buf[size - 1] = 0;
211 return 0;
214 int fs_tree_opendir (const char *path, struct fuse_file_info *fi) {
215 struct image_file *image = (struct image_file *)
216 fuse_get_context ()->private_data;
217 struct tree *node = tree_find_entry (image->tree, path);
219 (void) fi;
221 if (!node)
222 return -ENOENT;
224 if (node->type != TREE_DIR)
225 return -ENOTDIR;
227 return 0;
230 int fs_tree_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
231 off_t offset, struct fuse_file_info *fi) {
232 struct image_file *image = (struct image_file *)
233 fuse_get_context ()->private_data;
234 struct tree *node;
236 (void) offset;
237 (void) fi;
239 node = tree_find_entry (image->tree, path);
241 if (!node)
242 return -ENOENT;
244 if (node->type != TREE_DIR)
245 return -ENOTDIR;
247 filler (buf, ".", NULL, 0);
248 filler (buf, "..", NULL, 0);
250 node = node->sub;
251 while (node) {
252 filler (buf, node->name, NULL, 0);
253 node = node->next;
256 return 0;
259 int fs_tree_statfs (const char *path, struct statvfs *svfs) {
260 struct image_file *image = (struct image_file *)
261 fuse_get_context ()->private_data;
263 (void) path;
265 memset (svfs, 0, sizeof (struct statvfs));
267 svfs->f_bsize = 1;
268 svfs->f_blocks = image->nbytes;
269 svfs->f_files = image->nfiles;
271 return 0;
274 void fs_tree_get_ops (struct fuse_operations *fs_ops) {
275 memset (fs_ops, 0, sizeof (struct fuse_operations));
277 fs_ops->getattr = fs_tree_getattr;
278 fs_ops->open = fs_tree_open;
279 fs_ops->read = fs_tree_read;
280 fs_ops->opendir = fs_tree_opendir;
281 fs_ops->readdir = fs_tree_readdir;
282 fs_ops->readlink = fs_tree_readlink;
283 fs_ops->statfs = fs_tree_statfs;