# HG changeset patch # User J. Ali Harlow # Date 1412872061 -3600 # Node ID df914f383f5c20d2c60925a741d6132f1bd52276 # Parent 56ff755c268cf21322b7d6ec0cd4dd592a6388fa 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 -r 56ff755c268c -r df914f383f5c Makefile.am --- a/Makefile.am Sat Oct 04 18:12:58 2014 +0100 +++ b/Makefile.am Thu Oct 09 17:27:41 2014 +0100 @@ -4,6 +4,8 @@ ACLOCAL_AMFLAGS = -I gl/m4 +DISTCHECK_CONFIGURE_FLAGS = --enable-tests + # Creating ChangeLog from git log (taken from cairo/Makefile.am): ChangeLog: $(srcdir)/ChangeLog diff -r 56ff755c268c -r df914f383f5c configure.ac --- a/configure.ac Sat Oct 04 18:12:58 2014 +0100 +++ b/configure.ac Thu Oct 09 17:27:41 2014 +0100 @@ -72,11 +72,18 @@ 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 -r 56ff755c268c -r df914f383f5c librazor/Makefile.am --- a/librazor/Makefile.am Sat Oct 04 18:12:58 2014 +0100 +++ b/librazor/Makefile.am Thu Oct 09 17:27:41 2014 +0100 @@ -14,8 +14,13 @@ -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 @@ razor.c \ root.c \ util.c \ + path.c \ rpm.c \ iterator.c \ importer.c \ @@ -50,12 +56,18 @@ 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 -r 56ff755c268c -r df914f383f5c librazor/error.c --- a/librazor/error.c Sat Oct 04 18:12:58 2014 +0100 +++ b/librazor/error.c Thu Oct 09 17:27:41 2014 +0100 @@ -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 @@ 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 -r 56ff755c268c -r df914f383f5c librazor/test-lua.c --- a/librazor/test-lua.c Sat Oct 04 18:12:58 2014 +0100 +++ b/librazor/test-lua.c Thu Oct 09 17:27:41 2014 +0100 @@ -91,8 +91,8 @@ } 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 -r 56ff755c268c -r df914f383f5c librazor/types/Makefile.am --- a/librazor/types/Makefile.am Sat Oct 04 18:12:58 2014 +0100 +++ b/librazor/types/Makefile.am Thu Oct 09 17:27:41 2014 +0100 @@ -4,6 +4,10 @@ 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 -r 56ff755c268c -r df914f383f5c librazor/util.c --- a/librazor/util.c Sat Oct 04 18:12:58 2014 +0100 +++ b/librazor/util.c Thu Oct 09 17:27:41 2014 +0100 @@ -344,24 +344,6 @@ 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 @@ 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 @@ 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 -r 56ff755c268c -r df914f383f5c src/Makefile.am --- a/src/Makefile.am Sat Oct 04 18:12:58 2014 +0100 +++ b/src/Makefile.am Thu Oct 09 17:27:41 2014 +0100 @@ -19,6 +19,11 @@ 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 -r 56ff755c268c -r df914f383f5c src/import-yum.c --- a/src/import-yum.c Sat Oct 04 18:12:58 2014 +0100 +++ b/src/import-yum.c Thu Oct 09 17:27:41 2014 +0100 @@ -311,11 +311,15 @@ 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 -r 56ff755c268c -r df914f383f5c src/main.c --- a/src/main.c Sat Oct 04 18:12:58 2014 +0100 +++ b/src/main.c Thu Oct 09 17:27:41 2014 +0100 @@ -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 @@ 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 @@ 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 @@ 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 @@ razor_transaction_destroy(trans); razor_set_unref(upstream); razor_root_close(root); - razor_atomic_destroy(atomic); if (relocations) razor_relocations_destroy(relocations); return 1;