X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/3292ba8bb8e85babc44cb4f831f9b758089f1cfc..2f0aeb51af00c098bdcd016d2fe34c62dd2b74f0:/src/download.c?ds=sidebyside diff --git a/src/download.c b/src/download.c index e23e7863..27b123f2 100644 --- a/src/download.c +++ b/src/download.c @@ -24,100 +24,125 @@ #endif #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "download.h" -#ifdef HAVE_LIBCURL #include "curl_download.h" -#else -#include "http.h" -#endif - -#ifdef WINDOWS - -#include -#define access(a,b) _access(a,b) -#define close(a) closesocket(a) -char *dirname ( char * dir ) +gboolean a_check_html_file(FILE* f) { - char *tmp = dir + strlen(dir) - 1; - while ( tmp != dir && *tmp != '\\' ) - tmp--; - *tmp = '\0'; - return dir; + gchar **s; + gchar *bp; + fpos_t pos; + gchar buf[33]; + size_t nr; + gchar * html_str[] = { + " (bp - buf)); bp++) { + if (!(isspace(*bp))) + break; + } + if ((bp >= (buf + sizeof(buf) -1)) || ((bp - buf) >= nr)) + return FALSE; + for (s = html_str; *s; s++) { + if (strncasecmp(*s, bp, strlen(*s)) == 0) + return TRUE; + } + return FALSE; } -#else - -#include -#include - -/* dirname */ -#include - -#endif +gboolean a_check_map_file(FILE* f) +{ + return !a_check_html_file(f); +} -static int download( const char *hostname, const char *uri, const char *fn, int sendhostname) +static int download( const char *hostname, const char *uri, const char *fn, DownloadOptions *options, gboolean ftp) { FILE *f; int ret; + gchar *tmpfilename; + gboolean failure = FALSE; /* Check file */ - if ( access ( fn, F_OK ) == 0 ) + if ( g_file_test ( fn, G_FILE_TEST_EXISTS ) == TRUE ) { /* File exists: return */ return -3; } else { - if ( errno == ENOENT) - { - char *tmp = g_strdup ( fn ); -#ifdef WINDOWS - mkdir( dirname ( dirname ( tmp ) ) ); - g_free ( tmp ); tmp = g_strdup ( fn ); - mkdir( dirname ( tmp ) ); -#else - mkdir( dirname ( dirname ( tmp ) ), 0777 ); - g_free ( tmp ); tmp = g_strdup ( fn ); - mkdir( dirname ( tmp ), 0777 ); -#endif - g_free ( tmp ); - } - if ( ! (f = fopen ( fn, "w+b" )) ) /* immediately open file so other threads won't -- prevents race condition */ + gchar *dir = g_path_get_dirname ( fn ); + g_mkdir_with_parents ( dir , 0777 ); + g_free ( dir ); + + /* create placeholder file */ + if ( ! (f = g_fopen ( fn, "w+b" )) ) /* immediately open file so other threads won't -- prevents race condition */ return -4; + fclose ( f ); + f = NULL; + } + + tmpfilename = g_strdup_printf("%s.tmp", fn); + f = g_fopen ( tmpfilename, "w+b" ); + if ( ! f ) { + g_free ( tmpfilename ); + g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ + return -4; } /* Call the backend function */ -#ifdef HAVE_LIBCURL - ret = curl_download_get_url ( hostname, uri, f ); -#else - ret = http_download_get_url ( hostname, uri, f, 0, sendhostname ); -#endif + ret = curl_download_get_url ( hostname, uri, f, options, ftp ); + if (ret == -1 || ret == 1 || ret == -2) { + g_debug("%s: download failed: curl_download_get_url=%d", __FUNCTION__, ret); + failure = TRUE; + } + + if (!failure && options != NULL && options->check_file != NULL && ! options->check_file(f)) { + g_debug("%s: file content checking failed", __FUNCTION__); + failure = TRUE; + } - if (ret == -1 || ret == 1 || ret == -2) + if (failure) { + g_warning(_("Download error: %s"), fn); fclose ( f ); - remove ( fn ); + f = NULL; + g_remove ( tmpfilename ); + g_free ( tmpfilename ); + g_remove ( fn ); /* couldn't create temporary. delete 0-byte file. */ return -1; } fclose ( f ); + f = NULL; + g_rename ( tmpfilename, fn ); /* move completely-downloaded file to permanent location */ + g_free ( tmpfilename ); return ret; } /* 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 ) +int a_http_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ) { - return download ( hostname, uri, fn, 1 ); + return download ( hostname, uri, fn, opt, FALSE ); } -int a_http_download_get_url_nohostname ( const char *hostname, const char *uri, const char *fn ) +int a_ftp_download_get_url ( const char *hostname, const char *uri, const char *fn, DownloadOptions *opt ) { - return download ( hostname, uri, fn, 0 ); + return download ( hostname, uri, fn, opt, TRUE ); }