-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
Copy pathfs.c
91 lines (84 loc) · 2.33 KB
/
fs.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "fs.h"
#include "printf.h"
#include "str.h"
struct mg_fd *mg_fs_open(struct mg_fs *fs, const char *path, int flags) {
struct mg_fd *fd = (struct mg_fd *) calloc(1, sizeof(*fd));
if (fd != NULL) {
fd->fd = fs->op(path, flags);
fd->fs = fs;
if (fd->fd == NULL) {
free(fd);
fd = NULL;
}
}
return fd;
}
void mg_fs_close(struct mg_fd *fd) {
if (fd != NULL) {
fd->fs->cl(fd->fd);
free(fd);
}
}
struct mg_str mg_file_read(struct mg_fs *fs, const char *path) {
struct mg_str result = {NULL, 0};
void *fp;
fs->st(path, &result.len, NULL);
if ((fp = fs->op(path, MG_FS_READ)) != NULL) {
result.buf = (char *) calloc(1, result.len + 1);
if (result.buf != NULL &&
fs->rd(fp, (void *) result.buf, result.len) != result.len) {
free((void *) result.buf);
result.buf = NULL;
}
fs->cl(fp);
}
if (result.buf == NULL) result.len = 0;
return result;
}
bool mg_file_write(struct mg_fs *fs, const char *path, const void *buf,
size_t len) {
bool result = false;
struct mg_fd *fd;
char tmp[MG_PATH_MAX];
mg_snprintf(tmp, sizeof(tmp), "%s..%d", path, rand());
if ((fd = mg_fs_open(fs, tmp, MG_FS_WRITE)) != NULL) {
result = fs->wr(fd->fd, buf, len) == len;
mg_fs_close(fd);
if (result) {
fs->rm(path);
fs->mv(tmp, path);
} else {
fs->rm(tmp);
}
}
return result;
}
bool mg_file_printf(struct mg_fs *fs, const char *path, const char *fmt, ...) {
va_list ap;
char *data;
bool result = false;
va_start(ap, fmt);
data = mg_vmprintf(fmt, &ap);
va_end(ap);
result = mg_file_write(fs, path, data, strlen(data));
free(data);
return result;
}
// This helper function allows to scan a filesystem in a sequential way,
// without using callback function:
// char buf[100] = "";
// while (mg_fs_ls(&mg_fs_posix, "./", buf, sizeof(buf))) {
// ...
static void mg_fs_ls_fn(const char *filename, void *param) {
struct mg_str *s = (struct mg_str *) param;
if (s->buf[0] == '\0') {
mg_snprintf((char *) s->buf, s->len, "%s", filename);
} else if (strcmp(s->buf, filename) == 0) {
((char *) s->buf)[0] = '\0'; // Fetch next file
}
}
bool mg_fs_ls(struct mg_fs *fs, const char *path, char *buf, size_t len) {
struct mg_str s = {buf, len};
fs->ls(path, mg_fs_ls_fn, &s);
return buf[0] != '\0';
}