Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
898 user890104 3
//    Copyright 2013 user890104
770 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
#include "global.h"
24
 
25
#include "fuse.h"
26
#include "util.h"
27
#include "cache.h"
28
#include "emcore.h"
29
 
898 user890104 30
int32_t emcorefs_init(void) {
31
    int32_t res;
782 user890104 32
    uint32_t count;
33
 
34
    res = emcore_file_close_all(&count);
35
 
898 user890104 36
    if (res != EMCORE_SUCCESS) {
782 user890104 37
        return res;
38
    }
39
 
40
    res = emcore_dir_close_all(&count);
41
 
42
    return res;
43
}
44
 
898 user890104 45
int32_t emcorefs_getattr(const char *path, struct stat *stbuf) {
46
    int32_t res = 0;
770 user890104 47
    struct emcore_dir_entry *entry = NULL, curr_entry;
48
    uint32_t dir_handle;
49
    char *parent, *filename;
50
 
51
    memset(stbuf, 0, sizeof(*stbuf));
52
 
782 user890104 53
#ifdef DEBUG2
898 user890104 54
    if (strcmp(path, "/__cache_dump") == 0) {
782 user890104 55
        cache_dump();
56
    }
57
#endif
770 user890104 58
    entry = cache_get(path);
59
 
898 user890104 60
    if (!entry) {
770 user890104 61
        parent = strdup(path);
62
        dirname(parent);
898 user890104 63
        filename = basename((char *) path);
770 user890104 64
 
65
        res = emcore_dir_open(&dir_handle, parent);
66
 
898 user890104 67
        if (res == EMCORE_SUCCESS) {
68
            while (1) {
770 user890104 69
                res = emcore_dir_read(&curr_entry, dir_handle);
70
 
898 user890104 71
                if (res == EMCORE_ERROR_NO_MORE_ENTRIES) {
770 user890104 72
                    break;
73
                }
74
 
898 user890104 75
                if (res != EMCORE_SUCCESS) {
770 user890104 76
                    break;
77
                }
78
 
79
                cache_insert(parent, &curr_entry);
80
 
898 user890104 81
                if (strcmp(filename, curr_entry.name) == 0) {
770 user890104 82
                    entry = malloc(sizeof(*entry));
83
 
84
                    memcpy(entry, &curr_entry, sizeof(curr_entry));
85
 
86
                    break;
87
                }
88
            };
89
 
90
            emcore_dir_close(dir_handle);
91
        }
92
 
93
        free(parent);
94
    }
95
 
898 user890104 96
    if (!entry) {
97
        if (res == EMCORE_ERROR_NO_MORE_ENTRIES) {
770 user890104 98
            return -ENOENT;
99
        }
100
 
101
        return -EIO;
102
    }
898 user890104 103
    else {
770 user890104 104
        stbuf->st_uid = getuid();
105
        stbuf->st_gid = getgid();
106
        stbuf->st_mtime = fat_time_to_unix_ts(entry->wrttime, entry->wrtdate);
107
 
898 user890104 108
        if (entry->attributes & 0x10) {
770 user890104 109
            stbuf->st_mode = S_IFDIR | 0755;
110
            stbuf->st_nlink = 2;
111
            stbuf->st_size = 0x1000;
112
        }
898 user890104 113
        else {
770 user890104 114
            stbuf->st_mode = S_IFREG | 0644;
115
            stbuf->st_nlink = 1;
116
            stbuf->st_size = entry->size;
117
        }
118
    }
119
 
120
    return 0;
121
}
122
 
898 user890104 123
int32_t emcorefs_opendir(const char *path, struct fuse_file_info *fi) {
124
    int32_t res;
770 user890104 125
    uint32_t handle;
126
 
127
    res = emcore_dir_open(&handle, path);
128
 
898 user890104 129
    if (res != EMCORE_SUCCESS) {
770 user890104 130
        return -EIO;
131
    }
132
 
133
    fi->fh = handle;
134
 
135
    return 0;
136
}
137
 
898 user890104 138
int32_t emcorefs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
139
    int32_t res;
770 user890104 140
    struct emcore_dir_entry entry;
141
    (void) offset;
142
    (void) fi;
143
 
898 user890104 144
    if (strcmp(path, "/") == 0) {
770 user890104 145
        filler(buf, ".", NULL, 0);
146
        filler(buf, "..", NULL, 0);
147
    }
148
 
898 user890104 149
    while (1) {
770 user890104 150
        res = emcore_dir_read(&entry, fi->fh);
151
 
898 user890104 152
        if (res == EMCORE_ERROR_NO_MORE_ENTRIES) {
770 user890104 153
            break;
154
        }
155
 
898 user890104 156
        if (res != EMCORE_SUCCESS) {
770 user890104 157
            return -EIO;
158
        }
159
 
160
        cache_insert(path, &entry);
161
 
162
        filler(buf, entry.name, NULL, 0);
163
    }
164
 
165
    return 0;
166
}
167
 
898 user890104 168
int32_t emcorefs_releasedir(const char *path, struct fuse_file_info *fi) {
169
    int32_t res;
770 user890104 170
    uint32_t emcore_errno_value;
171
    (void)path;
172
 
173
    res = emcore_dir_close(fi->fh);
174
 
898 user890104 175
    if (res == EMCORE_ERROR_IO) {
770 user890104 176
        res = emcore_errno(&emcore_errno_value);
177
 
898 user890104 178
        if (res != EMCORE_SUCCESS) {
770 user890104 179
            return -EIO;
180
        }
181
 
898 user890104 182
        if (emcore_errno_value == EMCORE_SUCCESS) {
770 user890104 183
            return -emcore_errno_value;
184
        }
185
    }
186
 
898 user890104 187
    if (res != EMCORE_SUCCESS) {
770 user890104 188
        return -EIO;
189
    }
190
 
191
    return 0;
192
}
193
 
898 user890104 194
int32_t emcorefs_open(const char *path, struct fuse_file_info *fi) {
195
    int32_t res;
770 user890104 196
    uint32_t handle, emcore_errno_value;
782 user890104 197
 
198
#ifdef DEBUG
199
    fprintf(stderr, "FILE OPEN: [%s], 0x%08x\n", path, fi->flags);
200
#endif
201
 
770 user890104 202
    res = emcore_file_open(&handle, path, fi->flags);
203
 
898 user890104 204
    if (res == EMCORE_ERROR_IO) {
770 user890104 205
        res = emcore_errno(&emcore_errno_value);
206
 
898 user890104 207
        if (res != EMCORE_SUCCESS) {
770 user890104 208
            return -EIO;
209
        }
210
 
898 user890104 211
        if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 212
            return -emcore_errno_value;
213
        }
214
    }
215
 
898 user890104 216
    if (res != EMCORE_SUCCESS) {
770 user890104 217
        return -EIO;
218
    }
219
 
220
    fi->fh = handle;
221
 
222
    return 0;
223
}
224
 
898 user890104 225
int32_t emcorefs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
785 user890104 226
#ifdef DEBUG2
770 user890104 227
    fprintf(stderr, "FUSE_READ: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 228
#else
229
    (void)path;
230
#endif
898 user890104 231
    int32_t res;
770 user890104 232
    uint32_t emcore_errno_value, addr, nread = size;
233
 
898 user890104 234
    if (!fi->fh) {
770 user890104 235
        return -EIO;
236
    }
237
 
238
    res = emcore_malloc(&addr, size);
239
 
898 user890104 240
    if (res != EMCORE_SUCCESS) {
770 user890104 241
        return -EIO;
242
    }
243
 
244
    do {
245
        if (offset) {
246
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
247
 
898 user890104 248
            if (res == EMCORE_ERROR_IO) {
770 user890104 249
                res = emcore_errno(&emcore_errno_value);
250
 
898 user890104 251
                if (res != EMCORE_SUCCESS) {
770 user890104 252
                    nread = -EIO;
253
                    break;
254
                }
255
 
898 user890104 256
                if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 257
                    nread = -emcore_errno_value;
258
                    break;
259
                }
260
            }
261
 
898 user890104 262
            if (res != EMCORE_SUCCESS) {
770 user890104 263
                nread = -EIO;
264
                break;
265
            }
266
        }
267
 
268
        res = emcore_file_read(&nread, fi->fh, addr, size);
269
 
898 user890104 270
        if (res == EMCORE_ERROR_IO) {
770 user890104 271
            res = emcore_errno(&emcore_errno_value);
272
 
898 user890104 273
            if (res != EMCORE_SUCCESS) {
770 user890104 274
                nread = -EIO;
275
                break;
276
            }
277
 
898 user890104 278
            if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 279
                nread = -emcore_errno_value;
280
                break;
281
            }
282
        }
283
 
898 user890104 284
        if (res != EMCORE_SUCCESS) {
770 user890104 285
            nread = -EIO;
286
            break;
287
        }
288
 
289
        res = emcore_read(buf, addr, nread);
290
 
898 user890104 291
        if (res != EMCORE_SUCCESS) {
770 user890104 292
            nread = -EIO;
293
        }
294
    }
295
    while(0);
296
 
297
    res = emcore_free(addr);
298
 
898 user890104 299
    if (res != EMCORE_SUCCESS) {
770 user890104 300
        return -EIO;
301
    }
302
 
303
    return nread;
304
}
305
 
898 user890104 306
int32_t emcorefs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
785 user890104 307
#ifdef DEBUG2
784 user890104 308
    fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 309
#else
310
    (void)path;
311
#endif
898 user890104 312
    int32_t res;
784 user890104 313
    uint32_t emcore_errno_value, addr, nwrite = size;
314
 
898 user890104 315
    if (!fi->fh) {
784 user890104 316
        return -EIO;
317
    }
318
 
319
    res = emcore_malloc(&addr, size);
320
 
898 user890104 321
    if (res != EMCORE_SUCCESS) {
784 user890104 322
        return -EIO;
323
    }
324
 
325
    do {
326
        if (offset) {
327
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
328
 
898 user890104 329
            if (res == EMCORE_ERROR_IO) {
784 user890104 330
                res = emcore_errno(&emcore_errno_value);
331
 
898 user890104 332
                if (res != EMCORE_SUCCESS) {
784 user890104 333
                    nwrite = -EIO;
334
                    break;
335
                }
336
 
898 user890104 337
                if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 338
                    nwrite = -emcore_errno_value;
339
                    break;
340
                }
341
            }
342
 
898 user890104 343
            if (res != EMCORE_SUCCESS) {
784 user890104 344
                nwrite = -EIO;
345
                break;
346
            }
347
        }
348
 
349
        res = emcore_write(buf, addr, nwrite);
350
 
898 user890104 351
        if (res != EMCORE_SUCCESS) {
784 user890104 352
            nwrite = -EIO;
353
            break;
354
        }
355
 
356
        res = emcore_file_write(&nwrite, fi->fh, addr, size);
357
 
898 user890104 358
        if (res == EMCORE_ERROR_IO) {
784 user890104 359
            res = emcore_errno(&emcore_errno_value);
360
 
898 user890104 361
            if (res != EMCORE_SUCCESS) {
784 user890104 362
                nwrite = -EIO;
363
                break;
364
            }
365
 
898 user890104 366
            if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 367
                nwrite = -emcore_errno_value;
368
                break;
369
            }
370
        }
371
 
898 user890104 372
        if (res != EMCORE_SUCCESS) {
784 user890104 373
            nwrite = -EIO;
374
        }
375
    }
376
    while(0);
377
 
378
    res = emcore_free(addr);
379
 
898 user890104 380
    if (res != EMCORE_SUCCESS) {
784 user890104 381
        return -EIO;
382
    }
383
 
384
    cache_remove(path);
385
 
386
    return nwrite;
387
}
388
 
898 user890104 389
int32_t emcorefs_release(const char *path, struct fuse_file_info *fi) {
390
    int32_t res;
770 user890104 391
    uint32_t emcore_errno_value;
392
    (void)path;
393
 
898 user890104 394
    if (!fi->fh) {
770 user890104 395
        return -EIO;
396
    }
397
 
398
    res = emcore_file_close(fi->fh);
399
 
898 user890104 400
    if (EMCORE_ERROR_IO == res) {
770 user890104 401
        res = emcore_errno(&emcore_errno_value);
402
 
898 user890104 403
        if (res != EMCORE_SUCCESS) {
770 user890104 404
            return -EIO;
405
        }
406
 
898 user890104 407
        if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 408
            return -emcore_errno_value;
409
        }
410
    }
411
 
898 user890104 412
    if (res != EMCORE_SUCCESS) {
770 user890104 413
        return -EIO;
414
    }
415
 
416
    return 0;
417
}
782 user890104 418
 
898 user890104 419
int32_t emcorefs_mkdir(const char *path, mode_t mode) {
782 user890104 420
    (void)mode;
898 user890104 421
    int32_t res;
782 user890104 422
    uint32_t emcore_errno_value;
423
 
424
    res = emcore_dir_create(path);
425
 
898 user890104 426
    if (res == EMCORE_ERROR_IO) {
782 user890104 427
        res = emcore_errno(&emcore_errno_value);
428
 
898 user890104 429
        if (res != EMCORE_SUCCESS) {
782 user890104 430
            return -EIO;
431
        }
432
 
898 user890104 433
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 434
            return -emcore_errno_value;
435
        }
436
    }
437
 
898 user890104 438
    if (res != EMCORE_SUCCESS) {
782 user890104 439
        return -EIO;
440
    }
441
 
442
    return 0;
443
}
444
 
898 user890104 445
int32_t emcorefs_rmdir(const char *path) {
446
    int32_t res;
782 user890104 447
    uint32_t emcore_errno_value;
448
 
449
    res = emcore_dir_remove(path);
450
 
898 user890104 451
    if (res == EMCORE_ERROR_IO) {
782 user890104 452
        res = emcore_errno(&emcore_errno_value);
453
 
898 user890104 454
        if (res != EMCORE_SUCCESS) {
782 user890104 455
            return -EIO;
456
        }
457
 
898 user890104 458
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 459
            return -emcore_errno_value;
460
        }
461
    }
462
 
898 user890104 463
    if (res != EMCORE_SUCCESS) {
782 user890104 464
        return -EIO;
465
    }
466
 
467
    cache_remove(path);
468
 
469
    return 0;
470
}
471
 
898 user890104 472
int32_t emcorefs_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
782 user890104 473
    (void)mode;
474
    return emcorefs_open(path, fi);
475
}
476
 
898 user890104 477
int32_t emcorefs_mknod(const char *path, mode_t mode, dev_t dev) {
782 user890104 478
    (void)dev;
898 user890104 479
    int32_t res;
782 user890104 480
    struct fuse_file_info fi;
481
 
482
    fi.flags = O_WRONLY | O_CREAT | O_TRUNC;
483
 
484
    res = emcorefs_create(path, mode, &fi);
485
 
898 user890104 486
    if (res) {
782 user890104 487
        return res;
488
    }
489
 
490
    return emcorefs_release(path, &fi);
491
}
492
 
898 user890104 493
int32_t emcorefs_unlink(const char *path)
782 user890104 494
{
898 user890104 495
    int32_t res;
782 user890104 496
    uint32_t emcore_errno_value;
497
 
498
    res = emcore_file_unlink(path);
499
 
898 user890104 500
    if (res == EMCORE_ERROR_IO) {
782 user890104 501
        res = emcore_errno(&emcore_errno_value);
502
 
898 user890104 503
        if (res != EMCORE_SUCCESS) {
782 user890104 504
            return -EIO;
505
        }
506
 
898 user890104 507
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 508
            return -emcore_errno_value;
509
        }
510
    }
511
 
898 user890104 512
    if (res != EMCORE_SUCCESS) {
782 user890104 513
        return -EIO;
514
    }
515
 
516
    cache_remove(path);
517
 
518
    return 0;
784 user890104 519
}
520
 
898 user890104 521
int32_t emcorefs_rename(const char *path, const char *new_path) {
522
    int32_t res;
784 user890104 523
    uint32_t emcore_errno_value;
524
 
525
    res = emcore_file_rename(path, new_path);
898 user890104 526
 
527
    if (res == EMCORE_ERROR_IO) {
784 user890104 528
        res = emcore_errno(&emcore_errno_value);
529
 
898 user890104 530
        if (res != EMCORE_SUCCESS) {
784 user890104 531
            return -EIO;
532
        }
533
 
898 user890104 534
        if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 535
            return -emcore_errno_value;
536
        }
537
    }
538
 
898 user890104 539
    if (res != EMCORE_SUCCESS) {
784 user890104 540
        return -EIO;
541
    }
542
 
543
    cache_remove(path);
544
 
545
    return 0;
546
}
547
 
898 user890104 548
int32_t emcorefs_truncate(const char *path, off_t size) {
549
    int32_t res;
784 user890104 550
    struct fuse_file_info fi;
551
 
552
    res = emcorefs_open(path, &fi);
553
 
898 user890104 554
    if (res) {
784 user890104 555
        return res;
556
    }
557
 
558
    res = emcorefs_ftruncate(path, size, &fi);
559
 
898 user890104 560
    if (res) {
784 user890104 561
        return res;
562
    }
563
 
564
    return emcorefs_release(path, &fi);
565
}
566
 
898 user890104 567
int32_t emcorefs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) {
568
    int32_t res;
784 user890104 569
    uint32_t emcore_errno_value;
570
    (void)path;
571
 
898 user890104 572
    if (!fi->fh) {
784 user890104 573
        return -EIO;
574
    }
575
 
576
    res = emcore_file_truncate(fi->fh, size);
577
 
898 user890104 578
    if (res == EMCORE_ERROR_IO) {
784 user890104 579
        res = emcore_errno(&emcore_errno_value);
580
 
898 user890104 581
        if (res != EMCORE_SUCCESS) {
784 user890104 582
            return -EIO;
583
        }
584
 
898 user890104 585
        if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 586
            return -emcore_errno_value;
587
        }
588
    }
589
 
898 user890104 590
    if (res != EMCORE_SUCCESS) {
784 user890104 591
        return -EIO;
592
    }
593
 
594
    cache_remove(path);
595
 
596
    return 0;
597
}