diff options
Diffstat (limited to 'src/mimehooks.c')
-rw-r--r-- | src/mimehooks.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/mimehooks.c b/src/mimehooks.c new file mode 100644 index 00000000..3d999aba --- /dev/null +++ b/src/mimehooks.c | |||
@@ -0,0 +1,139 @@ | |||
1 | #include "mimehooks.h" | ||
2 | |||
3 | #include <the_Foundation/file.h> | ||
4 | #include <the_Foundation/path.h> | ||
5 | #include <the_Foundation/process.h> | ||
6 | #include <the_Foundation/stringlist.h> | ||
7 | |||
8 | iDefineTypeConstruction(FilterHook) | ||
9 | |||
10 | void init_FilterHook(iFilterHook *d) { | ||
11 | init_String(&d->label); | ||
12 | init_String(&d->mimePattern); | ||
13 | init_String(&d->command); | ||
14 | d->mimeRegex = NULL; | ||
15 | } | ||
16 | |||
17 | void deinit_FilterHook(iFilterHook *d) { | ||
18 | iRelease(d->mimeRegex); | ||
19 | deinit_String(&d->command); | ||
20 | deinit_String(&d->mimePattern); | ||
21 | deinit_String(&d->label); | ||
22 | } | ||
23 | |||
24 | void setMimePattern_FilterHook(iFilterHook *d, const iString *pattern) { | ||
25 | iReleasePtr(&d->mimeRegex); | ||
26 | d->mimeRegex = new_RegExp(cstr_String(pattern), caseInsensitive_RegExpOption); | ||
27 | } | ||
28 | |||
29 | void setCommand_FilterHook(iFilterHook *d, const iString *command) { | ||
30 | set_String(&d->command, command); | ||
31 | } | ||
32 | |||
33 | iBlock *run_FilterHook_(const iFilterHook *d, const iString *mime, const iBlock *body) { | ||
34 | iProcess * proc = new_Process(); | ||
35 | iStringList *args = new_StringList(); | ||
36 | iRangecc seg = iNullRange; | ||
37 | while (nextSplit_Rangecc(range_String(&d->command), ";", &seg)) { | ||
38 | pushBackRange_StringList(args, seg); | ||
39 | } | ||
40 | seg = iNullRange; | ||
41 | while (nextSplit_Rangecc(range_String(mime), ";", &seg)) { | ||
42 | pushBackRange_StringList(args, seg); | ||
43 | } | ||
44 | setArguments_Process(proc, args); | ||
45 | iRelease(args); | ||
46 | start_Process(proc); | ||
47 | writeInput_Process(proc, body); | ||
48 | waitForFinished_Process(proc); | ||
49 | iBlock *output = readOutput_Process(proc); | ||
50 | if (!startsWith_Rangecc(range_Block(output), "20")) { | ||
51 | /* Didn't produce valid output. */ | ||
52 | delete_Block(output); | ||
53 | output = NULL; | ||
54 | } | ||
55 | iRelease(proc); | ||
56 | return output; | ||
57 | } | ||
58 | |||
59 | /*----------------------------------------------------------------------------------------------*/ | ||
60 | |||
61 | struct Impl_MimeHooks { | ||
62 | iPtrArray filters; | ||
63 | }; | ||
64 | |||
65 | iDefineTypeConstruction(MimeHooks) | ||
66 | |||
67 | void init_MimeHooks(iMimeHooks *d) { | ||
68 | init_PtrArray(&d->filters); | ||
69 | } | ||
70 | |||
71 | void deinit_MimeHooks(iMimeHooks *d) { | ||
72 | iForEach(PtrArray, i, &d->filters) { | ||
73 | delete_FilterHook(i.ptr); | ||
74 | } | ||
75 | deinit_PtrArray(&d->filters); | ||
76 | } | ||
77 | |||
78 | iBool willTryFilter_MimeHooks(const iMimeHooks *d, const iString *mime) { | ||
79 | /* TODO: Combine this function with tryFilter_MimeHooks? */ | ||
80 | iRegExpMatch m; | ||
81 | iConstForEach(PtrArray, i, &d->filters) { | ||
82 | const iFilterHook *xc = i.ptr; | ||
83 | init_RegExpMatch(&m); | ||
84 | if (matchString_RegExp(xc->mimeRegex, mime, &m)) { | ||
85 | return iTrue; | ||
86 | } | ||
87 | } | ||
88 | return iFalse; | ||
89 | } | ||
90 | |||
91 | iBlock *tryFilter_MimeHooks(const iMimeHooks *d, const iString *mime, const iBlock *body) { | ||
92 | iRegExpMatch m; | ||
93 | iConstForEach(PtrArray, i, &d->filters) { | ||
94 | const iFilterHook *xc = i.ptr; | ||
95 | init_RegExpMatch(&m); | ||
96 | if (matchString_RegExp(xc->mimeRegex, mime, &m)) { | ||
97 | iBlock *result = run_FilterHook_(xc, mime, body); | ||
98 | if (result) { | ||
99 | return result; | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | return NULL; | ||
104 | } | ||
105 | |||
106 | static const char *mimeHooksFilename_MimeHooks_ = "mimehooks.txt"; | ||
107 | |||
108 | void load_MimeHooks(iMimeHooks *d, const char *saveDir) { | ||
109 | iFile *f = newCStr_File(concatPath_CStr(saveDir, mimeHooksFilename_MimeHooks_)); | ||
110 | if (open_File(f, read_FileMode | text_FileMode)) { | ||
111 | iBlock * src = readAll_File(f); | ||
112 | iRangecc srcLine = iNullRange; | ||
113 | int pos = 0; | ||
114 | iRangecc lines[3]; | ||
115 | iZap(lines); | ||
116 | while (nextSplit_Rangecc(range_Block(src), "\n", &srcLine)) { | ||
117 | iRangecc line = srcLine; | ||
118 | trim_Rangecc(&line); | ||
119 | if (isEmpty_Range(&line)) { | ||
120 | continue; | ||
121 | } | ||
122 | lines[pos++] = line; | ||
123 | if (pos == 3) { | ||
124 | iFilterHook *hook = new_FilterHook(); | ||
125 | setRange_String(&hook->label, lines[0]); | ||
126 | setMimePattern_FilterHook(hook, collect_String(newRange_String(lines[1]))); | ||
127 | setCommand_FilterHook(hook, collect_String(newRange_String(lines[2]))); | ||
128 | pushBack_PtrArray(&d->filters, hook); | ||
129 | } | ||
130 | } | ||
131 | delete_Block(src); | ||
132 | } | ||
133 | iRelease(f); | ||
134 | } | ||
135 | |||
136 | void save_MimeHooks(const iMimeHooks *d) { | ||
137 | iUnused(d); | ||
138 | } | ||
139 | |||