X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/f83131b9214303509234021bcf5cff939d4ce2c7..01709fe4e9fa57f256a22a4f87124ba0fb03dcfa:/src/download.c diff --git a/src/download.c b/src/download.c index 3063bfa5..1c7711b9 100644 --- a/src/download.c +++ b/src/download.c @@ -24,59 +24,35 @@ #endif #include -#include #include +#include #include -#include -#include +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_UTIME_H +#include +#endif #include #include #include + #include "download.h" #include "curl_download.h" +#include "preferences.h" +#include "globals.h" -#ifdef WINDOWS - -#include -#define close(a) closesocket(a) - -char *dirname ( char * dir ) +static gboolean check_file_first_line(FILE* f, gchar *patterns[]) { - char *tmp = dir + strlen(dir) - 1; - while ( tmp != dir && *tmp != '\\' ) - tmp--; - *tmp = '\0'; - return dir; -} - -#else - - -/* dirname */ -#include - -#endif - -static int check_map_file(FILE* f) -{ - char **s; - char *bp; - int res = 0; /* good */ + gchar **s; + gchar *bp; fpos_t pos; - char buf[33]; + gchar buf[33]; size_t nr; - char * html_str[] = { - "= (buf + sizeof(buf) -1)) || ((bp - buf) >= nr)) - return(res); - for (s = html_str; *s; s++) { + return FALSE; + for (s = patterns; *s; s++) { if (strncasecmp(*s, bp, strlen(*s)) == 0) - return(-1); + return TRUE; } - return(res); + return FALSE; +} + +gboolean a_check_html_file(FILE* f) +{ + gchar * html_str[] = { + "check_file_server_time) { + time_t tile_age = a_preferences_get(VIKING_PREFERENCES_NAMESPACE "download_tile_age")->u; + /* Get the modified time of this file */ + struct stat buf; + g_stat ( fn, &buf ); + time_condition = buf.st_mtime; + if ( (time(NULL) - time_condition) < tile_age ) + /* File cache is too recent, so return */ + return -3; + } else { + /* Nothing to do as file already exists, so return */ + return -3; } - /* create placeholder file */ - if ( ! (f = fopen ( fn, "w+b" )) ) /* immediately open file so other threads won't -- prevents race condition */ - return -4; - fclose ( f ); + } else { + gchar *dir = g_path_get_dirname ( fn ); + g_mkdir_with_parents ( dir , 0777 ); + g_free ( dir ); } tmpfilename = g_strdup_printf("%s.tmp", fn); - f = fopen ( tmpfilename, "w+b" ); + if (!lock_file ( tmpfilename ) ) + { + g_debug("%s: Couldn't take lock on temporary file \"%s\"\n", __FUNCTION__, tmpfilename); + g_free ( tmpfilename ); + return -4; + } + f = g_fopen ( tmpfilename, "w+b" ); /* truncate file and open it */ if ( ! f ) { + g_warning("Couldn't open temporary file \"%s\": %s", tmpfilename, g_strerror(errno)); g_free ( tmpfilename ); - remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ return -4; } /* Call the backend function */ - ret = curl_download_get_url ( hostname, uri, f, options, ftp ); + ret = curl_download_get_url ( hostname, uri, f, options, ftp, time_condition, handle ); + + if (ret != DOWNLOAD_NO_ERROR && ret != DOWNLOAD_NO_NEWER_FILE) { + g_debug("%s: download failed: curl_download_get_url=%d", __FUNCTION__, ret); + failure = TRUE; + } - if (ret == -1 || ret == 1 || ret == -2 || check_map_file(f)) + if (!failure && options != NULL && options->check_file != NULL && ! options->check_file(f)) { + g_debug("%s: file content checking failed", __FUNCTION__); + failure = TRUE; + } + + fclose ( f ); + f = NULL; + + if (failure) { g_warning(_("Download error: %s"), fn); - fclose ( f ); - remove ( tmpfilename ); + g_remove ( tmpfilename ); + unlock_file ( tmpfilename ); g_free ( tmpfilename ); - remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ + g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ return -1; } - fclose ( f ); - rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */ + if (ret == DOWNLOAD_NO_NEWER_FILE) { + g_remove ( tmpfilename ); +#if GLIB_CHECK_VERSION(2,18,0) + g_utime ( fn, NULL ); /* update mtime of local copy */ +#else + utimes ( fn, NULL ); /* update mtime of local copy */ +#endif + } else + g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */ + unlock_file ( tmpfilename ); g_free ( tmpfilename ); - return ret; + + return 0; } /* success = 0, -1 = couldn't connect, -2 HTTP error, -3 file exists, -4 couldn't write to file... */ /* uri: like "/uri.html?whatever" */ /* only reason for the "wrapper" is so we can do redirects. */ -int a_http_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ) +int a_http_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt, void *handle ) +{ + return download ( hostname, uri, fn, opt, FALSE, handle ); +} + +int a_ftp_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt, void *handle ) +{ + return download ( hostname, uri, fn, opt, TRUE, handle ); +} + +void * a_download_handle_init () { - return download ( hostname, uri, fn, opt, FALSE ); + return curl_download_handle_init (); } -int a_ftp_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ) +void a_download_handle_cleanup ( void *handle ) { - return download ( hostname, uri, fn, opt, TRUE ); + curl_download_handle_cleanup ( handle ); }