diff --git a/Changes b/Changes index a6df12e74..dd83cbf1f 100644 --- a/Changes +++ b/Changes @@ -2932,3 +2932,5 @@ seen. gmtime warning still there instead of 8 are supported for m_tkl (used by spamfilter add). This new system needs some testing... :) - Fixed a bug in 'Flood from unknown connection' (#0001566). +- Rewrote a great deal of the remote include code to make it work on Windows + due to Microsoft insanity. diff --git a/include/h.h b/include/h.h index 589b248b8..e582ac5d0 100644 --- a/include/h.h +++ b/include/h.h @@ -635,6 +635,8 @@ extern int count_oper_sessions(char *); extern char *unreal_mktemp(char *dir, char *suffix); extern char *unreal_getfilename(char *path); extern int unreal_copyfile(char *src, char *dest); +extern time_t unreal_getfilemodtime(char *filename); +extern void unreal_setfilemodtime(char *filename, time_t mtime); extern void DeleteTempModules(void); extern Extban *extbaninfo; extern Extban *findmod_by_bantype(char c); diff --git a/makefile.win32 b/makefile.win32 index cf09cbc9d..ea21d547e 100644 --- a/makefile.win32 +++ b/makefile.win32 @@ -13,12 +13,12 @@ RC=rc # # #To enable remote includes uncomment the next line: -#USE_REMOTEINC=1 +USE_REMOTEINC=1 # #If your libcurl library and include files are not in your compiler's #default locations, specify the locations here: -#LIBCURL_INC_DIR="c:\dev\curl\include" -#LIBCURL_LIB_DIR="c:\dev\curl\lib" +LIBCURL_INC_DIR="c:\dev\curl\include" +LIBCURL_LIB_DIR="c:\dev\curl\lib" # # ### END REMOTE INCLUDES ## diff --git a/src/modules.c b/src/modules.c index 8b237eb8d..b0b923c4d 100644 --- a/src/modules.c +++ b/src/modules.c @@ -82,10 +82,10 @@ void *obsd_dlsym(void *handle, char *symbol) { void DeleteTempModules(void) { + char tempbuf[PATH_MAX+1]; #ifndef _WIN32 DIR *fd = opendir("tmp"); struct dirent *dir; - char tempbuf[PATH_MAX+1]; if (!fd) /* Ouch.. this is NOT good!! */ { @@ -105,7 +105,28 @@ void DeleteTempModules(void) remove(tempbuf); } closedir(fd); -#endif +#else + WIN32_FIND_DATA hData; + HANDLE hFile = FindFirstFile("tmp/*", &hData); + if (hFile != INVALID_HANDLE_VALUE) + { + if (strcmp(hData.cFileName, ".") || strcmp(hData.cFileName, "..")) + { + strcpy(tempbuf, "tmp/"); + strcat(tempbuf, hData.cFileName); + remove(tempbuf); + } + } + while (FindNextFile(hFile, &hData)) + { + if (!strcmp(hData.cFileName, ".") || !strcmp(hData.cFileName, "..")) + continue; + strcpy(tempbuf, "tmp/"); + strcat(tempbuf, hData.cFileName); + remove(tempbuf); + } + FindClose(hFile); +#endif } void Module_Init(void) diff --git a/src/s_conf.c b/src/s_conf.c index 27a9a3103..38e3b110f 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -1461,9 +1461,9 @@ int init_conf(char *rootconf, int rehash) #endif unload_loaded_includes(); } + load_includes(); #ifndef STATIC_LINKING Init_all_testing_modules(); - load_includes(); #else if (!rehash) { ModuleInfo ModCoreInfo; @@ -7253,7 +7253,7 @@ int rehash(aClient *cptr, aClient *sptr, int sig) sendto_one(sptr, ":%s NOTICE %s :A rehash is already in progress", me.name, sptr->name); return 0; - } + } loop.ircd_rehashing = 1; loop.rehash_save_cptr = cptr; @@ -7261,15 +7261,16 @@ int rehash(aClient *cptr, aClient *sptr, int sig) loop.rehash_save_sig = sig; for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next) { - struct stat sb; + time_t modtime; if (!(inc->flag.type & INCLUDE_REMOTE)) continue; + if (inc->flag.type & INCLUDE_NOTLOADED) continue; found_remote = 1; - stat(inc->file, &sb); - download_file_async(inc->url, sb.st_ctime, conf_download_complete); + modtime = unreal_getfilemodtime(inc->file); inc->flag.type |= INCLUDE_DLQUEUED; + download_file_async(inc->url, modtime, conf_download_complete); } if (!found_remote) return rehash_internal(cptr, sptr, sig); @@ -7352,6 +7353,21 @@ char *find_remote_include(char *url) return NULL; } +char *find_loaded_remote_include(char *url) +{ + ConfigItem_include *inc; + for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next) + { + if ((inc->flag.type & INCLUDE_NOTLOADED)) + continue; + if (!(inc->flag.type & INCLUDE_REMOTE)) + continue; + if (!stricmp(url, inc->url)) + return inc->file; + } + return NULL; +} + int remote_include(ConfigEntry *ce) { char *file = find_remote_include(ce->ce_vardata); diff --git a/src/support.c b/src/support.c index ea9507616..0c8df622d 100644 --- a/src/support.c +++ b/src/support.c @@ -28,15 +28,17 @@ static char sccsid[] = "@(#)support.c 2.21 4/13/94 1990, 1991 Armin Gruner;\ #include "sys.h" #include "version.h" #include "h.h" +#include +#include #include #ifdef _WIN32 #include #else #include -#include -#include +#include extern int errno; /* ...seems that errno.h doesn't define this everywhere */ #endif + extern void outofmemory(); #define is_enabled match @@ -1738,17 +1740,25 @@ char *unreal_getfilename(char *path) */ int unreal_copyfile(char *src, char *dest) { -#ifndef _WIN32 char buf[2048]; + time_t mtime = unreal_getfilemodtime(src); + +#ifndef _WIN32 int srcfd = open(src, O_RDONLY); +#else + int srcfd = open(src, _O_RDONLY); +#endif int destfd; int len; if (srcfd < 0) return 0; +#ifndef _WIN32 destfd = open(dest, O_WRONLY|O_CREAT, DEFAULT_PERMISSIONS); - +#else + destfd = open(dest, _O_WRONLY|_O_CREAT, _S_IWRITE); +#endif if (destfd < 0) { config_error("Unable to create file '%s': %s", dest, strerror(ERRNO)); @@ -1771,6 +1781,7 @@ int unreal_copyfile(char *src, char *dest) close(srcfd); close(destfd); + unreal_setfilemodtime(dest, mtime); #if defined(IRC_UID) && defined(IRC_GID) if (!loop.ircd_booted) chown(dest, IRC_UID, IRC_GID); @@ -1781,7 +1792,61 @@ fail: close(destfd); unlink(dest); /* make sure our corrupt file isn't used */ return 0; +} + +void unreal_setfilemodtime(char *filename, time_t mtime) +{ +#ifndef _WIN32 + struct utimbuf utb; + utb.actime = utb.modtime = mtime; + utime(filename, &utb); #else - return 0; + FILETIME mTime; + LONGLONG llValue; + HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return; + llValue = Int32x32To64(mtime, 10000000) + 116444736000000000; + mTime.dwLowDateTime = (long)llValue; + mTime.dwHighDateTime = llValue >> 32; + + SetFileTime(hFile, &mTime, &mTime, &mTime); + CloseHandle(hFile); +#endif +} + +time_t unreal_getfilemodtime(char *filename) +{ +#ifndef _WIN32 + struct stat sb; + if (stat(filename, &sb)) + return 0; + return sb.st_ctime; +#else + /* See how much more fun WinAPI programming is??? */ + FILETIME cTime; + SYSTEMTIME sTime, lTime; + ULARGE_INTEGER fullTime; + time_t result; + HANDLE hFile = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return 0; + if (!GetFileTime(hFile, NULL, NULL, &cTime)) + return 0; + + CloseHandle(hFile); + + FileTimeToSystemTime(&cTime, &sTime); + SystemTimeToTzSpecificLocalTime(NULL, &sTime, &lTime); + SystemTimeToFileTime(&sTime, &cTime); + + fullTime.LowPart = cTime.dwLowDateTime; + fullTime.HighPart = cTime.dwHighDateTime; + fullTime.QuadPart -= 116444736000000000; + fullTime.QuadPart /= 10000000; + + return fullTime.LowPart; #endif } diff --git a/src/url.c b/src/url.c index b848bfcf8..b7498fa09 100644 --- a/src/url.c +++ b/src/url.c @@ -24,7 +24,6 @@ #include #include #include -#include #ifdef USE_SSL extern char *SSLKeyPasswd; @@ -167,6 +166,8 @@ char *download_file(char *url, char **error) curl_easy_setopt(curl, CURLOPT_WRITEDATA, fd); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, do_download); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); + curl_easy_setopt(curl, CURLOPT_FILETIME, 1); + #ifdef USE_SSL set_curl_ssl_options(curl); #endif @@ -182,7 +183,15 @@ char *download_file(char *url, char **error) free(file); curl_easy_cleanup(curl); if (res == CURLE_OK) + { + long last_mod; + + curl_easy_getinfo(curl, CURLINFO_FILETIME, &last_mod); + + if (last_mod != -1) + unreal_setfilemodtime(tmp, last_mod); return strdup(tmp); + } else { remove(tmp); @@ -218,12 +227,11 @@ void download_file_async(char *url, time_t cachetime, vFP callback) { static char errorbuf[CURL_ERROR_SIZE]; CURL *curl = curl_easy_init(); - if (curl) { - char *file = url_getfilename(url); + char *file = url_getfilename(url); char *filename = unreal_getfilename(file); - char *tmp = unreal_mktemp("tmp", filename ? filename : "download.conf"); + char *tmp = unreal_mktemp("tmp", filename ? filename : "download.conf"); FileHandle *handle = malloc(sizeof(FileHandle)); handle->fd = fopen(tmp, "wb"); if (!handle->fd) @@ -250,9 +258,9 @@ void download_file_async(char *url, time_t cachetime, vFP callback) bzero(handle->errorbuf, CURL_ERROR_SIZE); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, handle->errorbuf); curl_easy_setopt(curl, CURLOPT_PRIVATE, (char *)handle); + curl_easy_setopt(curl, CURLOPT_FILETIME, 1); if (cachetime) { - curl_easy_setopt(curl, CURLOPT_FILETIME, 1); curl_easy_setopt(curl, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); curl_easy_setopt(curl, CURLOPT_TIMEVALUE, cachetime); } @@ -322,9 +330,15 @@ void url_do_transfers_async(void) { handle->callback(url, NULL, NULL, 1); remove(handle->filename); + } else + { + if (last_mod != -1) + unreal_setfilemodtime(handle->filename, last_mod); + handle->callback(url, handle->filename, NULL, 0); + } } else { diff --git a/src/win32/Win32GUI.c b/src/win32/Win32GUI.c index dd08ef57c..8f081b898 100644 --- a/src/win32/Win32GUI.c +++ b/src/win32/Win32GUI.c @@ -115,6 +115,10 @@ HMENU hContext; OSVERSIONINFO VerInfo; char OSName[256]; HWND hFind; +#ifdef USE_LIBCURL +extern char *find_loaded_remote_include(char *url); +#endif + void TaskBarCreated() { HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0); SysTray.cbSize = sizeof(NOTIFYICONDATA); @@ -737,6 +741,8 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs; if (conf_include) { ConfigItem_include *inc; for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next) { + if (inc->flag.type & INCLUDE_NOTLOADED) + continue; #ifdef USE_LIBCURL if (inc->flag.type & INCLUDE_REMOTE) AppendMenu(hConfig, MF_STRING, i++, inc->url); @@ -890,7 +896,7 @@ static HMENU hRehash, hAbout, hConfig, hTray, hLogs; #ifdef USE_LIBCURL if (url_is_valid(path)) { - char *file = find_remote_include(path); + char *file = find_loaded_remote_include(path); DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)file); } else