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
 
784 user890104 349
int emcorefs_write(const char* path, const char* buf, uint32_t size, off_t offset, struct fuse_file_info* fi) {
350
    fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
351
 
352
    int res;
353
    uint32_t emcore_errno_value, addr, nwrite = size;
354
 
355
    if (!fi->fh)
356
    {
357
        return -EIO;
358
    }
359
 
360
    res = emcore_malloc(&addr, size);
361
 
362
    if (EMCORE_SUCCESS != res)
363
    {
364
        return -EIO;
365
    }
366
 
367
    do {
368
        if (offset) {
369
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
370
 
371
            if (EMCORE_ERROR_IO == res)
372
            {
373
                res = emcore_errno(&emcore_errno_value);
374
 
375
                if (EMCORE_SUCCESS != res)
376
                {
377
                    nwrite = -EIO;
378
                    break;
379
                }
380
 
381
                if (EMCORE_SUCCESS != emcore_errno_value)
382
                {
383
                    nwrite = -emcore_errno_value;
384
                    break;
385
                }
386
            }
387
 
388
            if (EMCORE_SUCCESS != res)
389
            {
390
                nwrite = -EIO;
391
                break;
392
            }
393
        }
394
 
395
        res = emcore_write(buf, addr, nwrite);
396
 
397
        if (EMCORE_SUCCESS != res)
398
        {
399
            nwrite = -EIO;
400
            break;
401
        }
402
 
403
        res = emcore_file_write(&nwrite, fi->fh, addr, size);
404
 
405
        if (EMCORE_ERROR_IO == res)
406
        {
407
            res = emcore_errno(&emcore_errno_value);
408
 
409
            if (EMCORE_SUCCESS != res)
410
            {
411
                nwrite = -EIO;
412
                break;
413
            }
414
 
415
            if (EMCORE_SUCCESS != emcore_errno_value)
416
            {
417
                nwrite = -emcore_errno_value;
418
                break;
419
            }
420
        }
421
 
422
        if (EMCORE_SUCCESS != res)
423
        {
424
            nwrite = -EIO;
425
        }
426
    }
427
    while(0);
428
 
429
    res = emcore_free(addr);
430
 
431
    if (EMCORE_SUCCESS != res)
432
    {
433
        return -EIO;
434
    }
435
 
436
    cache_remove(path);
437
 
438
    return nwrite;
439
}
440
 
770 user890104 441
int emcorefs_release(const char* path, struct fuse_file_info* fi)
442
{
443
    int res;
444
    uint32_t emcore_errno_value;
445
    (void)path;
446
 
447
    if (!fi->fh)
448
    {
449
        return -EIO;
450
    }
451
 
452
    res = emcore_file_close(fi->fh);
453
 
454
    if (EMCORE_ERROR_IO == res)
455
    {
456
        res = emcore_errno(&emcore_errno_value);
457
 
458
        if (EMCORE_SUCCESS != res)
459
        {
460
            return -EIO;
461
        }
462
 
463
        if (EMCORE_SUCCESS != emcore_errno_value)
464
        {
465
            return -emcore_errno_value;
466
        }
467
    }
468
 
469
    if (EMCORE_SUCCESS != res)
470
    {
471
        return -EIO;
472
    }
473
 
474
    return 0;
475
}
782 user890104 476
 
477
int emcorefs_mkdir(const char* path, mode_t mode)
478
{
479
    (void)mode;
480
    int res;
481
    uint32_t emcore_errno_value;
482
 
483
    res = emcore_dir_create(path);
484
 
485
    if (EMCORE_ERROR_IO == res)
486
    {
487
        res = emcore_errno(&emcore_errno_value);
488
 
489
        if (EMCORE_SUCCESS != res)
490
        {
491
            return -EIO;
492
        }
493
 
494
        if (EMCORE_SUCCESS != emcore_errno_value)
495
        {
496
            return -emcore_errno_value;
497
        }
498
    }
499
 
500
    if (EMCORE_SUCCESS != res)
501
    {
502
        return -EIO;
503
    }
504
 
505
    return 0;
506
}
507
 
508
int emcorefs_rmdir(const char* path)
509
{
510
    int res;
511
    uint32_t emcore_errno_value;
512
 
513
    res = emcore_dir_remove(path);
514
 
515
    if (EMCORE_ERROR_IO == res)
516
    {
517
        res = emcore_errno(&emcore_errno_value);
518
 
519
        if (EMCORE_SUCCESS != res)
520
        {
521
            return -EIO;
522
        }
523
 
524
        if (EMCORE_SUCCESS != emcore_errno_value)
525
        {
526
            return -emcore_errno_value;
527
        }
528
    }
529
 
530
    if (EMCORE_SUCCESS != res)
531
    {
532
        return -EIO;
533
    }
534
 
535
    cache_remove(path);
536
 
537
    return 0;
538
}
539
 
540
int emcorefs_create(const char* path, mode_t mode, struct fuse_file_info* fi)
541
{
542
    (void)mode;
543
    return emcorefs_open(path, fi);
544
}
545
 
546
int emcorefs_mknod(const char* path, mode_t mode, dev_t dev)
547
{
548
    (void)dev;
549
    int res;
550
    struct fuse_file_info fi;
551
 
552
    fi.flags = O_WRONLY | O_CREAT | O_TRUNC;
553
 
554
    res = emcorefs_create(path, mode, &fi);
555
 
556
    if (0 != res) {
557
        return res;
558
    }
559
 
560
    return emcorefs_release(path, &fi);
561
}
562
 
563
int emcorefs_unlink(const char* path)
564
{
565
    int res;
566
    uint32_t emcore_errno_value;
567
 
568
    res = emcore_file_unlink(path);
569
 
570
    if (EMCORE_ERROR_IO == res)
571
    {
572
        res = emcore_errno(&emcore_errno_value);
573
 
574
        if (EMCORE_SUCCESS != res)
575
        {
576
            return -EIO;
577
        }
578
 
579
        if (EMCORE_SUCCESS != emcore_errno_value)
580
        {
581
            return -emcore_errno_value;
582
        }
583
    }
584
 
585
    if (EMCORE_SUCCESS != res)
586
    {
587
        return -EIO;
588
    }
589
 
590
    cache_remove(path);
591
 
592
    return 0;
784 user890104 593
}
594
 
595
int emcorefs_rename(const char* path, const char* new_path)
596
{
597
    int res;
598
    uint32_t emcore_errno_value;
599
 
600
    res = emcore_file_rename(path, new_path);
601
 
602
    if (EMCORE_ERROR_IO == res)
603
    {
604
        res = emcore_errno(&emcore_errno_value);
605
 
606
        if (EMCORE_SUCCESS != res)
607
        {
608
            return -EIO;
609
        }
610
 
611
        if (EMCORE_SUCCESS != emcore_errno_value)
612
        {
613
            return -emcore_errno_value;
614
        }
615
    }
616
 
617
    if (EMCORE_SUCCESS != res)
618
    {
619
        return -EIO;
620
    }
621
 
622
    cache_remove(path);
623
 
624
    return 0;
625
}
626
 
627
int emcorefs_truncate(const char* path, off_t size)
628
{
629
    int res;
630
    struct fuse_file_info fi;
631
 
632
    res = emcorefs_open(path, &fi);
633
 
634
    if (0 != res) {
635
        return res;
636
    }
637
 
638
    res = emcorefs_ftruncate(path, size, &fi);
639
 
640
    if (0 != res) {
641
        return res;
642
    }
643
 
644
    return emcorefs_release(path, &fi);
645
}
646
 
647
int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi)
648
{
649
    int res;
650
    uint32_t emcore_errno_value;
651
    (void)path;
652
 
653
    if (!fi->fh)
654
    {
655
        return -EIO;
656
    }
657
 
658
    res = emcore_file_truncate(fi->fh, size);
659
 
660
    if (EMCORE_ERROR_IO == res)
661
    {
662
        res = emcore_errno(&emcore_errno_value);
663
 
664
        if (EMCORE_SUCCESS != res)
665
        {
666
            return -EIO;
667
        }
668
 
669
        if (EMCORE_SUCCESS != emcore_errno_value)
670
        {
671
            return -emcore_errno_value;
672
        }
673
    }
674
 
675
    if (EMCORE_SUCCESS != res)
676
    {
677
        return -EIO;
678
    }
679
 
680
    cache_remove(path);
681
 
682
    return 0;
683
}
684