From: J. Ali Harlow Date: Thu, 9 Oct 2014 16:27:41 +0000 (+0100) Subject: Support downloading from local repository even without libcurl X-Git-Tag: 0.6~8 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=8802fc72ca7a6b8f88382e9b74ba760f1c0512c2;p=razor.git Support downloading from local repository even without libcurl Using the --url option of the razor executable, it is possible to specify a yum repository on the local machine (eg., on installation media) and import from there, eg.,: C> razor --url file:///d:/ import-yum This will be handled by libcurl if available but if not, an internal copy routine will be used. Note that if Microsoft's KTM implementation of atomic transactions is used, then the current directory must support atomic transactions (also improve error messages for this, and other, cases). --- diff --git a/Makefile.am b/Makefile.am index 076084c..5558330 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,6 +4,8 @@ SUBDIRS = data docs gl librazor src test po ACLOCAL_AMFLAGS = -I gl/m4 +DISTCHECK_CONFIGURE_FLAGS = --enable-tests + # Creating ChangeLog from git log (taken from cairo/Makefile.am): ChangeLog: $(srcdir)/ChangeLog diff --git a/configure.ac b/configure.ac index 259d5f0..e201f36 100644 --- a/configure.ac +++ b/configure.ac @@ -72,11 +72,18 @@ else AC_SUBST([RAZOR_HAVE_ATOMIC_ROLLBACK],['#undef RAZOR_HAVE_ATOMIC_ROLLBACK']) fi +AC_ARG_ENABLE([tests], + [AS_HELP_STRING([--enable-tests], + [install test programs])], + [], + [enable_tests=no]) +AM_CONDITIONAL(INSTALL_TEST_PROGRAMS, test "$enable_tests" = "yes") + AC_MSG_CHECKING([for Microsoft Windows native API]) case $host_os in *mingw*) AC_DEFINE([MSWIN_API], 1, [Define to 1 to use Microsoft Windows native API.]) - EXTRA_LIBS='-lshell32 -lws2_32' + EXTRA_LIBS='-lshlwapi -lshell32 -lws2_32' mswin_api=yes;; *) mswin_api=no;; esac diff --git a/librazor/Makefile.am b/librazor/Makefile.am index a25a05c..b800570 100644 --- a/librazor/Makefile.am +++ b/librazor/Makefile.am @@ -14,8 +14,13 @@ INCLUDES = \ -DPACKAGE_LIB_DIR=\""$(libdir)"\" lib_LTLIBRARIES = librazor.la +check_PROGRAMS = test-pfu if HAVE_LUA - check_PROGRAMS = test-lua + check_PROGRAMS += test-lua +endif + +if INSTALL_TEST_PROGRAMS + bin_PROGRAMS = $(check_PROGRAMS) endif librazorincludedir = $(includedir)/razor @@ -29,6 +34,7 @@ librazor_la_SOURCES = \ razor.c \ root.c \ util.c \ + path.c \ rpm.c \ iterator.c \ importer.c \ @@ -50,12 +56,18 @@ librazor_la_LIBADD = $(ZLIB_LIBS) types/libtypes.la $(LUA_LIBS) \ librazor_la_LDFLAGS = -no-undefined -export-symbols-regex '^razor_' \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) +test_pfu_SOURCES = test-pfu.c +test_pfu_LDADD = path.lo util.lo error.lo types/libtypes.la \ + ../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS) + +TESTS = test-pfu + if HAVE_LUA test_lua_SOURCES = test-lua.c test_lua_LDADD = lua.lo util.lo error.lo types/libtypes.la $(LUA_LIBS) \ ../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS) - TESTS = test-lua + TESTS += test-lua endif EXTRA_DIST = \ diff --git a/librazor/error.c b/librazor/error.c index 24a00c5..65d512d 100644 --- a/librazor/error.c +++ b/librazor/error.c @@ -20,6 +20,9 @@ #ifdef MSWIN_API #include +#ifndef ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED +#define ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED 6832L +#endif #endif #include #include @@ -129,12 +132,28 @@ razor_error_new_mswin(const wchar_t *object, DWORD err) if (object) error->object = razor_utf16_to_utf8(object, -1); - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER| - FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), - (LPWSTR)&buf, 0, NULL); - error->str = razor_utf16_to_utf8(buf, -1); - LocalFree(buf); + switch(err) { + case ERROR_TRANSACTIONAL_OPEN_NOT_ALLOWED: + /* + * Attempting to include files in a transaction on a filesystem + * that doesn't support them (only NTFS?) produces this error + * for which the default text isn't very informative. Try and + * give more useful information. + */ + error->str = strdup("Not allowed (perhaps the filesystem " + "doesn't support transactions)"); + break; + default: + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER| + FORMAT_MESSAGE_FROM_SYSTEM| + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (LPWSTR)&buf, 0, NULL); + error->str = razor_utf16_to_utf8(buf, -1); + LocalFree(buf); + break; + } return error; } diff --git a/librazor/test-lua.c b/librazor/test-lua.c index fc194b4..54bb947 100644 --- a/librazor/test-lua.c +++ b/librazor/test-lua.c @@ -91,8 +91,8 @@ int main(int argc, char *argv[]) } fprintf(fp, "#!" LUA_BINARY "\n" "print('Abracadabra!')\n"); - fchmod(fileno(fp), S_IRUSR | S_IWUSR | S_IXUSR); fclose(fp); + chmod(s, S_IRUSR | S_IWUSR | S_IXUSR); free(s); script = razor_file_get_contents(test_file, &len, 0, &error); diff --git a/librazor/types/Makefile.am b/librazor/types/Makefile.am index 9cbd771..9e89a23 100644 --- a/librazor/types/Makefile.am +++ b/librazor/types/Makefile.am @@ -4,6 +4,10 @@ noinst_LTLIBRARIES = libtypes.la check_PROGRAMS = test-hashtable test-graph test-deque LDADD = libtypes.la +if INSTALL_TEST_PROGRAMS + bin_PROGRAMS = $(check_PROGRAMS) +endif + libtypes_la_SOURCES = \ array.c \ deque.c \ diff --git a/librazor/util.c b/librazor/util.c index b9994ae..b640939 100644 --- a/librazor/util.c +++ b/librazor/util.c @@ -344,24 +344,6 @@ RAZOR_EXPORT char *razor_concat(const char *s, ...) return concat; } -/** - * razor_path_add_root: - * - * Adds a root to a path. path must be an absolute pathname. In POSIX - * environments this is equivalent to the concationation of root and path. - * In Microsoft Windows an adjustment may need to be made for a drive letter - * in path (which will be dropped). - * - * Returns: The new pathname. - **/ -RAZOR_EXPORT char *razor_path_add_root(const char *path, const char *root) -{ - if (root && *root) - return razor_concat(root, SKIP_DRIVE_LETTER(path), NULL); - else - return strdup(path); -} - RAZOR_EXPORT const char *razor_system_arch(void) { #ifdef MSWIN_API @@ -394,12 +376,15 @@ char *razor_utf16_to_utf8(const wchar_t *utf16, int len) int n; char *utf8; + if (len == 0) + return strdup(""); + n = WideCharToMultiByte(CP_UTF8, 0, utf16, len, NULL, 0, NULL, NULL); - if (len >= 0 && utf16[len]) + if (len > 0) n++; utf8 = malloc(n); (void)WideCharToMultiByte(CP_UTF8, 0, utf16, len, utf8, n, NULL, NULL); - if (len >= 0 && utf16[len]) + if (len > 0) utf8[n - 1] = 0; return utf8; @@ -410,12 +395,17 @@ wchar_t *razor_utf8_to_utf16(const char *utf8, int len) int n; wchar_t *utf16; + if (len == 0) { + utf16 = calloc(1, sizeof(wchar_t)); + return utf16; + } + n = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); - if (len >= 0 && utf8[len]) + if (len > 0) n++; utf16 = malloc(n * sizeof(wchar_t)); (void)MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, n); - if (len >= 0 && utf8[len]) + if (len > 0) utf16[n - 1] = 0; return utf16; diff --git a/src/Makefile.am b/src/Makefile.am index b87e29f..6820b2d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,6 +19,11 @@ bin_PROGRAMS = razor noinst_PROGRAMS = rpm check_PROGRAMS = test-driver +if INSTALL_TEST_PROGRAMS + bin_PROGRAMS = $(check_PROGRAMS) + pkgdata_DATA = test.xml +endif + razor_SOURCES = main.c import-yum.c if HAVE_RPMLIB razor_SOURCES += import-rpmdb.c diff --git a/src/import-yum.c b/src/import-yum.c index fd0aa43..34fd44c 100644 --- a/src/import-yum.c +++ b/src/import-yum.c @@ -311,11 +311,15 @@ razor_set_create_from_yum(void) yum_character_data); primary = gzopen("primary.xml.gz", "rb"); - if (primary == NULL) + if (primary == NULL) { + perror("primary.xml.gz"); return NULL; + } filelists = gzopen("filelists.xml.gz", "rb"); - if (filelists == NULL) + if (filelists == NULL) { + perror("filelists.xml.gz"); return NULL; + } ctx.current_parser = ctx.primary_parser; diff --git a/src/main.c b/src/main.c index aa116ba..5eb9e09 100644 --- a/src/main.c +++ b/src/main.c @@ -32,9 +32,16 @@ #include #include #include +#ifdef MSWIN_API +#include +#include +#endif #ifdef HAVE_CURL #include #endif +#if !defined(HAVE_CURL) && !defined(MSWIN_API) +#include +#endif #include #include #include @@ -607,6 +614,71 @@ command_what_provides(int argc, char * const argv[]) RAZOR_PROPERTY_PROVIDES); } +#ifndef HAVE_CURL +static int +download_local(const char *url, const char *file) +{ + FILE *wfp, *rfp; + char buffer[256], *ptr, *local; + size_t nb, n; + + local = razor_path_from_url(url); + + if (local == NULL) { + fprintf(stderr, + "%s: download manually (curl not available)\n", + file); + return -1; + } else { + rfp = fopen(local, "rb"); + if (rfp == NULL) { + perror(local); + free(local); + return -1; + } + + wfp = fopen(file, "wb"); + if (wfp == NULL) { + perror(file); + fclose(rfp); + free(local); + return -1; + } + + while((nb = fread(buffer, 1, sizeof(buffer), rfp)) > 0) { + ptr = buffer; + while (nb > 0 && (n = fwrite(ptr, 1, nb, wfp)) > 0) { + ptr += n; + nb -= n; + } + + if (nb != 0) { + perror(file); + fclose(wfp); + fclose(rfp); + unlink(file); + free(local); + return -1; + } + } + + if (ferror(rfp)) { + perror(local); + fclose(wfp); + fclose(rfp); + unlink(file); + free(local); + return -1; + } + + fclose(wfp); + fclose(rfp); + free(local); + return 0; + } +} +#endif /* !HAVE_CURL */ + #ifdef HAVE_CURL static int show_progress(void *clientp, @@ -620,65 +692,74 @@ show_progress(void *clientp, return 0; } -#endif /* HAVE_CURL */ static int -download_if_missing(const char *url, const char *file) +download_with_curl(const char *url, const char *file) { -#ifndef HAVE_CURL - return 1; -#else + FILE *fp; CURL *curl; - struct stat buf; char error[256]; - FILE *fp; CURLcode res; long response; curl = curl_easy_init(); - if (curl == NULL) - return 1; + if (curl == NULL) { + fprintf(stderr, + "%s: download manually (curl failed)\n", file); + return -1; + } curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file); - if (stat(file, &buf) < 0) { - fp = fopen(file, "wb"); - if (fp == NULL) { - fprintf(stderr, - "failed to open %s for writing\n", file); - return -1; - } - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - fclose(fp); - if (res != CURLE_OK) { - fprintf(stderr, "curl error: %s\n", error); - unlink(file); - return -1; - } - res = curl_easy_getinfo(curl, - CURLINFO_RESPONSE_CODE, &response); - if (res != CURLE_OK) { - fprintf(stderr, "curl error: %s\n", error); - unlink(file); - return -1; - } - if (response != 200) { - fprintf(stderr, " - failed %ld\n", response); - unlink(file); - return -1; - } - fprintf(stderr, "\n"); + fp = fopen(file, "wb"); + if (fp == NULL) { + perror(file); + return -1; } - + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_URL, url); + res = curl_easy_perform(curl); + fclose(fp); + if (res != CURLE_OK) { + fprintf(stderr, "curl error: %s\n", error); + unlink(file); + return -1; + } + res = curl_easy_getinfo(curl, + CURLINFO_RESPONSE_CODE, &response); + if (res != CURLE_OK) { + fprintf(stderr, "curl error: %s\n", error); + unlink(file); + return -1; + } + if (response != 200) { + fprintf(stderr, " - failed %ld\n", response); + unlink(file); + return -1; + } + fprintf(stderr, "\n"); curl_easy_cleanup(curl); return 0; +} #endif /* HAVE_CURL */ + +static int +download_if_missing(const char *url, const char *file) +{ + struct stat buf; + + if (stat(file, &buf) >= 0) + return 0; + +#ifndef HAVE_CURL + return download_local(url, file); +#else + return download_with_curl(url, file); +#endif } #define YUM_URL "http://download.fedora.redhat.com" \ @@ -704,7 +785,7 @@ command_import_yum(int argc, char * const argv[]) return 1; } - printf("downloading from %s.\n", yum_url); + printf("downloading from '%s'.\n", yum_url); snprintf(buffer, sizeof buffer, "%s/repodata/primary.xml.gz", yum_url); if (download_if_missing(buffer, "primary.xml.gz") < 0) @@ -1450,7 +1531,6 @@ command_install_or_update(int argc, char * const argv[], int do_update) razor_transaction_destroy(trans); razor_set_unref(upstream); razor_root_close(root); - razor_atomic_destroy(atomic); if (relocations) razor_relocations_destroy(relocations); return 1;