diff --git a/ChangeLog b/ChangeLog index e83b90cdc..f9ced8b95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sun Oct 18 02:30:14 CEST 2009 (acab) +------------------------------------ + * win32: glob() before main (WIP) + Fri Oct 16 20:08:51 CEST 2009 (acab) ------------------------------------ * win32: stat added, dirent updated diff --git a/win32/clamscan.vcproj b/win32/clamscan.vcproj index 0aefcca5e..72e0e3bed 100644 --- a/win32/clamscan.vcproj +++ b/win32/clamscan.vcproj @@ -196,6 +196,10 @@ RelativePath=".\compat\libgen.c" > + + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#if HAVE_CONFIG_H +#include "clamav-config.h" +#endif + +#include "dirent.h" +#include "libgen.h" + +/* THIS IS A HACK ! */ +/* _setargv is the designed way to customize command line parsing which we use here + for globbing reasons (incidentally the globbing in setargv.obj is badly broken) + + The crt first calls OUR _setargv from pre_c_init but later, from within pre_cpp_init, + it also calls ITS OWN BUILTIN NATIVE CRAP, which re-parses the command line and + eventually overrides our override. + + So, we additionally replace the command line global pointer _acmdln with a + crafted set of arguments in order to fool buggy CRT's. +*/ +#define _MY_CRT_INSISTS_ON_PARSING_THE_COMMAND_LINE_TWICE_FOR_NO_REASONS_ +#ifdef _MY_CRT_INSISTS_ON_PARSING_THE_COMMAND_LINE_TWICE_FOR_NO_REASONS_ +extern char ** __p__acmdln(void); +#endif + +void glob_add(const char *path, int *argc, char ***argv); + +int _setargv() { + char *cur = GetCommandLineA(), *begparm = NULL, *endparm = NULL; + char **argv = NULL, c; + int argc = 0, i, in_sq = 0, in_dq = 0, need_glob = 0; + int *g_argc = __p___argc(); + char ***g_argv = __p___argv(); + + do { + c = *cur; + switch(c) { + case '\0': + endparm = cur; + break; + case ' ': + if(begparm && !(in_sq | in_dq)) + endparm = cur; + break; + case '\'': + if(!in_dq) { + in_sq = !in_sq; + if(!in_sq) + endparm = cur; + } + break; + case '"': + if(!in_sq) { + in_dq = !in_dq; + if(!in_dq) + endparm = cur; + } + break; + case '*': +// case '?': + if(!in_sq) + need_glob = 1; + default: + if(!begparm) { + begparm = cur; + endparm = NULL; + } + } + if (begparm && endparm) { + if(begparm < endparm) { + char *path = malloc(endparm - begparm + 1); + + memcpy(path, begparm, endparm - begparm); + path[endparm - begparm] = '\0'; + if(argc || need_glob) + glob_add(path, &argc, &argv); + else { + argv = realloc(argv, sizeof(*argv) * (argc + 1)); + argv[argc] = path; + argc++; + } + } + need_glob = 0; + in_sq = 0; + in_dq = 0; + begparm = NULL; + endparm = NULL; + } + cur++; + } while (c); + + if(argc) { + int i, argvlen = sizeof(*argv) * (argc + 1), argclen = 0; + argv = realloc(argv, argvlen); + argv[argc] = NULL; + for(i=0; id_name); + char *newpath; + + if(namelen < baselen) continue; + if(strncasecmp(base, de->d_name, baselen)) continue; + if(de->d_type == DT_DIR && taildirsep <= tailwldsep) { + int d_taillen = taildirsep - tail; + if(namelen < baselen + d_taillen) continue; + if(strncasecmp(tail, &de->d_name[namelen - d_taillen], d_taillen)) continue; + newpath = malloc(dirlen + namelen + taillen - d_taillen + 3); + sprintf(newpath, "%s\\%s\\%s", dir, de->d_name, &tail[d_taillen+1]); + glob_add(newpath, argc, argv); + } else { + int d_taillen = tailwldsep - tail; + char *start; + if(namelen < baselen + d_taillen) continue; + + start = &de->d_name[baselen]; + namelen -= baselen; + + for(; namelen >= d_taillen; start++, namelen--) { + if(strncasecmp(start, tail, d_taillen)) continue; + newpath = malloc(dirlen + (start - de->d_name) + taillen + 2); + sprintf(newpath, "%s\\", dir); + memcpy(&newpath[dirlen + 1], de->d_name, start - de->d_name); + strcpy(&newpath[dirlen + 1 + start - de->d_name], tail); + glob_add(newpath, argc, argv); + } + } + } + if(d) closedir(d); + free(dup1); + free(dup2); + free(path); +}