/src/httrack/src/htsmodules.c
Line | Count | Source |
1 | | /* ------------------------------------------------------------ */ |
2 | | /* |
3 | | HTTrack Website Copier, Offline Browser for Windows and Unix |
4 | | Copyright (C) 1998 Xavier Roche and other contributors |
5 | | |
6 | | SPDX-License-Identifier: GPL-3.0-or-later |
7 | | |
8 | | This program is free software: you can redistribute it and/or modify |
9 | | it under the terms of the GNU General Public License as published by |
10 | | the Free Software Foundation, either version 3 of the License, or |
11 | | (at your option) any later version. |
12 | | |
13 | | This program 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. See the |
16 | | GNU General Public License for more details. |
17 | | |
18 | | You should have received a copy of the GNU General Public License |
19 | | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | | |
21 | | Ethical use: we kindly ask that you NOT use this software to harvest email |
22 | | addresses or to collect any other private information about people. Doing so |
23 | | would dishonor our work and waste the many hours we have spent on it. |
24 | | |
25 | | Please visit our Website: http://www.httrack.com |
26 | | */ |
27 | | |
28 | | /* ------------------------------------------------------------ */ |
29 | | /* File: htsmodules.c subroutines: */ |
30 | | /* external modules (parsers) */ |
31 | | /* Author: Xavier Roche */ |
32 | | /* ------------------------------------------------------------ */ |
33 | | |
34 | | /* Internal engine bytecode */ |
35 | | #define HTS_INTERNAL_BYTECODE |
36 | | |
37 | | #include "htsglobal.h" |
38 | | #include "htsmodules.h" |
39 | | #include "htsopt.h" |
40 | | #include "htsbasenet.h" |
41 | | #include "htslib.h" |
42 | | |
43 | | extern int fspc(httrackp * opt, FILE * fp, const char *type); |
44 | | |
45 | | #ifndef _WIN32 |
46 | | #if HTS_DLOPEN |
47 | | #include <dlfcn.h> |
48 | | #endif |
49 | | #endif |
50 | | |
51 | | /* >>> Put all modules definitions here */ |
52 | | #include "htszlib.h" |
53 | | #include "htsbase.h" |
54 | | /* <<< */ |
55 | | |
56 | | /* >>> Put all modules variables here */ |
57 | | |
58 | | int V6_is_available = HTS_INET6; |
59 | | |
60 | | static char WHAT_is_available[64] = ""; |
61 | | |
62 | | /* <<< */ |
63 | | |
64 | 0 | HTSEXT_API const char *hts_get_version_info(httrackp * opt) { |
65 | 0 | size_t size; |
66 | 0 | int i; |
67 | |
|
68 | 0 | strcpy(opt->state.HTbuff, WHAT_is_available); |
69 | 0 | size = strlen(opt->state.HTbuff); |
70 | 0 | for(i = 0; i < opt->libHandles.count; i++) { |
71 | 0 | const char *name = opt->libHandles.handles[i].moduleName; |
72 | |
|
73 | 0 | if (name != NULL) { |
74 | 0 | size_t nsize = strlen(name) + sizeof("+"); |
75 | |
|
76 | 0 | size += nsize; |
77 | 0 | if (size + 1 >= sizeof(opt->state.HTbuff)) |
78 | 0 | break; |
79 | 0 | strcat(opt->state.HTbuff, "+"); |
80 | 0 | strcat(opt->state.HTbuff, name); |
81 | 0 | } |
82 | 0 | } |
83 | 0 | return opt->state.HTbuff; |
84 | 0 | } |
85 | | |
86 | | static void htspe_log(htsmoduleStruct * str, const char *msg); |
87 | | |
88 | 0 | int hts_parse_externals(htsmoduleStruct * str) { |
89 | 0 | str->wrapper_name = "wrapper-lib"; |
90 | | |
91 | | /* External callback */ |
92 | 0 | if (RUN_CALLBACK1(str->opt, detect, str)) { |
93 | 0 | if (str->wrapper_name == NULL) |
94 | 0 | str->wrapper_name = "wrapper-lib"; |
95 | | /* Blacklisted */ |
96 | 0 | if (multipleStringMatch |
97 | 0 | (str->wrapper_name, StringBuff(str->opt->mod_blacklist))) { |
98 | 0 | return -1; |
99 | 0 | } else { |
100 | 0 | htspe_log(str, str->wrapper_name); |
101 | 0 | return RUN_CALLBACK1(str->opt, parse, str); |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | /* Not detected */ |
106 | 0 | return -1; |
107 | 0 | } |
108 | | |
109 | | void clearCallbacks(htscallbacks * chain_); |
110 | 0 | void clearCallbacks(htscallbacks * chain_) { |
111 | 0 | htscallbacks *chain; |
112 | |
|
113 | 0 | chain = chain_; |
114 | 0 | while(chain != NULL) { |
115 | 0 | if (chain->exitFnc != NULL) { |
116 | 0 | (void) chain->exitFnc(); /* result ignored */ |
117 | 0 | chain->exitFnc = NULL; |
118 | 0 | } |
119 | 0 | chain = chain->next; |
120 | 0 | } |
121 | 0 | chain = chain_; |
122 | 0 | while(chain != NULL) { |
123 | 0 | if (chain->moduleHandle != NULL) { |
124 | | #ifdef _WIN32 |
125 | | FreeLibrary(chain->moduleHandle); |
126 | | #else |
127 | 0 | dlclose(chain->moduleHandle); |
128 | 0 | #endif |
129 | 0 | } |
130 | 0 | chain = chain->next; |
131 | 0 | } |
132 | 0 | chain = chain_->next; // Don't free the block #0 |
133 | 0 | while(chain != NULL) { |
134 | 0 | htscallbacks *nextchain = chain->next; |
135 | |
|
136 | 0 | freet(chain); |
137 | 0 | chain = nextchain; |
138 | 0 | } |
139 | 0 | chain_->next = NULL; // Empty |
140 | 0 | } |
141 | | |
142 | 0 | void *openFunctionLib(const char *file_) { |
143 | 0 | void *handle; |
144 | 0 | char *file = malloct(strlen(file_) + 32); |
145 | |
|
146 | 0 | if (file == NULL) |
147 | 0 | return NULL; /* no module, which the caller already reports */ |
148 | 0 | strcpy(file, file_); |
149 | | #ifdef _WIN32 |
150 | | handle = LoadLibraryA(file); |
151 | | if (handle == NULL) { |
152 | | sprintf(file, "%s.dll", file_); |
153 | | handle = LoadLibraryA(file); |
154 | | } |
155 | | #else |
156 | 0 | handle = dlopen(file, RTLD_LAZY); |
157 | 0 | if (handle == NULL) { |
158 | 0 | sprintf(file, "lib%s.so", file_); |
159 | 0 | handle = dlopen(file, RTLD_LAZY); |
160 | 0 | } |
161 | 0 | #endif |
162 | 0 | freet(file); |
163 | 0 | return handle; |
164 | 0 | } |
165 | | |
166 | 0 | void closeFunctionLib(void *handle) { |
167 | | #ifdef _WIN32 |
168 | | FreeLibrary(handle); |
169 | | #else |
170 | 0 | dlclose(handle); |
171 | 0 | #endif |
172 | 0 | } |
173 | | |
174 | 0 | void *getFunctionPtr(void *handle, const char *fncname_) { |
175 | 0 | if (handle) { |
176 | 0 | void *userfunction = NULL; |
177 | 0 | char *fncname = strdupt(fncname_); |
178 | | |
179 | | /* Strip optional comma */ |
180 | 0 | char *comma; |
181 | |
|
182 | 0 | if ((comma = strchr(fncname, ',')) != NULL) { /* empty arg */ |
183 | 0 | *comma++ = '\0'; |
184 | 0 | } |
185 | | |
186 | | /* the function itself */ |
187 | 0 | userfunction = (void *) DynamicGet(handle, (char *) fncname); |
188 | |
|
189 | 0 | freet(fncname); |
190 | |
|
191 | 0 | return userfunction; |
192 | 0 | } |
193 | 0 | return NULL; |
194 | 0 | } |
195 | | |
196 | 0 | void htspe_init(void) { |
197 | 0 | static int initOk = 0; |
198 | |
|
199 | 0 | if (!initOk) { |
200 | 0 | initOk = 1; |
201 | | |
202 | | /* See CVE-2010-5252 */ |
203 | | #if (defined(_WIN32) && (!defined(_DEBUG))) |
204 | | { |
205 | | /* See KB 2389418 |
206 | | "If this parameter is an empty string (""), the call removes the |
207 | | current directory from the default DLL search order" */ |
208 | | BOOL (WINAPI*const k32_SetDllDirectoryA)(LPCSTR) = |
209 | | (BOOL (WINAPI *)(LPCSTR)) |
210 | | GetProcAddress(GetModuleHandle("kernel32.dll"), "SetDllDirectoryA"); |
211 | | if (k32_SetDllDirectoryA != NULL && !k32_SetDllDirectoryA("")) { |
212 | | /* Do no choke on NT or 98SE with KernelEx NT API (James Blough) */ |
213 | | const DWORD dwVersion = GetVersion(); |
214 | | const DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); |
215 | | const DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); |
216 | | if (dwMajorVersion >= 5) { |
217 | | assertf(!"SetDllDirectory failed"); |
218 | | } |
219 | | } |
220 | | } |
221 | | #endif |
222 | | |
223 | | /* Options availability */ |
224 | 0 | sprintf(WHAT_is_available, "%s%s%s", V6_is_available ? "" : "-noV6", |
225 | 0 | "", |
226 | | #if HTS_USEOPENSSL |
227 | | "" |
228 | | #else |
229 | 0 | "-nossl" |
230 | 0 | #endif |
231 | 0 | ); |
232 | 0 | } |
233 | 0 | } |
234 | | |
235 | 0 | void htspe_uninit(void) { |
236 | 0 | } |
237 | | |
238 | 0 | static void htspe_log(htsmoduleStruct * str, const char *msg) { |
239 | 0 | const char *savename = str->filename; |
240 | 0 | httrackp *opt = (httrackp *) str->opt; |
241 | |
|
242 | 0 | hts_log_print(opt, LOG_DEBUG, "(External module): parsing %s using module %s", |
243 | 0 | savename, msg); |
244 | 0 | } |
245 | | |
246 | 0 | HTSEXT_API const char *hts_is_available(void) { |
247 | 0 | return WHAT_is_available; |
248 | 0 | } |