Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
3
//    Copyright 2011 user890104
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
 
26
#include "fuse.h"
27
#include "util.h"
28
#include "cache.h"
29
#include "emcore.h"
30
 
31
 
782 user890104 32
int emcorefs_init(void)
33
{
34
    int res;
35
    uint32_t count;
36
 
37
    res = emcore_file_close_all(&count);
38
 
39
    if (EMCORE_SUCCESS != res)
40
    {
41
        return res;
42
    }
43
 
44
    res = emcore_dir_close_all(&count);
45
 
46
    return res;
47
}
48
 
770 user890104 49
int emcorefs_getattr(const char* path, struct stat* stbuf)
50
{
51
    int res = 0;
52
    struct emcore_dir_entry *entry = NULL, curr_entry;
53
    uint32_t dir_handle;
54
    char *parent, *filename;
55
 
56
    memset(stbuf, 0, sizeof(*stbuf));
57
 
782 user890104 58
#ifdef DEBUG2
59
    if (0 == strcmp(path, "/__cache_dump"))
60
    {
61
        cache_dump();
62
    }
63
#endif
770 user890104 64
    entry = cache_get(path);
65
 
66
    if (NULL == entry)
67
    {
68
        parent = strdup(path);
69
        dirname(parent);
70
        filename = basename((char*)path);
71
 
72
        res = emcore_dir_open(&dir_handle, parent);
73
 
74
        if (EMCORE_SUCCESS == res)
75
        {
76
            while (1)
77
            {
78
                res = emcore_dir_read(&curr_entry, dir_handle);
79
 
80
                if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
81
                {
82
                    break;
83
                }
84
 
85
                if (EMCORE_SUCCESS != res)
86
                {
87
                    break;
88
                }
89
 
90
                cache_insert(parent, &curr_entry);
91
 
92
                if (0 == strcmp(filename, curr_entry.name))
93
                {
94
                    entry = malloc(sizeof(*entry));
95
 
96
                    memcpy(entry, &curr_entry, sizeof(curr_entry));
97
 
98
                    break;
99
                }
100
            };
101
 
102
            emcore_dir_close(dir_handle);
103
        }
104
 
105
        free(parent);
106
    }
107
 
108
    if (NULL == entry) {
109
        if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
110
        {
111
            return -ENOENT;
112
        }
113
 
114
        return -EIO;
115
    }
116
    else
117
    {
118
        stbuf->st_uid = getuid();
119
        stbuf->st_gid = getgid();
120
        stbuf->st_mtime = fat_time_to_unix_ts(entry->wrttime, entry->wrtdate);
121
 
122
        if (entry->attributes & 0x10)
123
        {
124
            stbuf->st_mode = S_IFDIR | 0755;
125
            stbuf->st_nlink = 2;
126
            stbuf->st_size = 0x1000;
127
        }
128
        else
129
        {
130
            stbuf->st_mode = S_IFREG | 0644;
131
            stbuf->st_nlink = 1;
132
            stbuf->st_size = entry->size;
133
        }
134
    }
135
 
136
    return 0;
137
}
138
 
139
int emcorefs_opendir(const char* path, struct fuse_file_info* fi)
140
{
141
    int res;
142
    uint32_t handle;
143
 
144
    res = emcore_dir_open(&handle, path);
145
 
146
    if (EMCORE_SUCCESS != res)
147
    {
148
        return -EIO;
149
    }
150
 
151
    fi->fh = handle;
152
 
153
    return 0;
154
}
155
 
156
int emcorefs_readdir(const char* path, void* buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi)
157
{
158
    int res;
159
    struct emcore_dir_entry entry;
160
    (void) offset;
161
    (void) fi;
162
 
163
    if (strcmp(path, "/") == 0)
164
    {
165
        filler(buf, ".", NULL, 0);
166
        filler(buf, "..", NULL, 0);
167
    }
168
 
169
    while (1)
170
    {
171
        res = emcore_dir_read(&entry, fi->fh);
172
 
173
        if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
174
        {
175
            break;
176
        }
177
 
178
        if (EMCORE_SUCCESS != res)
179
        {
180
            return -EIO;
181
        }
182
 
183
        cache_insert(path, &entry);
184
 
185
        filler(buf, entry.name, NULL, 0);
186
    }
187
 
188
    return 0;
189
}
190
 
191
int emcorefs_releasedir(const char* path, struct fuse_file_info* fi)
192
{
193
    int res;
194
    uint32_t emcore_errno_value;
195
    (void)path;
196
 
197
    res = emcore_dir_close(fi->fh);
198
 
199
    if (EMCORE_ERROR_IO == res)
200
    {
201
        res = emcore_errno(&emcore_errno_value);
202
 
203
        if (EMCORE_SUCCESS != res)
204
        {
205
            return -EIO;
206
        }
207
 
208
        if (EMCORE_SUCCESS != emcore_errno_value)
209
        {
210
            return -emcore_errno_value;
211
        }
212
    }
213
 
214
    if (EMCORE_SUCCESS != res)
215
    {
216
        return -EIO;
217
    }
218
 
219
    return 0;
220
}
221
 
222
int emcorefs_open(const char* path, struct fuse_file_info* fi)
223
{
224
    int res;
225
    uint32_t handle, emcore_errno_value;
782 user890104 226
 
227
#ifdef DEBUG
228
    fprintf(stderr, "FILE OPEN: [%s], 0x%08x\n", path, fi->flags);
229
#endif
230
 
770 user890104 231
    res = emcore_file_open(&handle, path, fi->flags);
232
 
233
    if (EMCORE_ERROR_IO == res)
234
    {
235
        res = emcore_errno(&emcore_errno_value);
236
 
237
        if (EMCORE_SUCCESS != res)
238
        {
239
            return -EIO;
240
        }
241
 
242
        if (EMCORE_SUCCESS != emcore_errno_value)
243
        {
244
            return -emcore_errno_value;
245
        }
246
    }
247
 
248
    if (EMCORE_SUCCESS != res)
249
    {
250
        return -EIO;
251
    }
252
 
253
    fi->fh = handle;
254
 
255
    return 0;
256
}
257
 
258
int emcorefs_read(const char* path, char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi) {
259
    fprintf(stderr, "FUSE_READ: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
260
 
261
    int res;
262
    uint32_t emcore_errno_value, addr, nread = size;
263
 
264
    if (!fi->fh)
265
    {
266
        return -EIO;
267
    }
268
 
269
    res = emcore_malloc(&addr, size);
270
 
271
    if (EMCORE_SUCCESS != res)
272
    {
273
        return -EIO;
274
    }
275
 
276
    do {
277
        if (offset) {
278
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
279
 
280
            if (EMCORE_ERROR_IO == res)
281
            {
282
                res = emcore_errno(&emcore_errno_value);
283
 
284
                if (EMCORE_SUCCESS != res)
285
                {
286
                    nread = -EIO;
287
                    break;
288
                }
289
 
290
                if (EMCORE_SUCCESS != emcore_errno_value)
291
                {
292
                    nread = -emcore_errno_value;
293
                    break;
294
                }
295
            }
296
 
297
            if (EMCORE_SUCCESS != res)
298
            {
299
                nread = -EIO;
300
                break;
301
            }
302
        }
303
 
304
        res = emcore_file_read(&nread, fi->fh, addr, size);
305
 
306
        if (EMCORE_ERROR_IO == res)
307
        {
308
            res = emcore_errno(&emcore_errno_value);
309
 
310
            if (EMCORE_SUCCESS != res)
311
            {
312
                nread = -EIO;
313
                break;
314
            }
315
 
316
            if (EMCORE_SUCCESS != emcore_errno_value)
317
            {
318
                nread = -emcore_errno_value;
319
                break;
320
            }
321
        }
322
 
323
        if (EMCORE_SUCCESS != res)
324
        {
325
            nread = -EIO;
326
            break;
327
        }
328
 
329
        res = emcore_read(buf, addr, nread);
330
 
331
        if (EMCORE_SUCCESS != res)
332
        {
333
            nread = -EIO;
334
        }
335
 
336
    }
337
    while(0);
338
 
339
    res = emcore_free(addr);
340
 
341
    if (EMCORE_SUCCESS != res)
342
    {
343
        return -EIO;
344
    }
345
 
346
    return nread;
347
}
348
 
349
int emcorefs_release(const char* path, struct fuse_file_info* fi)
350
{
351
    int res;
352
    uint32_t emcore_errno_value;
353
    (void)path;
354
 
355
    if (!fi->fh)
356
    {
357
        return -EIO;
358
    }
359
 
360
    res = emcore_file_close(fi->fh);
361
 
362
    if (EMCORE_ERROR_IO == res)
363
    {
364
        res = emcore_errno(&emcore_errno_value);
365
 
366
        if (EMCORE_SUCCESS != res)
367
        {
368
            return -EIO;
369
        }
370
 
371
        if (EMCORE_SUCCESS != emcore_errno_value)
372
        {
373
            return -emcore_errno_value;
374
        }
375
    }
376
 
377
    if (EMCORE_SUCCESS != res)
378
    {
379
        return -EIO;
380
    }
381
 
382
    return 0;
383
}
782 user890104 384
 
385
int emcorefs_mkdir(const char* path, mode_t mode)
386
{
387
    (void)mode;
388
    int res;
389
    uint32_t emcore_errno_value;
390
 
391
    res = emcore_dir_create(path);
392
 
393
    if (EMCORE_ERROR_IO == res)
394
    {
395
        res = emcore_errno(&emcore_errno_value);
396
 
397
        if (EMCORE_SUCCESS != res)
398
        {
399
            return -EIO;
400
        }
401
 
402
        if (EMCORE_SUCCESS != emcore_errno_value)
403
        {
404
            return -emcore_errno_value;
405
        }
406
    }
407
 
408
    if (EMCORE_SUCCESS != res)
409
    {
410
        return -EIO;
411
    }
412
 
413
    return 0;
414
}
415
 
416
int emcorefs_rmdir(const char* path)
417
{
418
    int res;
419
    uint32_t emcore_errno_value;
420
 
421
    res = emcore_dir_remove(path);
422
 
423
    if (EMCORE_ERROR_IO == res)
424
    {
425
        res = emcore_errno(&emcore_errno_value);
426
 
427
        if (EMCORE_SUCCESS != res)
428
        {
429
            return -EIO;
430
        }
431
 
432
        if (EMCORE_SUCCESS != emcore_errno_value)
433
        {
434
            return -emcore_errno_value;
435
        }
436
    }
437
 
438
    if (EMCORE_SUCCESS != res)
439
    {
440
        return -EIO;
441
    }
442
 
443
    cache_remove(path);
444
 
445
    return 0;
446
}
447
 
448
int emcorefs_create(const char* path, mode_t mode, struct fuse_file_info* fi)
449
{
450
    (void)mode;
451
    return emcorefs_open(path, fi);
452
}
453
 
454
int emcorefs_mknod(const char* path, mode_t mode, dev_t dev)
455
{
456
    (void)dev;
457
    int res;
458
    struct fuse_file_info fi;
459
 
460
    fi.flags = O_WRONLY | O_CREAT | O_TRUNC;
461
 
462
    res = emcorefs_create(path, mode, &fi);
463
 
464
    if (0 != res) {
465
        return res;
466
    }
467
 
468
    return emcorefs_release(path, &fi);
469
}
470
 
471
int emcorefs_unlink(const char* path)
472
{
473
 
474
    int res;
475
    uint32_t emcore_errno_value;
476
 
477
    res = emcore_file_unlink(path);
478
 
479
    if (EMCORE_ERROR_IO == res)
480
    {
481
        res = emcore_errno(&emcore_errno_value);
482
 
483
        if (EMCORE_SUCCESS != res)
484
        {
485
            return -EIO;
486
        }
487
 
488
        if (EMCORE_SUCCESS != emcore_errno_value)
489
        {
490
            return -emcore_errno_value;
491
        }
492
    }
493
 
494
    if (EMCORE_SUCCESS != res)
495
    {
496
        return -EIO;
497
    }
498
 
499
    cache_remove(path);
500
 
501
    return 0;
502
}