Mercurial > molko
annotate src/libmlk-core/core/vfs-zip.c @ 378:460c78706989
misc: update copyright years
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 02 Jan 2022 10:22:48 +0100 |
parents | 68287c7bcdb5 |
children | d74f53299252 |
rev | line source |
---|---|
335
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * vfs-zip.c -- VFS subsystem for zip archives |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
378
460c78706989
misc: update copyright years
David Demelier <markand@malikania.fr>
parents:
335
diff
changeset
|
4 * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> |
335
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
19 #include <assert.h> |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
20 #include <string.h> |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
21 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
22 #include <zip.h> |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
23 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
24 #include "error.h" |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
25 #include "vfs-zip.h" |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
26 #include "vfs.h" |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
27 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
28 static inline int |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
29 mkflags(const char *mode) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
30 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
31 /* TODO: this should check for mutual exclusions. */ |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
32 int flags = 0; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
33 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
34 for (; *mode; ++mode) { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
35 switch (*mode) { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
36 case 'w': |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
37 flags |= ZIP_CREATE; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
38 break; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
39 case 'x': |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
40 flags |= ZIP_EXCL; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 break; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
42 case '+': |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 flags |= ZIP_TRUNCATE; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 break; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 case 'r': |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 flags |= ZIP_RDONLY; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
47 break; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
48 default: |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
49 break; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
50 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
51 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
52 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
53 return flags; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
54 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 static size_t |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
57 file_read(struct vfs_file *file, void *buf, size_t bufsz) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
58 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
59 return zip_fread(file->data, buf, bufsz); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
60 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
61 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
62 static size_t |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
63 file_write(struct vfs_file *file, const void *buf, size_t bufsz) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
64 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
65 (void)file; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
66 (void)buf; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
67 (void)bufsz; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
68 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
69 return errorf("operation not supported"); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
70 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
71 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
72 static int |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
73 file_flush(struct vfs_file *file) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
75 (void)file; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 return 0; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
79 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
80 static void |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
81 file_finish(struct vfs_file *file) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
82 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
83 zip_fclose(file->data); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
84 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
85 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
86 static int |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
87 impl_open(struct vfs *vfs, struct vfs_file *file, const char *entry, const char *mode) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
88 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
89 (void)mode; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
90 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
91 if (!(file->data = zip_fopen(vfs->data, entry, 0))) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
92 return errorf("unable to open file in archive"); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
93 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
94 file->read = file_read; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
95 file->write = file_write; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
96 file->flush = file_flush; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
97 file->finish = file_finish; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
98 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
99 return 0; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
100 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
101 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
102 static void |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
103 impl_finish(struct vfs *vfs) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
104 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
105 zip_close(vfs->data); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
106 } |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
107 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
108 int |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
109 vfs_zip(struct vfs *vfs, const char *file, const char *mode) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
110 { |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
111 assert(vfs); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
112 assert(file); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
113 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
114 memset(vfs, 0, sizeof (*vfs)); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
115 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
116 if (!(vfs->data = zip_open(file, mkflags(mode), NULL))) |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
117 return errorf("%s: unable to open zip file", file); |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
118 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
119 vfs->open = impl_open; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
120 vfs->finish = impl_finish; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
121 |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
122 return 0; |
68287c7bcdb5
core: implement vfs-zip (read-only)
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
123 } |