Subversion Repositories freemyipod

Rev

Go to most recent revision | 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
 
785 user890104 258
int emcorefs_read(const char* path, char* buf, size_t size, off_t offset, struct fuse_file_info* fi) {
259
#ifdef DEBUG2
770 user890104 260
    fprintf(stderr, "FUSE_READ: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 261
#else
262
    (void)path;
263
#endif
770 user890104 264
    int res;
265
    uint32_t emcore_errno_value, addr, nread = size;
266
 
267
    if (!fi->fh)
268
    {
269
        return -EIO;
270
    }
271
 
272
    res = emcore_malloc(&addr, size);
273
 
274
    if (EMCORE_SUCCESS != res)
275
    {
276
        return -EIO;
277
    }
278
 
279
    do {
280
        if (offset) {
281
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
282
 
283
            if (EMCORE_ERROR_IO == res)
284
            {
285
                res = emcore_errno(&emcore_errno_value);
286
 
287
                if (EMCORE_SUCCESS != res)
288
                {
289
                    nread = -EIO;
290
                    break;
291
                }
292
 
293
                if (EMCORE_SUCCESS != emcore_errno_value)
294
                {
295
                    nread = -emcore_errno_value;
296
                    break;
297
                }
298
            }
299
 
300
            if (EMCORE_SUCCESS != res)
301
            {
302
                nread = -EIO;
303
                break;
304
            }
305
        }
306
 
307
        res = emcore_file_read(&nread, fi->fh, addr, size);
308
 
309
        if (EMCORE_ERROR_IO == res)
310
        {
311
            res = emcore_errno(&emcore_errno_value);
312
 
313
            if (EMCORE_SUCCESS != res)
314
            {
315
                nread = -EIO;
316
                break;
317
            }
318
 
319
            if (EMCORE_SUCCESS != emcore_errno_value)
320
            {
321
                nread = -emcore_errno_value;
322
                break;
323
            }
324
        }
325
 
326
        if (EMCORE_SUCCESS != res)
327
        {
328
            nread = -EIO;
329
            break;
330
        }
331
 
332
        res = emcore_read(buf, addr, nread);
333
 
334
        if (EMCORE_SUCCESS != res)
335
        {
336
            nread = -EIO;
337
        }
338
 
339
    }
340
    while(0);
341
 
342
    res = emcore_free(addr);
343
 
344
    if (EMCORE_SUCCESS != res)
345
    {
346
        return -EIO;
347
    }
348
 
349
    return nread;
350
}
351
 
785 user890104 352
int emcorefs_write(const char* path, const char* buf, size_t size, off_t offset, struct fuse_file_info* fi) {
353
#ifdef DEBUG2
784 user890104 354
    fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 355
#else
356
    (void)path;
357
#endif
784 user890104 358
    int res;
359
    uint32_t emcore_errno_value, addr, nwrite = size;
360
 
361
    if (!fi->fh)
362
    {
363
        return -EIO;
364
    }
365
 
366
    res = emcore_malloc(&addr, size);
367
 
368
    if (EMCORE_SUCCESS != res)
369
    {
370
        return -EIO;
371
    }
372
 
373
    do {
374
        if (offset) {
375
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
376
 
377
            if (EMCORE_ERROR_IO == res)
378
            {
379
                res = emcore_errno(&emcore_errno_value);
380
 
381
                if (EMCORE_SUCCESS != res)
382
                {
383
                    nwrite = -EIO;
384
                    break;
385
                }
386
 
387
                if (EMCORE_SUCCESS != emcore_errno_value)
388
                {
389
                    nwrite = -emcore_errno_value;
390
                    break;
391
                }
392
            }
393
 
394
            if (EMCORE_SUCCESS != res)
395
            {
396
                nwrite = -EIO;
397
                break;
398
            }
399
        }
400
 
401
        res = emcore_write(buf, addr, nwrite);
402
 
403
        if (EMCORE_SUCCESS != res)
404
        {
405
            nwrite = -EIO;
406
            break;
407
        }
408
 
409
        res = emcore_file_write(&nwrite, fi->fh, addr, size);
410
 
411
        if (EMCORE_ERROR_IO == res)
412
        {
413
            res = emcore_errno(&emcore_errno_value);
414
 
415
            if (EMCORE_SUCCESS != res)
416
            {
417
                nwrite = -EIO;
418
                break;
419
            }
420
 
421
            if (EMCORE_SUCCESS != emcore_errno_value)
422
            {
423
                nwrite = -emcore_errno_value;
424
                break;
425
            }
426
        }
427
 
428
        if (EMCORE_SUCCESS != res)
429
        {
430
            nwrite = -EIO;
431
        }
432
    }
433
    while(0);
434
 
435
    res = emcore_free(addr);
436
 
437
    if (EMCORE_SUCCESS != res)
438
    {
439
        return -EIO;
440
    }
441
 
442
    cache_remove(path);
443
 
444
    return nwrite;
445
}
446
 
770 user890104 447
int emcorefs_release(const char* path, struct fuse_file_info* fi)
448
{
449
    int res;
450
    uint32_t emcore_errno_value;
451
    (void)path;
452
 
453
    if (!fi->fh)
454
    {
455
        return -EIO;
456
    }
457
 
458
    res = emcore_file_close(fi->fh);
459
 
460
    if (EMCORE_ERROR_IO == res)
461
    {
462
        res = emcore_errno(&emcore_errno_value);
463
 
464
        if (EMCORE_SUCCESS != res)
465
        {
466
            return -EIO;
467
        }
468
 
469
        if (EMCORE_SUCCESS != emcore_errno_value)
470
        {
471
            return -emcore_errno_value;
472
        }
473
    }
474
 
475
    if (EMCORE_SUCCESS != res)
476
    {
477
        return -EIO;
478
    }
479
 
480
    return 0;
481
}
782 user890104 482
 
483
int emcorefs_mkdir(const char* path, mode_t mode)
484
{
485
    (void)mode;
486
    int res;
487
    uint32_t emcore_errno_value;
488
 
489
    res = emcore_dir_create(path);
490
 
491
    if (EMCORE_ERROR_IO == res)
492
    {
493
        res = emcore_errno(&emcore_errno_value);
494
 
495
        if (EMCORE_SUCCESS != res)
496
        {
497
            return -EIO;
498
        }
499
 
500
        if (EMCORE_SUCCESS != emcore_errno_value)
501
        {
502
            return -emcore_errno_value;
503
        }
504
    }
505
 
506
    if (EMCORE_SUCCESS != res)
507
    {
508
        return -EIO;
509
    }
510
 
511
    return 0;
512
}
513
 
514
int emcorefs_rmdir(const char* path)
515
{
516
    int res;
517
    uint32_t emcore_errno_value;
518
 
519
    res = emcore_dir_remove(path);
520
 
521
    if (EMCORE_ERROR_IO == res)
522
    {
523
        res = emcore_errno(&emcore_errno_value);
524
 
525
        if (EMCORE_SUCCESS != res)
526
        {
527
            return -EIO;
528
        }
529
 
530
        if (EMCORE_SUCCESS != emcore_errno_value)
531
        {
532
            return -emcore_errno_value;
533
        }
534
    }
535
 
536
    if (EMCORE_SUCCESS != res)
537
    {
538
        return -EIO;
539
    }
540
 
541
    cache_remove(path);
542
 
543
    return 0;
544
}
545
 
546
int emcorefs_create(const char* path, mode_t mode, struct fuse_file_info* fi)
547
{
548
    (void)mode;
549
    return emcorefs_open(path, fi);
550
}
551
 
552
int emcorefs_mknod(const char* path, mode_t mode, dev_t dev)
553
{
554
    (void)dev;
555
    int res;
556
    struct fuse_file_info fi;
557
 
558
    fi.flags = O_WRONLY | O_CREAT | O_TRUNC;
559
 
560
    res = emcorefs_create(path, mode, &fi);
561
 
562
    if (0 != res) {
563
        return res;
564
    }
565
 
566
    return emcorefs_release(path, &fi);
567
}
568
 
569
int emcorefs_unlink(const char* path)
570
{
571
    int res;
572
    uint32_t emcore_errno_value;
573
 
574
    res = emcore_file_unlink(path);
575
 
576
    if (EMCORE_ERROR_IO == res)
577
    {
578
        res = emcore_errno(&emcore_errno_value);
579
 
580
        if (EMCORE_SUCCESS != res)
581
        {
582
            return -EIO;
583
        }
584
 
585
        if (EMCORE_SUCCESS != emcore_errno_value)
586
        {
587
            return -emcore_errno_value;
588
        }
589
    }
590
 
591
    if (EMCORE_SUCCESS != res)
592
    {
593
        return -EIO;
594
    }
595
 
596
    cache_remove(path);
597
 
598
    return 0;
784 user890104 599
}
600
 
601
int emcorefs_rename(const char* path, const char* new_path)
602
{
603
    int res;
604
    uint32_t emcore_errno_value;
605
 
606
    res = emcore_file_rename(path, new_path);
607
 
608
    if (EMCORE_ERROR_IO == res)
609
    {
610
        res = emcore_errno(&emcore_errno_value);
611
 
612
        if (EMCORE_SUCCESS != res)
613
        {
614
            return -EIO;
615
        }
616
 
617
        if (EMCORE_SUCCESS != emcore_errno_value)
618
        {
619
            return -emcore_errno_value;
620
        }
621
    }
622
 
623
    if (EMCORE_SUCCESS != res)
624
    {
625
        return -EIO;
626
    }
627
 
628
    cache_remove(path);
629
 
630
    return 0;
631
}
632
 
633
int emcorefs_truncate(const char* path, off_t size)
634
{
635
    int res;
636
    struct fuse_file_info fi;
637
 
638
    res = emcorefs_open(path, &fi);
639
 
640
    if (0 != res) {
641
        return res;
642
    }
643
 
644
    res = emcorefs_ftruncate(path, size, &fi);
645
 
646
    if (0 != res) {
647
        return res;
648
    }
649
 
650
    return emcorefs_release(path, &fi);
651
}
652
 
653
int emcorefs_ftruncate(const char* path, off_t size, struct fuse_file_info* fi)
654
{
655
    int res;
656
    uint32_t emcore_errno_value;
657
    (void)path;
658
 
659
    if (!fi->fh)
660
    {
661
        return -EIO;
662
    }
663
 
664
    res = emcore_file_truncate(fi->fh, size);
665
 
666
    if (EMCORE_ERROR_IO == res)
667
    {
668
        res = emcore_errno(&emcore_errno_value);
669
 
670
        if (EMCORE_SUCCESS != res)
671
        {
672
            return -EIO;
673
        }
674
 
675
        if (EMCORE_SUCCESS != emcore_errno_value)
676
        {
677
            return -emcore_errno_value;
678
        }
679
    }
680
 
681
    if (EMCORE_SUCCESS != res)
682
    {
683
        return -EIO;
684
    }
685
 
686
    cache_remove(path);
687
 
688
    return 0;
689
}
690