... | ... |
@@ -493,7 +493,7 @@ |
493 | 493 |
/* #undef USE_SYSLOG */ |
494 | 494 |
|
495 | 495 |
/* Version number of package */ |
496 |
-#define VERSION "devel-clamav-0.96rc1-8-g9a04560" |
|
496 |
+#define VERSION "devel-clamav-0.96rc1-13-g99a2d96" |
|
497 | 497 |
|
498 | 498 |
/* Version suffix for package */ |
499 | 499 |
#define VERSION_SUFFIX "" |
... | ... |
@@ -220,18 +220,6 @@ |
220 | 220 |
> |
221 | 221 |
</File> |
222 | 222 |
</Filter> |
223 |
- <Filter |
|
224 |
- Name="compat" |
|
225 |
- > |
|
226 |
- <File |
|
227 |
- RelativePath=".\compat\libgen.c" |
|
228 |
- > |
|
229 |
- </File> |
|
230 |
- <File |
|
231 |
- RelativePath=".\compat\setargv.c" |
|
232 |
- > |
|
233 |
- </File> |
|
234 |
- </Filter> |
|
235 | 223 |
</Filter> |
236 | 224 |
<Filter |
237 | 225 |
Filter="h;hpp;hxx;hm;inl;inc;xsd" |
... | ... |
@@ -204,18 +204,6 @@ |
204 | 204 |
> |
205 | 205 |
</File> |
206 | 206 |
</Filter> |
207 |
- <Filter |
|
208 |
- Name="compat" |
|
209 |
- > |
|
210 |
- <File |
|
211 |
- RelativePath=".\compat\libgen.c" |
|
212 |
- > |
|
213 |
- </File> |
|
214 |
- <File |
|
215 |
- RelativePath=".\compat\setargv.c" |
|
216 |
- > |
|
217 |
- </File> |
|
218 |
- </Filter> |
|
219 | 207 |
</Filter> |
220 | 208 |
<Filter |
221 | 209 |
Filter="h;hpp;hxx;hm;inl;inc;xsd" |
... | ... |
@@ -190,18 +190,6 @@ |
190 | 190 |
> |
191 | 191 |
</File> |
192 | 192 |
<Filter |
193 |
- Name="compat" |
|
194 |
- > |
|
195 |
- <File |
|
196 |
- RelativePath=".\compat\libgen.c" |
|
197 |
- > |
|
198 |
- </File> |
|
199 |
- <File |
|
200 |
- RelativePath=".\compat\setargv.c" |
|
201 |
- > |
|
202 |
- </File> |
|
203 |
- </Filter> |
|
204 |
- <Filter |
|
205 | 193 |
Name="shared" |
206 | 194 |
> |
207 | 195 |
<File |
208 | 196 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,274 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: aCaB <acab@clamav.net> |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#include "dirent.h" |
|
21 |
+#include "libgen.h" |
|
22 |
+ |
|
23 |
+/* |
|
24 |
+ I GIVE UP! The CRT is b0rked and cannot be helped. |
|
25 |
+ |
|
26 |
+ The documentation suggestes to handle globbing automagically via linking in |
|
27 |
+ the msvc-provided setargv.obj. Unfortunately that thing has got any sort of bugs |
|
28 |
+ and perverts filenames rather than expanding them. |
|
29 |
+ |
|
30 |
+ The other suggested approach is to override the crt-builtin "_setargv" with a |
|
31 |
+ custom routine to manually process the command line args before they are fed to main. |
|
32 |
+ Now this is even funnier: the hook is indeed called bedore main(), but then its work |
|
33 |
+ is discarded and replaced with that of the default parser... how useful! |
|
34 |
+ After some debugging the problem turned out to be in the design. The flow is like: |
|
35 |
+ pre_c_init -> _setargv |
|
36 |
+ then |
|
37 |
+ pre_cpp_init -> _setargv |
|
38 |
+ Looking at the code in there, it clearly shows that both _init functions are 99% the |
|
39 |
+ same. In case you are wondering... yes, everything is done twice! Including the |
|
40 |
+ command line parsing... |
|
41 |
+ There is however a small difference: while pre_c_init correctly calls the custom |
|
42 |
+ _setargv if present, pre_cpp_init always calls the crt-builtin! |
|
43 |
+ If you want to double check this link the msvc-provided noarg.obj in, then break in main |
|
44 |
+ and see how argv and argc are actually set... If you try with setargv.obj, instead, you |
|
45 |
+ will see that it apparently works, but that's just a hack for which pre_cpp_init ends |
|
46 |
+ up calling __setargv instead of _setargv based on the _dowildcard flag. |
|
47 |
+ |
|
48 |
+ So the way to FIX this mess involves a small trick: in the _setargv override I |
|
49 |
+ don't just parse the command line properly, but I also turn my arguments into a new |
|
50 |
+ command line, which I use to replace the existing one. The replaced line will then be |
|
51 |
+ processed by pre_cpp_init and everything is fine. |
|
52 |
+ To replace the original line with the fixed one it's sufficient to replace the pointer |
|
53 |
+ returned by the __p__acmdln() function. The proto it "extern char **__p__acmdln(void)". |
|
54 |
+ |
|
55 |
+ Of course the trick only works if the line is crafted in a way that can be understood |
|
56 |
+ and parsed by the _setargv builtin. |
|
57 |
+ Apparently, however, the authors of this pile of crap which goes under the name of CRT, |
|
58 |
+ are not even able to keep their bugs consistent. So, while in MSVC 2008 it was enough to |
|
59 |
+ put each arg in "'s, in MSVC 2008 SP 1 you additionally need to take care of "escaped" |
|
60 |
+ quotes. I.e.: \". |
|
61 |
+ |
|
62 |
+ Whatever... |
|
63 |
+ I've given up trying to fit globbing below main. It's now hooked into main via a |
|
64 |
+ #define wrapper. |
|
65 |
+*/ |
|
66 |
+ |
|
67 |
+static int glob_add(const char *path, int *argc, char ***argv) { |
|
68 |
+ char *tail = strchr(path, '*'), *tailqmark; |
|
69 |
+ char *dup1, *dup2, *dir, *base, *taildirsep, *tailwldsep; |
|
70 |
+ struct dirent *de; |
|
71 |
+ int baselen, taillen, dirlen, mergedir = 0, outlen = 0; |
|
72 |
+ int qmarklen = 0; |
|
73 |
+ DIR *d; |
|
74 |
+ |
|
75 |
+ if(strlen(path) > 4 && !memcmp(path, "\\\\?\\", 4)) |
|
76 |
+ tailqmark = strchr(&path[4], '?'); |
|
77 |
+ else |
|
78 |
+ tailqmark = strchr(path, '?'); |
|
79 |
+ |
|
80 |
+ if(tailqmark && (!tail || tailqmark < tail)) |
|
81 |
+ tail = tailqmark; |
|
82 |
+ |
|
83 |
+ if(!tail) { |
|
84 |
+ *argv = realloc(*argv, sizeof(**argv) * (*argc + 1)); |
|
85 |
+ (*argv)[*argc] = path; |
|
86 |
+ (*argc)++; |
|
87 |
+ return strlen(path); |
|
88 |
+ } |
|
89 |
+ |
|
90 |
+ if(tail!=path && tail[-1] == '\\') { |
|
91 |
+ tail[-1] = '\0'; |
|
92 |
+ mergedir = 1; |
|
93 |
+ } |
|
94 |
+ while(*tail) { |
|
95 |
+ if(*tail == '?') { |
|
96 |
+ if(tail == tailqmark || qmarklen) |
|
97 |
+ qmarklen++; |
|
98 |
+ *tail = 0; |
|
99 |
+ } else if(*tail == '*') { |
|
100 |
+ *tail = '\0'; |
|
101 |
+ qmarklen = 0; |
|
102 |
+ } else |
|
103 |
+ break; |
|
104 |
+ tail++; |
|
105 |
+ } |
|
106 |
+ taillen = strlen(tail); |
|
107 |
+ taildirsep = strchr(tail, '\\'); |
|
108 |
+ if(taildirsep && taildirsep - tail == taillen - 1) { |
|
109 |
+ *taildirsep = '\0'; |
|
110 |
+ taildirsep = NULL; |
|
111 |
+ taillen--; |
|
112 |
+ } |
|
113 |
+ if(!taildirsep) |
|
114 |
+ taildirsep = tail + taillen; |
|
115 |
+ |
|
116 |
+ tailwldsep = strchr(tail, '*'); |
|
117 |
+ tailqmark = strchr(tail, '?'); |
|
118 |
+ if(tailqmark && (!tailwldsep || tailqmark < tailwldsep)) |
|
119 |
+ tailwldsep = tailqmark; |
|
120 |
+ if(!tailwldsep) |
|
121 |
+ tailwldsep = tail + taillen; |
|
122 |
+ |
|
123 |
+ dup1 = strdup(path); |
|
124 |
+ dup2 = strdup(path); |
|
125 |
+ |
|
126 |
+ if(!mergedir) { |
|
127 |
+ dir = dirname(dup1); |
|
128 |
+ base = basename(dup2); |
|
129 |
+ } else { |
|
130 |
+ dir = dup1; |
|
131 |
+ base = dup2; |
|
132 |
+ *dup2 = '\0'; |
|
133 |
+ } |
|
134 |
+ |
|
135 |
+ dirlen = strlen(dir); |
|
136 |
+ baselen = strlen(base); |
|
137 |
+ |
|
138 |
+ d = opendir(dir); |
|
139 |
+ while(d && (de = readdir(d))) { |
|
140 |
+ int namelen = strlen(de->d_name); |
|
141 |
+ char *newpath; |
|
142 |
+ |
|
143 |
+ if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; |
|
144 |
+ if(namelen < baselen) continue; |
|
145 |
+ if(strncasecmp(base, de->d_name, baselen)) continue; |
|
146 |
+ if(de->d_type == DT_DIR && taildirsep < tailwldsep) { |
|
147 |
+ int d_taillen = taildirsep - tail; |
|
148 |
+ if(namelen < baselen + d_taillen) continue; |
|
149 |
+ if(strncasecmp(tail, &de->d_name[namelen - d_taillen], d_taillen)) continue; |
|
150 |
+ newpath = malloc(dirlen + namelen + taillen - d_taillen + 3); |
|
151 |
+ sprintf(newpath, "%s\\%s\\%s", dir, de->d_name, &tail[d_taillen+1]); |
|
152 |
+ outlen += glob_add(newpath, argc, argv); |
|
153 |
+ } else { |
|
154 |
+ int d_taillen = tailwldsep - tail; |
|
155 |
+ char *start; |
|
156 |
+ if(namelen < baselen + d_taillen) continue; |
|
157 |
+ if(qmarklen && baselen + qmarklen + d_taillen != namelen) continue; |
|
158 |
+ if(d_taillen == taillen) { |
|
159 |
+ start = &de->d_name[namelen - d_taillen]; |
|
160 |
+ namelen = d_taillen; |
|
161 |
+ } else { |
|
162 |
+ start = &de->d_name[baselen]; |
|
163 |
+ namelen -= baselen; |
|
164 |
+ } |
|
165 |
+ |
|
166 |
+ for(; namelen >= d_taillen; start++, namelen--) { |
|
167 |
+ if(strncasecmp(start, tail, d_taillen)) continue; |
|
168 |
+ newpath = malloc(dirlen + (start - de->d_name) + taillen + 2); |
|
169 |
+ sprintf(newpath, "%s\\", dir); |
|
170 |
+ memcpy(&newpath[dirlen + 1], de->d_name, start - de->d_name); |
|
171 |
+ strcpy(&newpath[dirlen + 1 + start - de->d_name], tail); |
|
172 |
+ outlen += glob_add(newpath, argc, argv); |
|
173 |
+ } |
|
174 |
+ } |
|
175 |
+ } |
|
176 |
+ if(d) closedir(d); |
|
177 |
+ free(dup1); |
|
178 |
+ free(dup2); |
|
179 |
+ free(path); |
|
180 |
+ return outlen; |
|
181 |
+} |
|
182 |
+ |
|
183 |
+void w32_glob(int *argc_ptr, char ***argv_ptr) { |
|
184 |
+ char *cur = GetCommandLineA(), *begparm = NULL, *endparm = NULL; |
|
185 |
+ char **argv = NULL, c; |
|
186 |
+ int argc = 0, in_sq = 0, in_dq = 0, need_glob = 0, allarglen = 0; |
|
187 |
+ |
|
188 |
+ do { |
|
189 |
+ c = *cur; |
|
190 |
+ switch(c) { |
|
191 |
+ case '\0': |
|
192 |
+ endparm = cur; |
|
193 |
+ break; |
|
194 |
+ case ' ': |
|
195 |
+ if(begparm && !(in_sq | in_dq)) |
|
196 |
+ endparm = cur; |
|
197 |
+ break; |
|
198 |
+ case '\'': |
|
199 |
+ if(!in_dq) { |
|
200 |
+ in_sq = !in_sq; |
|
201 |
+ if(!in_sq) |
|
202 |
+ endparm = cur; |
|
203 |
+ } |
|
204 |
+ break; |
|
205 |
+ case '"': |
|
206 |
+ if(!in_sq) { |
|
207 |
+ in_dq = !in_dq; |
|
208 |
+ if(!in_dq) |
|
209 |
+ endparm = cur; |
|
210 |
+ } |
|
211 |
+ break; |
|
212 |
+ case '*': |
|
213 |
+ case '?': |
|
214 |
+ if(!in_sq) |
|
215 |
+ need_glob = 1; |
|
216 |
+ default: |
|
217 |
+ if(!begparm) { |
|
218 |
+ begparm = cur; |
|
219 |
+ endparm = NULL; |
|
220 |
+ } |
|
221 |
+ } |
|
222 |
+ if (begparm && endparm) { |
|
223 |
+ if(begparm < endparm) { |
|
224 |
+ char *path = malloc(endparm - begparm + 1), *quotes; |
|
225 |
+ int arglen = 0; |
|
226 |
+ |
|
227 |
+ memcpy(path, begparm, endparm - begparm); |
|
228 |
+ path[endparm - begparm] = '\0'; |
|
229 |
+ quotes = path; |
|
230 |
+ while((quotes = strchr(quotes, '"'))) |
|
231 |
+ memmove(quotes, quotes + 1, (endparm - begparm) - (quotes - path)); |
|
232 |
+ if(argc && need_glob) { |
|
233 |
+ arglen = glob_add(path, &argc, &argv); |
|
234 |
+ if(!arglen) { |
|
235 |
+ path = malloc(endparm - begparm + 1); |
|
236 |
+ memcpy(path, begparm, endparm - begparm); |
|
237 |
+ path[endparm - begparm] = '\0'; |
|
238 |
+ } |
|
239 |
+ } |
|
240 |
+ if(!arglen) { |
|
241 |
+ argv = realloc(argv, sizeof(*argv) * (argc + 1)); |
|
242 |
+ argv[argc] = path; |
|
243 |
+ argc++; |
|
244 |
+ arglen = endparm - begparm; |
|
245 |
+ } |
|
246 |
+ allarglen += arglen; |
|
247 |
+ } |
|
248 |
+ need_glob = 0; |
|
249 |
+ in_sq = 0; |
|
250 |
+ in_dq = 0; |
|
251 |
+ begparm = NULL; |
|
252 |
+ endparm = NULL; |
|
253 |
+ } |
|
254 |
+ cur++; |
|
255 |
+ } while (c); |
|
256 |
+ |
|
257 |
+ if(argc) { |
|
258 |
+ int i, argvlen = sizeof(*argv) * (argc + 1), argclen = 0; |
|
259 |
+ argv = realloc(argv, argvlen + allarglen + argc); |
|
260 |
+ argv[argc] = NULL; |
|
261 |
+ for(i=0; i<argc; i++) { |
|
262 |
+ int curlen = strlen(argv[i]) + 1; |
|
263 |
+ char *curarg = (char *)argv + argvlen + argclen; |
|
264 |
+ memcpy(curarg, argv[i], curlen); |
|
265 |
+ argclen += curlen; |
|
266 |
+ free(argv[i]); |
|
267 |
+ argv[i] = curarg; |
|
268 |
+ } |
|
269 |
+ } |
|
270 |
+ *argc_ptr = argc; |
|
271 |
+ *argv_ptr = argv; |
|
272 |
+} |
|
273 |
+ |
... | ... |
@@ -1,3 +1,23 @@ |
1 |
+/* |
|
2 |
+ * Copyright (C) 2010 Sourcefire, Inc. |
|
3 |
+ * |
|
4 |
+ * Authors: aCaB <acab@clamav.net> |
|
5 |
+ * |
|
6 |
+ * This program is free software; you can redistribute it and/or modify |
|
7 |
+ * it under the terms of the GNU General Public License version 2 as |
|
8 |
+ * published by the Free Software Foundation. |
|
9 |
+ * |
|
10 |
+ * This program is distributed in the hope that it will be useful, |
|
11 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
+ * GNU General Public License for more details. |
|
14 |
+ * |
|
15 |
+ * You should have received a copy of the GNU General Public License |
|
16 |
+ * along with this program; if not, write to the Free Software |
|
17 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
18 |
+ * MA 02110-1301, USA. |
|
19 |
+ */ |
|
20 |
+ |
|
1 | 21 |
/* just a draft for now */ |
2 | 22 |
|
3 | 23 |
#if HAVE_CONFIG_H |
4 | 24 |
deleted file mode 100644 |
... | ... |
@@ -1,269 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2009 Sourcefire, Inc. |
|
3 |
- * |
|
4 |
- * Authors: aCaB <acab@clamav.net> |
|
5 |
- * |
|
6 |
- * This program is free software; you can redistribute it and/or modify |
|
7 |
- * it under the terms of the GNU General Public License version 2 as |
|
8 |
- * published by the Free Software Foundation. |
|
9 |
- * |
|
10 |
- * This program is distributed in the hope that it will be useful, |
|
11 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 |
- * GNU General Public License for more details. |
|
14 |
- * |
|
15 |
- * You should have received a copy of the GNU General Public License |
|
16 |
- * along with this program; if not, write to the Free Software |
|
17 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
18 |
- * MA 02110-1301, USA. |
|
19 |
- */ |
|
20 |
- |
|
21 |
-#if HAVE_CONFIG_H |
|
22 |
-#include "clamav-config.h" |
|
23 |
-#endif |
|
24 |
- |
|
25 |
-#include "dirent.h" |
|
26 |
-#include "libgen.h" |
|
27 |
- |
|
28 |
-#include <fcntl.h> |
|
29 |
- |
|
30 |
-/* THIS IS A HACK ! */ |
|
31 |
-/* _setargv is the designed way to customize command line parsing which we use here |
|
32 |
- for globbing reasons (incidentally the globbing in setargv.obj is badly broken) |
|
33 |
- |
|
34 |
- The crt first calls OUR _setargv from pre_c_init but later, from within pre_cpp_init, |
|
35 |
- it also calls ITS OWN BUILTIN NATIVE CRAP, which re-parses the command line and |
|
36 |
- eventually overrides our override. |
|
37 |
- |
|
38 |
- So, we additionally replace the command line global pointer _acmdln with a |
|
39 |
- crafted set of arguments in order to fool buggy CRT's. |
|
40 |
-*/ |
|
41 |
-#define _MY_CRT_INSISTS_ON_PARSING_THE_COMMAND_LINE_TWICE_FOR_NO_REASONS_ |
|
42 |
-#ifdef _MY_CRT_INSISTS_ON_PARSING_THE_COMMAND_LINE_TWICE_FOR_NO_REASONS_ |
|
43 |
-extern char ** __p__acmdln(void); |
|
44 |
-#endif |
|
45 |
- |
|
46 |
-int glob_add(const char *path, int *argc, char ***argv); |
|
47 |
- |
|
48 |
-int _setargv() { |
|
49 |
- char *cur = GetCommandLineA(), *begparm = NULL, *endparm = NULL; |
|
50 |
- char **argv = NULL, c; |
|
51 |
- int argc = 0, in_sq = 0, in_dq = 0, need_glob = 0, allarglen = 0; |
|
52 |
- int *g_argc = __p___argc(); |
|
53 |
- char ***g_argv = __p___argv(); |
|
54 |
- |
|
55 |
- _setmode(_fileno(stdin), _O_BINARY); |
|
56 |
- do { |
|
57 |
- c = *cur; |
|
58 |
- switch(c) { |
|
59 |
- case '\0': |
|
60 |
- endparm = cur; |
|
61 |
- break; |
|
62 |
- case ' ': |
|
63 |
- if(begparm && !(in_sq | in_dq)) |
|
64 |
- endparm = cur; |
|
65 |
- break; |
|
66 |
- case '\'': |
|
67 |
- if(!in_dq) { |
|
68 |
- in_sq = !in_sq; |
|
69 |
- if(!in_sq) |
|
70 |
- endparm = cur; |
|
71 |
- } |
|
72 |
- break; |
|
73 |
- case '"': |
|
74 |
- if(!in_sq) { |
|
75 |
- in_dq = !in_dq; |
|
76 |
- if(!in_dq) |
|
77 |
- endparm = cur; |
|
78 |
- } |
|
79 |
- break; |
|
80 |
- case '*': |
|
81 |
- case '?': |
|
82 |
- if(!in_sq) |
|
83 |
- need_glob = 1; |
|
84 |
- default: |
|
85 |
- if(!begparm) { |
|
86 |
- begparm = cur; |
|
87 |
- endparm = NULL; |
|
88 |
- } |
|
89 |
- } |
|
90 |
- if (begparm && endparm) { |
|
91 |
- if(begparm < endparm) { |
|
92 |
- char *path = malloc(endparm - begparm + 1), *quotes; |
|
93 |
- int arglen = 0; |
|
94 |
- |
|
95 |
- memcpy(path, begparm, endparm - begparm); |
|
96 |
- path[endparm - begparm] = '\0'; |
|
97 |
- quotes = path; |
|
98 |
- while((quotes = strchr(quotes, '"'))) |
|
99 |
- memmove(quotes, quotes + 1, (endparm - begparm) - (quotes - path)); |
|
100 |
- if(argc && need_glob) { |
|
101 |
- arglen = glob_add(path, &argc, &argv); |
|
102 |
- if(!arglen) { |
|
103 |
- path = malloc(endparm - begparm + 1); |
|
104 |
- memcpy(path, begparm, endparm - begparm); |
|
105 |
- path[endparm - begparm] = '\0'; |
|
106 |
- } |
|
107 |
- } |
|
108 |
- if(!arglen) { |
|
109 |
- argv = realloc(argv, sizeof(*argv) * (argc + 1)); |
|
110 |
- argv[argc] = path; |
|
111 |
- argc++; |
|
112 |
- arglen = endparm - begparm; |
|
113 |
- } |
|
114 |
- allarglen += arglen; |
|
115 |
- } |
|
116 |
- need_glob = 0; |
|
117 |
- in_sq = 0; |
|
118 |
- in_dq = 0; |
|
119 |
- begparm = NULL; |
|
120 |
- endparm = NULL; |
|
121 |
- } |
|
122 |
- cur++; |
|
123 |
- } while (c); |
|
124 |
- |
|
125 |
- if(argc) { |
|
126 |
- int i, argvlen = sizeof(*argv) * (argc + 1), argclen = 0; |
|
127 |
- argv = realloc(argv, argvlen + allarglen + argc); |
|
128 |
- argv[argc] = NULL; |
|
129 |
- for(i=0; i<argc; i++) { |
|
130 |
- int curlen = strlen(argv[i]) + 1; |
|
131 |
- char *curarg = (char *)argv + argvlen + argclen; |
|
132 |
- memcpy(curarg, argv[i], curlen); |
|
133 |
- argclen += curlen; |
|
134 |
- free(argv[i]); |
|
135 |
- argv[i] = curarg; |
|
136 |
- } |
|
137 |
-#ifdef _MY_CRT_INSISTS_ON_PARSING_THE_COMMAND_LINE_TWICE_FOR_NO_REASONS_ |
|
138 |
- { |
|
139 |
- char *fake_cmdl = malloc(argclen + 1 + 2*argc); |
|
140 |
- char *curarg = fake_cmdl; |
|
141 |
- char **g_cmdl = __p__acmdln(); |
|
142 |
- for(i=0; i<argc; i++) |
|
143 |
- curarg += sprintf(curarg, "\"%s\" ", argv[i]); |
|
144 |
- curarg--; |
|
145 |
- *curarg = '\0'; |
|
146 |
- *g_cmdl = fake_cmdl; |
|
147 |
- } |
|
148 |
-#endif |
|
149 |
- *g_argc = argc; |
|
150 |
- *g_argv = argv; |
|
151 |
- } |
|
152 |
- return 0; |
|
153 |
-} |
|
154 |
- |
|
155 |
-int glob_add(const char *path, int *argc, char ***argv) { |
|
156 |
- char *tail = strchr(path, '*'), *tailqmark; |
|
157 |
- char *dup1, *dup2, *dir, *base, *taildirsep, *tailwldsep; |
|
158 |
- struct dirent *de; |
|
159 |
- int baselen, taillen, dirlen, mergedir = 0, outlen = 0; |
|
160 |
- int qmarklen = 0; |
|
161 |
- DIR *d; |
|
162 |
- |
|
163 |
- if(strlen(path) > 4 && !memcmp(path, "\\\\?\\", 4)) |
|
164 |
- tailqmark = strchr(&path[4], '?'); |
|
165 |
- else |
|
166 |
- tailqmark = strchr(path, '?'); |
|
167 |
- |
|
168 |
- if(tailqmark && (!tail || tailqmark < tail)) |
|
169 |
- tail = tailqmark; |
|
170 |
- |
|
171 |
- if(!tail) { |
|
172 |
- *argv = realloc(*argv, sizeof(**argv) * (*argc + 1)); |
|
173 |
- (*argv)[*argc] = path; |
|
174 |
- (*argc)++; |
|
175 |
- return strlen(path); |
|
176 |
- } |
|
177 |
- |
|
178 |
- if(tail!=path && tail[-1] == '\\') { |
|
179 |
- tail[-1] = '\0'; |
|
180 |
- mergedir = 1; |
|
181 |
- } |
|
182 |
- while(*tail) { |
|
183 |
- if(*tail == '?') { |
|
184 |
- if(tail == tailqmark || qmarklen) |
|
185 |
- qmarklen++; |
|
186 |
- *tail = 0; |
|
187 |
- } else if(*tail == '*') { |
|
188 |
- *tail = '\0'; |
|
189 |
- qmarklen = 0; |
|
190 |
- } else |
|
191 |
- break; |
|
192 |
- tail++; |
|
193 |
- } |
|
194 |
- taillen = strlen(tail); |
|
195 |
- taildirsep = strchr(tail, '\\'); |
|
196 |
- if(taildirsep && taildirsep - tail == taillen - 1) { |
|
197 |
- *taildirsep = '\0'; |
|
198 |
- taildirsep = NULL; |
|
199 |
- taillen--; |
|
200 |
- } |
|
201 |
- if(!taildirsep) |
|
202 |
- taildirsep = tail + taillen; |
|
203 |
- |
|
204 |
- tailwldsep = strchr(tail, '*'); |
|
205 |
- tailqmark = strchr(tail, '?'); |
|
206 |
- if(tailqmark && (!tailwldsep || tailqmark < tailwldsep)) |
|
207 |
- tailwldsep = tailqmark; |
|
208 |
- if(!tailwldsep) |
|
209 |
- tailwldsep = tail + taillen; |
|
210 |
- |
|
211 |
- dup1 = strdup(path); |
|
212 |
- dup2 = strdup(path); |
|
213 |
- |
|
214 |
- if(!mergedir) { |
|
215 |
- dir = dirname(dup1); |
|
216 |
- base = basename(dup2); |
|
217 |
- } else { |
|
218 |
- dir = dup1; |
|
219 |
- base = dup2; |
|
220 |
- *dup2 = '\0'; |
|
221 |
- } |
|
222 |
- |
|
223 |
- dirlen = strlen(dir); |
|
224 |
- baselen = strlen(base); |
|
225 |
- |
|
226 |
- d = opendir(dir); |
|
227 |
- while(d && (de = readdir(d))) { |
|
228 |
- int namelen = strlen(de->d_name); |
|
229 |
- char *newpath; |
|
230 |
- |
|
231 |
- if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; |
|
232 |
- if(namelen < baselen) continue; |
|
233 |
- if(strncasecmp(base, de->d_name, baselen)) continue; |
|
234 |
- if(de->d_type == DT_DIR && taildirsep < tailwldsep) { |
|
235 |
- int d_taillen = taildirsep - tail; |
|
236 |
- if(namelen < baselen + d_taillen) continue; |
|
237 |
- if(strncasecmp(tail, &de->d_name[namelen - d_taillen], d_taillen)) continue; |
|
238 |
- newpath = malloc(dirlen + namelen + taillen - d_taillen + 3); |
|
239 |
- sprintf(newpath, "%s\\%s\\%s", dir, de->d_name, &tail[d_taillen+1]); |
|
240 |
- outlen += glob_add(newpath, argc, argv); |
|
241 |
- } else { |
|
242 |
- int d_taillen = tailwldsep - tail; |
|
243 |
- char *start; |
|
244 |
- if(namelen < baselen + d_taillen) continue; |
|
245 |
- if(qmarklen && baselen + qmarklen + d_taillen != namelen) continue; |
|
246 |
- if(d_taillen == taillen) { |
|
247 |
- start = &de->d_name[namelen - d_taillen]; |
|
248 |
- namelen = d_taillen; |
|
249 |
- } else { |
|
250 |
- start = &de->d_name[baselen]; |
|
251 |
- namelen -= baselen; |
|
252 |
- } |
|
253 |
- |
|
254 |
- for(; namelen >= d_taillen; start++, namelen--) { |
|
255 |
- if(strncasecmp(start, tail, d_taillen)) continue; |
|
256 |
- newpath = malloc(dirlen + (start - de->d_name) + taillen + 2); |
|
257 |
- sprintf(newpath, "%s\\", dir); |
|
258 |
- memcpy(&newpath[dirlen + 1], de->d_name, start - de->d_name); |
|
259 |
- strcpy(&newpath[dirlen + 1 + start - de->d_name], tail); |
|
260 |
- outlen += glob_add(newpath, argc, argv); |
|
261 |
- } |
|
262 |
- } |
|
263 |
- } |
|
264 |
- if(d) closedir(d); |
|
265 |
- free(dup1); |
|
266 |
- free(dup2); |
|
267 |
- free(path); |
|
268 |
- return outlen; |
|
269 |
-} |
... | ... |
@@ -132,61 +132,64 @@ EXPORTS sha256_final @44274 NONAME |
132 | 132 |
EXPORTS optget @44275 NONAME |
133 | 133 |
EXPORTS optparse @44276 NONAME |
134 | 134 |
EXPORTS optfree @44277 NONAME |
135 |
-EXPORTS clam_options @44278 NONAME DATA |
|
135 |
+EXPORTS w32_glob @44278 NONAME |
|
136 |
+EXPORTS dirname @44279 NONAME |
|
137 |
+EXPORTS basename @44280 NONAME |
|
138 |
+EXPORTS clam_options @44281 NONAME DATA |
|
136 | 139 |
|
137 | 140 |
; zlib |
138 |
-EXPORTS gzopen @44279 NONAME |
|
139 |
-EXPORTS gzgets @44280 NONAME |
|
140 |
-EXPORTS gzdopen @44281 NONAME |
|
141 |
-EXPORTS gzclose @44282 NONAME |
|
142 |
-EXPORTS gzwrite @44283 NONAME |
|
141 |
+EXPORTS gzopen @44282 NONAME |
|
142 |
+EXPORTS gzgets @44283 NONAME |
|
143 |
+EXPORTS gzdopen @44284 NONAME |
|
144 |
+EXPORTS gzclose @44285 NONAME |
|
145 |
+EXPORTS gzwrite @44286 NONAME |
|
143 | 146 |
|
144 | 147 |
; pthreads |
145 |
-EXPORTS pthread_mutex_lock @44284 NONAME |
|
146 |
-EXPORTS pthread_mutex_unlock @44285 NONAME |
|
147 |
-EXPORTS pthread_mutex_destroy @44286 NONAME |
|
148 |
-EXPORTS pthread_once @44287 NONAME |
|
149 |
-EXPORTS pthread_getspecific @44288 NONAME |
|
150 |
-EXPORTS pthread_setspecific @44289 NONAME |
|
151 |
-EXPORTS pthread_create @44290 NONAME |
|
152 |
-EXPORTS pthread_cond_timedwait @44291 NONAME |
|
153 |
-EXPORTS pthread_cond_init @44292 NONAME |
|
154 |
-EXPORTS pthread_cond_broadcast @44293 NONAME |
|
155 |
-EXPORTS pthread_cond_signal @44294 NONAME |
|
156 |
-EXPORTS pthread_cond_destroy @44295 NONAME |
|
157 |
-EXPORTS pthread_join @44296 NONAME |
|
158 |
-EXPORTS pthread_key_create @44297 NONAME |
|
159 |
-EXPORTS pthread_cond_wait @44298 NONAME |
|
160 |
-EXPORTS pthread_attr_init @44299 NONAME |
|
161 |
-EXPORTS pthread_attr_setdetachstate @44300 NONAME |
|
162 |
-EXPORTS pthread_attr_destroy @44301 NONAME |
|
163 |
-EXPORTS pthread_mutex_init @44302 NONAME |
|
148 |
+EXPORTS pthread_mutex_lock @44287 NONAME |
|
149 |
+EXPORTS pthread_mutex_unlock @44288 NONAME |
|
150 |
+EXPORTS pthread_mutex_destroy @44289 NONAME |
|
151 |
+EXPORTS pthread_once @44290 NONAME |
|
152 |
+EXPORTS pthread_getspecific @44291 NONAME |
|
153 |
+EXPORTS pthread_setspecific @44292 NONAME |
|
154 |
+EXPORTS pthread_create @44293 NONAME |
|
155 |
+EXPORTS pthread_cond_timedwait @44294 NONAME |
|
156 |
+EXPORTS pthread_cond_init @44295 NONAME |
|
157 |
+EXPORTS pthread_cond_broadcast @44296 NONAME |
|
158 |
+EXPORTS pthread_cond_signal @44297 NONAME |
|
159 |
+EXPORTS pthread_cond_destroy @44298 NONAME |
|
160 |
+EXPORTS pthread_join @44299 NONAME |
|
161 |
+EXPORTS pthread_key_create @44300 NONAME |
|
162 |
+EXPORTS pthread_cond_wait @44301 NONAME |
|
163 |
+EXPORTS pthread_attr_init @44302 NONAME |
|
164 |
+EXPORTS pthread_attr_setdetachstate @44303 NONAME |
|
165 |
+EXPORTS pthread_attr_destroy @44304 NONAME |
|
166 |
+EXPORTS pthread_mutex_init @44305 NONAME |
|
164 | 167 |
|
165 | 168 |
; winsock bridge and compatibility functions |
166 |
-EXPORTS htonl @44303 NONAME |
|
167 |
-EXPORTS htons @44304 NONAME |
|
168 |
-EXPORTS ntohl @44305 NONAME |
|
169 |
-EXPORTS ntohs @44306 NONAME |
|
170 |
-EXPORTS __WSAFDIsSet @44307 NONAME |
|
171 |
-EXPORTS w32_socket @44308 NONAME |
|
172 |
-EXPORTS w32_getsockopt @44309 NONAME |
|
173 |
-EXPORTS w32_setsockopt @44310 NONAME |
|
174 |
-EXPORTS w32_bind @44311 NONAME |
|
175 |
-EXPORTS w32_listen @44312 NONAME |
|
176 |
-EXPORTS w32_accept @44313 NONAME |
|
177 |
-EXPORTS w32_connect @44314 NONAME |
|
178 |
-EXPORTS w32_shutdown @44315 NONAME |
|
179 |
-EXPORTS w32_send @44316 NONAME |
|
180 |
-EXPORTS w32_recv @44317 NONAME |
|
181 |
-EXPORTS w32_closesocket @44318 NONAME |
|
182 |
-EXPORTS w32_getservbyname @44319 NONAME |
|
183 |
-EXPORTS w32_getaddrinfo @44320 NONAME |
|
184 |
-EXPORTS w32_freeaddrinfo @44321 NONAME |
|
185 |
-EXPORTS w32_inet_ntop @44322 NONAME |
|
186 |
-EXPORTS w32_gethostbyname @44323 NONAME |
|
187 |
-EXPORTS w32_select @44324 NONAME |
|
188 |
-EXPORTS poll_with_event @44325 NONAME |
|
189 |
-EXPORTS w32_stat @44326 NONAME |
|
190 |
-EXPORTS w32_strerror @44327 NONAME |
|
191 |
-EXPORTS w32_strerror_r @44328 NONAME |
|
192 |
-EXPORTS inet_addr @44329 NONAME |
|
169 |
+EXPORTS htonl @44306 NONAME |
|
170 |
+EXPORTS htons @44307 NONAME |
|
171 |
+EXPORTS ntohl @44308 NONAME |
|
172 |
+EXPORTS ntohs @44309 NONAME |
|
173 |
+EXPORTS __WSAFDIsSet @44310 NONAME |
|
174 |
+EXPORTS w32_socket @44311 NONAME |
|
175 |
+EXPORTS w32_getsockopt @44312 NONAME |
|
176 |
+EXPORTS w32_setsockopt @44313 NONAME |
|
177 |
+EXPORTS w32_bind @44314 NONAME |
|
178 |
+EXPORTS w32_listen @44315 NONAME |
|
179 |
+EXPORTS w32_accept @44316 NONAME |
|
180 |
+EXPORTS w32_connect @44317 NONAME |
|
181 |
+EXPORTS w32_shutdown @44318 NONAME |
|
182 |
+EXPORTS w32_send @44319 NONAME |
|
183 |
+EXPORTS w32_recv @44320 NONAME |
|
184 |
+EXPORTS w32_closesocket @44321 NONAME |
|
185 |
+EXPORTS w32_getservbyname @44322 NONAME |
|
186 |
+EXPORTS w32_getaddrinfo @44323 NONAME |
|
187 |
+EXPORTS w32_freeaddrinfo @44324 NONAME |
|
188 |
+EXPORTS w32_inet_ntop @44325 NONAME |
|
189 |
+EXPORTS w32_gethostbyname @44326 NONAME |
|
190 |
+EXPORTS w32_select @44327 NONAME |
|
191 |
+EXPORTS poll_with_event @44328 NONAME |
|
192 |
+EXPORTS w32_stat @44329 NONAME |
|
193 |
+EXPORTS w32_strerror @44330 NONAME |
|
194 |
+EXPORTS w32_strerror_r @44331 NONAME |
|
195 |
+EXPORTS inet_addr @44332 NONAME |
... | ... |
@@ -6,7 +6,7 @@ |
6 | 6 |
ProjectType="Visual C++" |
7 | 7 |
RootNamespace="libclamav" |
8 | 8 |
TargetFrameworkVersion="196613" |
9 |
- Version="9.00" |
|
9 |
+ Version="9,00" |
|
10 | 10 |
> |
11 | 11 |
<Platforms> |
12 | 12 |
<Platform |
... | ... |
@@ -185,14 +185,6 @@ |
185 | 185 |
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" |
186 | 186 |
> |
187 | 187 |
<File |
188 |
- RelativePath="..\libclamav\filtering.c" |
|
189 |
- > |
|
190 |
- </File> |
|
191 |
- <File |
|
192 |
- RelativePath="..\libclamav\perflogging.c" |
|
193 |
- > |
|
194 |
- </File> |
|
195 |
- <File |
|
196 | 188 |
RelativePath="..\libclamav\7z.c" |
197 | 189 |
> |
198 | 190 |
</File> |
... | ... |
@@ -285,6 +277,10 @@ |
285 | 285 |
> |
286 | 286 |
</File> |
287 | 287 |
<File |
288 |
+ RelativePath="..\libclamav\filtering.c" |
|
289 |
+ > |
|
290 |
+ </File> |
|
291 |
+ <File |
|
288 | 292 |
RelativePath="..\libclamav\fmap.c" |
289 | 293 |
> |
290 | 294 |
</File> |
... | ... |
@@ -393,6 +389,10 @@ |
393 | 393 |
> |
394 | 394 |
</File> |
395 | 395 |
<File |
396 |
+ RelativePath="..\libclamav\perflogging.c" |
|
397 |
+ > |
|
398 |
+ </File> |
|
399 |
+ <File |
|
396 | 400 |
RelativePath="..\libclamav\petite.c" |
397 | 401 |
> |
398 | 402 |
</File> |
... | ... |
@@ -792,6 +792,10 @@ |
792 | 792 |
> |
793 | 793 |
</File> |
794 | 794 |
<File |
795 |
+ RelativePath=".\compat\glob.c" |
|
796 |
+ > |
|
797 |
+ </File> |
|
798 |
+ <File |
|
795 | 799 |
RelativePath=".\compat\libclamav_main.c" |
796 | 800 |
> |
797 | 801 |
</File> |
... | ... |
@@ -6,6 +6,7 @@ |
6 | 6 |
#include <stdio.h> |
7 | 7 |
#include <stdlib.h> |
8 | 8 |
#include <io.h> |
9 |
+#include <fcntl.h> |
|
9 | 10 |
#include <direct.h> |
10 | 11 |
#include <Ws2tcpip.h> |
11 | 12 |
#include <process.h> |
... | ... |
@@ -73,6 +74,8 @@ typedef unsigned int in_addr_t; |
73 | 73 |
|
74 | 74 |
#define PATHSEP "\\" |
75 | 75 |
|
76 |
+void w32_glob(int *argc_ptr, char ***argv_ptr); |
|
77 |
+ |
|
76 | 78 |
#undef DATADIR |
77 | 79 |
#undef CONFDIR |
78 | 80 |
#if !defined(THIS_IS_LIBCLAMAV) && defined(_MSC_VER) |
... | ... |
@@ -91,5 +94,8 @@ LIBCLAMAV_EXPORT extern const char *CONFDIR_MILTER; |
91 | 91 |
#undef OUT |
92 | 92 |
#endif |
93 | 93 |
|
94 |
+int real_main(int, char**); |
|
95 |
+#define main main(int argc, char **argv) { _setmode(_fileno(stdin), _O_BINARY); w32_glob(&argc, &argv); return real_main(argc, argv); }; int real_main |
|
96 |
+ |
|
94 | 97 |
#endif /* __PLATFORM_H */ |
95 | 98 |
|
... | ... |
@@ -215,13 +215,13 @@ my @PROJECTS = ( |
215 | 215 |
{makefile => 'libclamav/c++', sections => ['libclamavcxx'], output => 'win32/libclamavcxx.vcproj'}, |
216 | 216 |
|
217 | 217 |
# CLAMSCAN # |
218 |
- {makefile => 'clamscan', sections => ['clamscan'], output => 'win32/clamscan.vcproj', makefile_only => '(optparser\\.c|getopt\\.c)$', vcproj_only => 'compat\\\\'}, |
|
218 |
+ {makefile => 'clamscan', sections => ['clamscan'], output => 'win32/clamscan.vcproj', makefile_only => '(optparser\\.c|getopt\\.c)$'}, |
|
219 | 219 |
|
220 | 220 |
# CLAMDSCAN # |
221 |
- {makefile => 'clamdscan', sections => ['clamdscan'], output => 'win32/clamdscan.vcproj', makefile_only => '(optparser\\.c|getopt\\.c)$', vcproj_only => 'compat\\\\'}, |
|
221 |
+ {makefile => 'clamdscan', sections => ['clamdscan'], output => 'win32/clamdscan.vcproj', makefile_only => '(optparser\\.c|getopt\\.c)$'}, |
|
222 | 222 |
|
223 | 223 |
# CLAMD # |
224 |
- {makefile => 'clamd', sections => ['clamd'], output => 'win32/clamd.vcproj', makefile_only => '(optparser\\.c|getopt\\.c|(daz|clam)uko.*)$', vcproj_only => 'compat\\\\'}, |
|
224 |
+ {makefile => 'clamd', sections => ['clamd'], output => 'win32/clamd.vcproj', makefile_only => '(optparser\\.c|getopt\\.c|(daz|clam)uko.*)$'}, |
|
225 | 225 |
|
226 | 226 |
# FRESHCLAM # |
227 | 227 |
{makefile => 'freshclam', sections => ['freshclam'], output => 'win32/freshclam.vcproj', makefile_only => '(optparser\\.c|getopt\\.c)$', vcproj_only => 'compat\\\\'}, |