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
//
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
 
899 user890104 123
int32_t emcorefs_utimens(const char *path, const struct timespec tv[2]) {
124
    (void)path;
125
    (void)tv;
126
 
127
    return 0;
128
}
129
 
898 user890104 130
int32_t emcorefs_opendir(const char *path, struct fuse_file_info *fi) {
131
    int32_t res;
770 user890104 132
    uint32_t handle;
133
 
134
    res = emcore_dir_open(&handle, path);
135
 
898 user890104 136
    if (res != EMCORE_SUCCESS) {
770 user890104 137
        return -EIO;
138
    }
139
 
140
    fi->fh = handle;
141
 
142
    return 0;
143
}
144
 
898 user890104 145
int32_t emcorefs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
146
    int32_t res;
770 user890104 147
    struct emcore_dir_entry entry;
148
    (void) offset;
149
    (void) fi;
150
 
898 user890104 151
    if (strcmp(path, "/") == 0) {
770 user890104 152
        filler(buf, ".", NULL, 0);
153
        filler(buf, "..", NULL, 0);
154
    }
155
 
898 user890104 156
    while (1) {
770 user890104 157
        res = emcore_dir_read(&entry, fi->fh);
158
 
898 user890104 159
        if (res == EMCORE_ERROR_NO_MORE_ENTRIES) {
770 user890104 160
            break;
161
        }
162
 
898 user890104 163
        if (res != EMCORE_SUCCESS) {
770 user890104 164
            return -EIO;
165
        }
166
 
167
        cache_insert(path, &entry);
168
 
169
        filler(buf, entry.name, NULL, 0);
170
    }
171
 
172
    return 0;
173
}
174
 
898 user890104 175
int32_t emcorefs_releasedir(const char *path, struct fuse_file_info *fi) {
176
    int32_t res;
770 user890104 177
    uint32_t emcore_errno_value;
178
    (void)path;
179
 
180
    res = emcore_dir_close(fi->fh);
181
 
898 user890104 182
    if (res == EMCORE_ERROR_IO) {
770 user890104 183
        res = emcore_errno(&emcore_errno_value);
184
 
898 user890104 185
        if (res != EMCORE_SUCCESS) {
770 user890104 186
            return -EIO;
187
        }
188
 
898 user890104 189
        if (emcore_errno_value == EMCORE_SUCCESS) {
770 user890104 190
            return -emcore_errno_value;
191
        }
192
    }
193
 
898 user890104 194
    if (res != EMCORE_SUCCESS) {
770 user890104 195
        return -EIO;
196
    }
197
 
198
    return 0;
199
}
200
 
898 user890104 201
int32_t emcorefs_open(const char *path, struct fuse_file_info *fi) {
202
    int32_t res;
770 user890104 203
    uint32_t handle, emcore_errno_value;
782 user890104 204
 
205
#ifdef DEBUG
206
    fprintf(stderr, "FILE OPEN: [%s], 0x%08x\n", path, fi->flags);
207
#endif
208
 
770 user890104 209
    res = emcore_file_open(&handle, path, fi->flags);
210
 
898 user890104 211
    if (res == EMCORE_ERROR_IO) {
770 user890104 212
        res = emcore_errno(&emcore_errno_value);
213
 
898 user890104 214
        if (res != EMCORE_SUCCESS) {
770 user890104 215
            return -EIO;
216
        }
217
 
898 user890104 218
        if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 219
            return -emcore_errno_value;
220
        }
221
    }
222
 
898 user890104 223
    if (res != EMCORE_SUCCESS) {
770 user890104 224
        return -EIO;
225
    }
226
 
227
    fi->fh = handle;
228
 
229
    return 0;
230
}
231
 
898 user890104 232
int32_t emcorefs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
785 user890104 233
#ifdef DEBUG2
770 user890104 234
    fprintf(stderr, "FUSE_READ: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 235
#else
236
    (void)path;
237
#endif
898 user890104 238
    int32_t res;
770 user890104 239
    uint32_t emcore_errno_value, addr, nread = size;
240
 
898 user890104 241
    if (!fi->fh) {
770 user890104 242
        return -EIO;
243
    }
244
 
245
    res = emcore_malloc(&addr, size);
246
 
898 user890104 247
    if (res != EMCORE_SUCCESS) {
770 user890104 248
        return -EIO;
249
    }
250
 
251
    do {
252
        if (offset) {
253
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
254
 
898 user890104 255
            if (res == EMCORE_ERROR_IO) {
770 user890104 256
                res = emcore_errno(&emcore_errno_value);
257
 
898 user890104 258
                if (res != EMCORE_SUCCESS) {
770 user890104 259
                    nread = -EIO;
260
                    break;
261
                }
262
 
898 user890104 263
                if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 264
                    nread = -emcore_errno_value;
265
                    break;
266
                }
267
            }
268
 
898 user890104 269
            if (res != EMCORE_SUCCESS) {
770 user890104 270
                nread = -EIO;
271
                break;
272
            }
273
        }
274
 
275
        res = emcore_file_read(&nread, fi->fh, addr, size);
276
 
898 user890104 277
        if (res == EMCORE_ERROR_IO) {
770 user890104 278
            res = emcore_errno(&emcore_errno_value);
279
 
898 user890104 280
            if (res != EMCORE_SUCCESS) {
770 user890104 281
                nread = -EIO;
282
                break;
283
            }
284
 
898 user890104 285
            if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 286
                nread = -emcore_errno_value;
287
                break;
288
            }
289
        }
290
 
898 user890104 291
        if (res != EMCORE_SUCCESS) {
770 user890104 292
            nread = -EIO;
293
            break;
294
        }
295
 
296
        res = emcore_read(buf, addr, nread);
297
 
898 user890104 298
        if (res != EMCORE_SUCCESS) {
770 user890104 299
            nread = -EIO;
300
        }
301
    }
302
    while(0);
303
 
304
    res = emcore_free(addr);
305
 
898 user890104 306
    if (res != EMCORE_SUCCESS) {
770 user890104 307
        return -EIO;
308
    }
309
 
310
    return nread;
311
}
312
 
898 user890104 313
int32_t emcorefs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
785 user890104 314
#ifdef DEBUG2
784 user890104 315
    fprintf(stderr, "FUSE_WRITE: path=[%s] size=[%d] offset=[%jd] fi->flags=[%d]\n", path, size, offset, fi->flags);
785 user890104 316
#else
317
    (void)path;
318
#endif
898 user890104 319
    int32_t res;
784 user890104 320
    uint32_t emcore_errno_value, addr, nwrite = size;
321
 
898 user890104 322
    if (!fi->fh) {
784 user890104 323
        return -EIO;
324
    }
325
 
326
    res = emcore_malloc(&addr, size);
327
 
898 user890104 328
    if (res != EMCORE_SUCCESS) {
784 user890104 329
        return -EIO;
330
    }
331
 
332
    do {
333
        if (offset) {
334
            res = emcore_file_seek(fi->fh, offset, SEEK_SET);
335
 
898 user890104 336
            if (res == EMCORE_ERROR_IO) {
784 user890104 337
                res = emcore_errno(&emcore_errno_value);
338
 
898 user890104 339
                if (res != EMCORE_SUCCESS) {
784 user890104 340
                    nwrite = -EIO;
341
                    break;
342
                }
343
 
898 user890104 344
                if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 345
                    nwrite = -emcore_errno_value;
346
                    break;
347
                }
348
            }
349
 
898 user890104 350
            if (res != EMCORE_SUCCESS) {
784 user890104 351
                nwrite = -EIO;
352
                break;
353
            }
354
        }
355
 
356
        res = emcore_write(buf, addr, nwrite);
357
 
898 user890104 358
        if (res != EMCORE_SUCCESS) {
784 user890104 359
            nwrite = -EIO;
360
            break;
361
        }
362
 
363
        res = emcore_file_write(&nwrite, fi->fh, addr, size);
364
 
898 user890104 365
        if (res == EMCORE_ERROR_IO) {
784 user890104 366
            res = emcore_errno(&emcore_errno_value);
367
 
898 user890104 368
            if (res != EMCORE_SUCCESS) {
784 user890104 369
                nwrite = -EIO;
370
                break;
371
            }
372
 
898 user890104 373
            if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 374
                nwrite = -emcore_errno_value;
375
                break;
376
            }
377
        }
378
 
898 user890104 379
        if (res != EMCORE_SUCCESS) {
784 user890104 380
            nwrite = -EIO;
381
        }
382
    }
383
    while(0);
384
 
385
    res = emcore_free(addr);
386
 
898 user890104 387
    if (res != EMCORE_SUCCESS) {
784 user890104 388
        return -EIO;
389
    }
390
 
391
    cache_remove(path);
392
 
393
    return nwrite;
394
}
395
 
898 user890104 396
int32_t emcorefs_release(const char *path, struct fuse_file_info *fi) {
397
    int32_t res;
770 user890104 398
    uint32_t emcore_errno_value;
399
    (void)path;
400
 
898 user890104 401
    if (!fi->fh) {
770 user890104 402
        return -EIO;
403
    }
404
 
405
    res = emcore_file_close(fi->fh);
406
 
898 user890104 407
    if (EMCORE_ERROR_IO == res) {
770 user890104 408
        res = emcore_errno(&emcore_errno_value);
409
 
898 user890104 410
        if (res != EMCORE_SUCCESS) {
770 user890104 411
            return -EIO;
412
        }
413
 
898 user890104 414
        if (emcore_errno_value != EMCORE_SUCCESS) {
770 user890104 415
            return -emcore_errno_value;
416
        }
417
    }
418
 
898 user890104 419
    if (res != EMCORE_SUCCESS) {
770 user890104 420
        return -EIO;
421
    }
422
 
423
    return 0;
424
}
782 user890104 425
 
898 user890104 426
int32_t emcorefs_mkdir(const char *path, mode_t mode) {
782 user890104 427
    (void)mode;
898 user890104 428
    int32_t res;
782 user890104 429
    uint32_t emcore_errno_value;
430
 
431
    res = emcore_dir_create(path);
432
 
898 user890104 433
    if (res == EMCORE_ERROR_IO) {
782 user890104 434
        res = emcore_errno(&emcore_errno_value);
435
 
898 user890104 436
        if (res != EMCORE_SUCCESS) {
782 user890104 437
            return -EIO;
438
        }
439
 
898 user890104 440
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 441
            return -emcore_errno_value;
442
        }
443
    }
444
 
898 user890104 445
    if (res != EMCORE_SUCCESS) {
782 user890104 446
        return -EIO;
447
    }
448
 
449
    return 0;
450
}
451
 
898 user890104 452
int32_t emcorefs_rmdir(const char *path) {
453
    int32_t res;
782 user890104 454
    uint32_t emcore_errno_value;
455
 
456
    res = emcore_dir_remove(path);
457
 
898 user890104 458
    if (res == EMCORE_ERROR_IO) {
782 user890104 459
        res = emcore_errno(&emcore_errno_value);
460
 
898 user890104 461
        if (res != EMCORE_SUCCESS) {
782 user890104 462
            return -EIO;
463
        }
464
 
898 user890104 465
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 466
            return -emcore_errno_value;
467
        }
468
    }
469
 
898 user890104 470
    if (res != EMCORE_SUCCESS) {
782 user890104 471
        return -EIO;
472
    }
473
 
474
    cache_remove(path);
475
 
476
    return 0;
477
}
478
 
898 user890104 479
int32_t emcorefs_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
782 user890104 480
    (void)mode;
481
    return emcorefs_open(path, fi);
482
}
483
 
898 user890104 484
int32_t emcorefs_mknod(const char *path, mode_t mode, dev_t dev) {
782 user890104 485
    (void)dev;
898 user890104 486
    int32_t res;
782 user890104 487
    struct fuse_file_info fi;
488
 
489
    fi.flags = O_WRONLY | O_CREAT | O_TRUNC;
490
 
491
    res = emcorefs_create(path, mode, &fi);
492
 
898 user890104 493
    if (res) {
782 user890104 494
        return res;
495
    }
496
 
497
    return emcorefs_release(path, &fi);
498
}
499
 
898 user890104 500
int32_t emcorefs_unlink(const char *path)
782 user890104 501
{
898 user890104 502
    int32_t res;
782 user890104 503
    uint32_t emcore_errno_value;
504
 
505
    res = emcore_file_unlink(path);
506
 
898 user890104 507
    if (res == EMCORE_ERROR_IO) {
782 user890104 508
        res = emcore_errno(&emcore_errno_value);
509
 
898 user890104 510
        if (res != EMCORE_SUCCESS) {
782 user890104 511
            return -EIO;
512
        }
513
 
898 user890104 514
        if (emcore_errno_value != EMCORE_SUCCESS) {
782 user890104 515
            return -emcore_errno_value;
516
        }
517
    }
518
 
898 user890104 519
    if (res != EMCORE_SUCCESS) {
782 user890104 520
        return -EIO;
521
    }
522
 
523
    cache_remove(path);
524
 
525
    return 0;
784 user890104 526
}
527
 
898 user890104 528
int32_t emcorefs_rename(const char *path, const char *new_path) {
529
    int32_t res;
784 user890104 530
    uint32_t emcore_errno_value;
531
 
532
    res = emcore_file_rename(path, new_path);
898 user890104 533
 
534
    if (res == EMCORE_ERROR_IO) {
784 user890104 535
        res = emcore_errno(&emcore_errno_value);
536
 
898 user890104 537
        if (res != EMCORE_SUCCESS) {
784 user890104 538
            return -EIO;
539
        }
540
 
898 user890104 541
        if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 542
            return -emcore_errno_value;
543
        }
544
    }
545
 
898 user890104 546
    if (res != EMCORE_SUCCESS) {
784 user890104 547
        return -EIO;
548
    }
549
 
550
    cache_remove(path);
551
 
552
    return 0;
553
}
554
 
898 user890104 555
int32_t emcorefs_truncate(const char *path, off_t size) {
556
    int32_t res;
784 user890104 557
    struct fuse_file_info fi;
558
 
559
    res = emcorefs_open(path, &fi);
560
 
898 user890104 561
    if (res) {
784 user890104 562
        return res;
563
    }
564
 
565
    res = emcorefs_ftruncate(path, size, &fi);
566
 
898 user890104 567
    if (res) {
784 user890104 568
        return res;
569
    }
570
 
571
    return emcorefs_release(path, &fi);
572
}
573
 
898 user890104 574
int32_t emcorefs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) {
575
    int32_t res;
784 user890104 576
    uint32_t emcore_errno_value;
577
    (void)path;
578
 
898 user890104 579
    if (!fi->fh) {
784 user890104 580
        return -EIO;
581
    }
582
 
583
    res = emcore_file_truncate(fi->fh, size);
584
 
898 user890104 585
    if (res == EMCORE_ERROR_IO) {
784 user890104 586
        res = emcore_errno(&emcore_errno_value);
587
 
898 user890104 588
        if (res != EMCORE_SUCCESS) {
784 user890104 589
            return -EIO;
590
        }
591
 
898 user890104 592
        if (emcore_errno_value != EMCORE_SUCCESS) {
784 user890104 593
            return -emcore_errno_value;
594
        }
595
    }
596
 
898 user890104 597
    if (res != EMCORE_SUCCESS) {
784 user890104 598
        return -EIO;
599
    }
600
 
601
    cache_remove(path);
602
 
603
    return 0;
604
}