1.1 --- a/configure.ac Mon Jul 04 10:48:18 2016 +0100
1.2 +++ b/configure.ac Mon Jul 04 13:04:19 2016 +0100
1.3 @@ -205,6 +205,25 @@
1.4 AC_MSG_RESULT($have_gcc4)
1.5
1.6 REQUIREMENTS=""
1.7 +AC_ARG_WITH([libarchive],
1.8 + [AS_HELP_STRING([--without-libarchive],
1.9 + [disable support for libarchive])],
1.10 + [],
1.11 + [with_libarchive=yes])
1.12 +
1.13 +LIBARCHIVE_CFLAGS=
1.14 +LIBARCHIVE_LIBS=
1.15 +AS_IF([test "x$with_libarchive" != xno],
1.16 + [PKG_CHECK_MODULES(LIBARCHIVE, [libarchive])
1.17 + REQUIREMENTS="$REQUIREMENTS libarchive"
1.18 + AC_DEFINE([HAVE_LIBARCHIVE], [1], [Define if you have libarchive])])
1.19 +AC_SUBST(LIBARCHIVE_CFLAGS)
1.20 +AC_SUBST(LIBARCHIVE_LIBS)
1.21 +
1.22 +AS_IF([test "x$with_libarchive" != xno],
1.23 + [AC_PATH_PROG(ZIP, [zip], [])])
1.24 +AM_CONDITIONAL([HAVE_ZIP], [test -n "$ZIP"])
1.25 +
1.26 AC_ARG_WITH([curl],
1.27 [AS_HELP_STRING([--without-curl], [disable support for curl])],
1.28 [],
1.29 @@ -217,6 +236,7 @@
1.30 AC_DEFINE([HAVE_CURL], [1], [Define if you have curl])])
1.31 AC_SUBST(CURL_CFLAGS)
1.32 AC_SUBST(CURL_LIBS)
1.33 +AM_CONDITIONAL([HAVE_CURL], [test "x$with_curl" != xno])
1.34
1.35 ZLIB_LIBS=""
1.36 AC_ARG_WITH(zlib, [ --with-zlib=<dir> Use zlib from here],
2.1 --- a/librazor/Makefile.am Mon Jul 04 10:48:18 2016 +0100
2.2 +++ b/librazor/Makefile.am Mon Jul 04 13:04:19 2016 +0100
2.3 @@ -55,8 +55,8 @@
2.4 librazor_la_SOURCES += lua.c
2.5 endif
2.6
2.7 -librazor_la_LIBADD = $(ZLIB_LIBS) types/libtypes.la $(LUA_LIBS) \
2.8 - ../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS)
2.9 +librazor_la_LIBADD = $(LIBARCHIVE_LIBS) $(ZLIB_LIBS) types/libtypes.la \
2.10 + $(LUA_LIBS) ../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS)
2.11 librazor_la_LDFLAGS = -no-undefined -export-symbols-regex '^razor_' \
2.12 -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
2.13
2.14 @@ -76,7 +76,8 @@
2.15 if HAVE_LUA
2.16 test_lua_SOURCES = test-lua.c
2.17 test_lua_LDADD = lua.lo uri.lo uri-io.lo util.lo path.lo error.lo \
2.18 - types/libtypes.la $(LUA_LIBS) ../gl/libgnu.la $(INTLLIBS) $(EXTRA_LIBS)
2.19 + types/libtypes.la $(LIBARCHIVE_LIBS) $(LUA_LIBS) ../gl/libgnu.la \
2.20 + $(INTLLIBS) $(EXTRA_LIBS)
2.21
2.22 TESTS += test-lua
2.23 endif
3.1 --- a/librazor/razor-internal.h Mon Jul 04 10:48:18 2016 +0100
3.2 +++ b/librazor/razor-internal.h Mon Jul 04 13:04:19 2016 +0100
3.3 @@ -257,22 +257,6 @@
3.4 char *razor_file_readdir(void *dir, struct razor_error **error);
3.5 int razor_file_closedir(void *dir, struct razor_error **error);
3.6
3.7 -int razor_uri_mkdir(const char *uri, mode_t mode, struct razor_error **error);
3.8 -int razor_uri_unlink(const char *uri, struct razor_error **error);
3.9 -int razor_uri_open(const char *uri, int flags, mode_t mode,
3.10 - struct razor_error **error);
3.11 -int razor_uri_move(const char *uri, const char *dest,
3.12 - struct razor_error **error);
3.13 -int razor_uri_is_directory(const char *uri, struct razor_error **error);
3.14 -char *razor_uri_mkdtemp_near(const char *uri, const char *template,
3.15 - struct razor_error **error) RAZOR_MALLOC;
3.16 -void *razor_uri_opendir(const char *uri, struct razor_error **error);
3.17 -char *razor_uri_readdir(void *dir, struct razor_error **error) RAZOR_MALLOC;
3.18 -int razor_uri_closedir(void *dir, struct razor_error **error);
3.19 -void *razor_uri_get_contents(const char *uri, size_t *length, int private,
3.20 - struct razor_error **error);
3.21 -int razor_uri_free_contents(void *addr, size_t length);
3.22 -
3.23 char *razor_path_from_parsed_uri(const struct razor_uri *ru,
3.24 struct razor_error **error);
3.25
4.1 --- a/librazor/razor.h.in Mon Jul 04 10:48:18 2016 +0100
4.2 +++ b/librazor/razor.h.in Mon Jul 04 13:04:19 2016 +0100
4.3 @@ -592,9 +592,6 @@
4.4
4.5 struct razor_set *razor_importer_finish(struct razor_importer *importer);
4.6
4.7 -struct razor_set *razor_set_create_from_yum(void);
4.8 -struct razor_set *razor_set_create_from_rpmdb(void);
4.9 -
4.10 /**
4.11 * SECTION:root
4.12 * @title: Root
4.13 @@ -650,6 +647,22 @@
4.14 int (*closedir)(void *dir, struct razor_error **error);
4.15 };
4.16
4.17 +int razor_uri_mkdir(const char *uri, mode_t mode, struct razor_error **error);
4.18 +int razor_uri_unlink(const char *uri, struct razor_error **error);
4.19 +int razor_uri_open(const char *uri, int flags, mode_t mode,
4.20 + struct razor_error **error);
4.21 +int razor_uri_move(const char *uri, const char *dest,
4.22 + struct razor_error **error);
4.23 +int razor_uri_is_directory(const char *uri, struct razor_error **error);
4.24 +char *razor_uri_mkdtemp_near(const char *uri, const char *_template,
4.25 + struct razor_error **error) RAZOR_MALLOC;
4.26 +void *razor_uri_opendir(const char *uri, struct razor_error **error);
4.27 +char *razor_uri_readdir(void *dir, struct razor_error **error) RAZOR_MALLOC;
4.28 +int razor_uri_closedir(void *dir, struct razor_error **error);
4.29 +void *razor_uri_get_contents(const char *uri, size_t *length, int _private,
4.30 + struct razor_error **error);
4.31 +int razor_uri_free_contents(void *addr, size_t length);
4.32 +
4.33 int razor_uri_set_vtable(const char *scheme, struct razor_uri_vtable *vtable,
4.34 struct razor_error **error);
4.35
4.36 @@ -680,7 +693,7 @@
4.37 char *razor_path_from_uri(const char *uri, struct razor_error **error)
4.38 RAZOR_MALLOC;
4.39 char *razor_path_to_uri(const char *path) RAZOR_MALLOC;
4.40 -char *razor_path_relative_to_uri(const char *file_uri, const char *path,
4.41 +char *razor_path_relative_to_uri(const char *uri, const char *path,
4.42 struct razor_error **error) RAZOR_MALLOC;
4.43
4.44 const char *razor_system_arch(void);
5.1 --- a/librazor/uri-io.c Mon Jul 04 10:48:18 2016 +0100
5.2 +++ b/librazor/uri-io.c Mon Jul 04 13:04:19 2016 +0100
5.3 @@ -38,6 +38,10 @@
5.4 #if HAVE_SYS_MMAN_H
5.5 #include <sys/mman.h>
5.6 #endif
5.7 +#if HAVE_LIBARCHIVE
5.8 +#include <archive.h>
5.9 +#include <archive_entry.h>
5.10 +#endif
5.11 #include <assert.h>
5.12
5.13 #include "razor.h"
5.14 @@ -51,6 +55,130 @@
5.15 #define strcmp0(s1, s2) ((s1) && (s2) ? strcmp(s1, s2) : \
5.16 (s1) ? 1 : (s2) ? -1 : 0)
5.17
5.18 +#if HAVE_LIBARCHIVE
5.19 +static void *
5.20 +razor_archive_get_file_contents(const char *filename, int fd, const char *path,
5.21 + size_t *length, struct razor_error **error)
5.22 +{
5.23 + int r;
5.24 + void *addr;
5.25 + const void *buf;
5.26 + size_t size;
5.27 + off_t offset;
5.28 + struct archive *a;
5.29 + struct archive_entry *entry;
5.30 +
5.31 + a = archive_read_new();
5.32 + archive_read_support_compression_all(a);
5.33 + archive_read_support_format_all(a);
5.34 +
5.35 + r = archive_read_open_fd(a, fd, 10240);
5.36 +
5.37 + if (r) {
5.38 + razor_set_error(error, RAZOR_POSIX_ERROR, archive_errno(a),
5.39 + filename, archive_error_string(a));
5.40 + archive_read_finish(a);
5.41 + return NULL;
5.42 + }
5.43 +
5.44 + for (;;) {
5.45 + r = archive_read_next_header(a, &entry);
5.46 + if (r == ARCHIVE_EOF)
5.47 + break;
5.48 + else if (r < ARCHIVE_WARN) {
5.49 + razor_set_error(error, RAZOR_POSIX_ERROR,
5.50 + archive_errno(a), filename,
5.51 + archive_error_string(a));
5.52 + archive_read_close(a);
5.53 + archive_read_finish(a);
5.54 + return NULL;
5.55 + }
5.56 +
5.57 + /*
5.58 + * TODO: Unicode support. Might need to wait for libarchive v4.
5.59 + */
5.60 + if (!strcmp(archive_entry_pathname(entry), path)) {
5.61 + addr = malloc(archive_entry_size(entry));
5.62 + if (!addr) {
5.63 + archive_read_close(a);
5.64 + archive_read_finish(a);
5.65 + razor_set_error(error, RAZOR_POSIX_ERROR,
5.66 + ENOMEM, NULL,
5.67 + "Not enough memory");
5.68 + return NULL;
5.69 + }
5.70 +
5.71 + for(;;) {
5.72 + r = archive_read_data_block(a, &buf, &size,
5.73 + &offset);
5.74 + if (r == ARCHIVE_EOF)
5.75 + break;
5.76 + if (r < ARCHIVE_OK) {
5.77 + razor_set_error(error, RAZOR_POSIX_ERROR,
5.78 + archive_errno(a), path,
5.79 + archive_error_string(a));
5.80 + free(addr);
5.81 + addr = NULL;
5.82 + break;
5.83 + }
5.84 + memcpy((char *)addr + offset, buf, size);
5.85 + }
5.86 +
5.87 + archive_read_close(a);
5.88 + archive_read_finish(a);
5.89 +
5.90 + return addr;
5.91 + }
5.92 + }
5.93 +
5.94 + archive_read_close(a);
5.95 + archive_read_finish(a);
5.96 +
5.97 + razor_set_error(error, RAZOR_POSIX_ERROR, ENOENT, path,
5.98 + "No such file or directory in archive");
5.99 +
5.100 + return NULL;
5.101 +}
5.102 +
5.103 +static void *
5.104 +razor_file_get_contents_archive(const char *filename, size_t *length,
5.105 + struct razor_error **error)
5.106 +{
5.107 + int fd;
5.108 + char *path, *slash, *s;
5.109 + void *addr;
5.110 +
5.111 + path = strdup(filename);
5.112 + slash = strrchr(path, '/');
5.113 +
5.114 + while (slash) {
5.115 + *slash = '\0';
5.116 + fd = open(path, O_RDONLY | O_BINARY);
5.117 + if (fd >= 0) {
5.118 + addr = razor_archive_get_file_contents(path, fd,
5.119 + slash + 1,
5.120 + length, error);
5.121 + free(path);
5.122 + close(fd);
5.123 + return addr;
5.124 + } else if (errno != ENOTDIR) {
5.125 + free(path);
5.126 + razor_set_error_posix(error, filename);
5.127 + return NULL;
5.128 + }
5.129 + s = strrchr(path, '/');
5.130 + *slash = '/';
5.131 + slash = s;
5.132 + }
5.133 +
5.134 + /* Impossible */
5.135 + free(path);
5.136 + razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR, filename,
5.137 + strerror(ENOTDIR));
5.138 + return NULL;
5.139 +}
5.140 +#endif
5.141 +
5.142 #define OPEN_FILE_USED (1U<<0)
5.143 #define OPEN_FILE_MMAPPED (1U<<1)
5.144
5.145 @@ -68,24 +196,33 @@
5.146 int fd;
5.147 struct stat st;
5.148 void *addr = NULL;
5.149 - size_t nb;
5.150 + size_t nb, size;
5.151 ssize_t res;
5.152 struct open_file *of, *ofend;
5.153
5.154 fd = open(filename, O_RDONLY | O_BINARY);
5.155 if (fd < 0) {
5.156 +#if HAVE_LIBARCHIVE
5.157 + if (errno != ENOTDIR) {
5.158 + razor_set_error_posix(error, filename);
5.159 + return NULL;
5.160 + }
5.161 + addr = razor_file_get_contents_archive(filename, &size, error);
5.162 + if (!addr)
5.163 + return NULL;
5.164 +#else
5.165 razor_set_error_posix(error, filename);
5.166 return NULL;
5.167 +#endif
5.168 + } else {
5.169 + if (fstat(fd, &st) < 0) {
5.170 + razor_set_error_posix(error, filename);
5.171 + close(fd);
5.172 + return NULL;
5.173 + }
5.174 + size = st.st_size;
5.175 }
5.176
5.177 - if (fstat(fd, &st) < 0) {
5.178 - razor_set_error_posix(error, filename);
5.179 - close(fd);
5.180 - return NULL;
5.181 - }
5.182 -
5.183 - *length = st.st_size;
5.184 -
5.185 ofend = open_files.data + open_files.size;
5.186 for (of = open_files.data; of < ofend; of++)
5.187 if (!(of->flags & OPEN_FILE_USED))
5.188 @@ -96,21 +233,21 @@
5.189 }
5.190
5.191 #if HAVE_SYS_MMAN_H
5.192 - if (!private) {
5.193 - addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
5.194 + if (!addr && !private) {
5.195 + addr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
5.196 if (addr == MAP_FAILED)
5.197 addr = NULL;
5.198 else
5.199 of->flags = OPEN_FILE_USED | OPEN_FILE_MMAPPED;
5.200 }
5.201 #endif /* HAVE_SYS_MMAN_H */
5.202 +
5.203 if (!addr) {
5.204 - addr = malloc(st.st_size);
5.205 + addr = malloc(size);
5.206 if (addr) {
5.207 - of->flags = OPEN_FILE_USED;
5.208 nb = 0;
5.209 - while(nb < st.st_size) {
5.210 - res = read(fd, addr + nb, st.st_size - nb);
5.211 + while(nb < size) {
5.212 + res = read(fd, addr + nb, size - nb);
5.213 if (res <= 0) {
5.214 razor_set_error_posix(error, filename);
5.215 free(addr);
5.216 @@ -119,14 +256,21 @@
5.217 }
5.218 nb += res;
5.219 }
5.220 + if (addr)
5.221 + of->flags = OPEN_FILE_USED;
5.222 } else
5.223 razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
5.224 "Not enough memory");
5.225 }
5.226 - close(fd);
5.227 +
5.228 + if (fd >= 0)
5.229 + close(fd);
5.230
5.231 of->addr = addr;
5.232 - of->length = st.st_size;
5.233 + of->length = size;
5.234 +
5.235 + if (addr)
5.236 + *length = size;
5.237
5.238 return addr;
5.239 }
5.240 @@ -659,7 +803,8 @@
5.241 return fallback;
5.242 }
5.243
5.244 -int razor_uri_mkdir(const char *uri, mode_t mode, struct razor_error **error)
5.245 +RAZOR_EXPORT int
5.246 +razor_uri_mkdir(const char *uri, mode_t mode, struct razor_error **error)
5.247 {
5.248 int retval;
5.249 char *path;
5.250 @@ -700,7 +845,8 @@
5.251 return retval;
5.252 }
5.253
5.254 -int razor_uri_unlink(const char *uri, struct razor_error **error)
5.255 +RAZOR_EXPORT int
5.256 +razor_uri_unlink(const char *uri, struct razor_error **error)
5.257 {
5.258 int retval;
5.259 char *path;
5.260 @@ -741,8 +887,9 @@
5.261 return retval;
5.262 }
5.263
5.264 -int razor_uri_open(const char *uri, int flags, mode_t mode,
5.265 - struct razor_error **error)
5.266 +RAZOR_EXPORT int
5.267 +razor_uri_open(const char *uri, int flags, mode_t mode,
5.268 + struct razor_error **error)
5.269 {
5.270 int retval;
5.271 char *path;
5.272 @@ -783,8 +930,9 @@
5.273 return retval;
5.274 }
5.275
5.276 -int razor_uri_move(const char *src_uri, const char *dst_uri,
5.277 - struct razor_error **error)
5.278 +RAZOR_EXPORT int
5.279 +razor_uri_move(const char *src_uri, const char *dst_uri,
5.280 + struct razor_error **error)
5.281 {
5.282 int retval;
5.283 char *src_path, *dst_path;
5.284 @@ -851,8 +999,9 @@
5.285 return retval;
5.286 }
5.287
5.288 -void *razor_uri_get_contents(const char *uri, size_t *length, int private,
5.289 - struct razor_error **error)
5.290 +RAZOR_EXPORT void *
5.291 +razor_uri_get_contents(const char *uri, size_t *length, int private,
5.292 + struct razor_error **error)
5.293 {
5.294 void *retval;
5.295 char *path;
5.296 @@ -897,7 +1046,7 @@
5.297 return retval;
5.298 }
5.299
5.300 -int razor_uri_free_contents(void *addr, size_t length)
5.301 +RAZOR_EXPORT int razor_uri_free_contents(void *addr, size_t length)
5.302 {
5.303 int retval, of;
5.304 struct razor_uri_vtable_entry *entry, *eend;
5.305 @@ -925,7 +1074,8 @@
5.306 return retval;
5.307 }
5.308
5.309 -int razor_uri_is_directory(const char *uri, struct razor_error **error)
5.310 +RAZOR_EXPORT int
5.311 +razor_uri_is_directory(const char *uri, struct razor_error **error)
5.312 {
5.313 int retval;
5.314 char *path;
5.315 @@ -966,8 +1116,9 @@
5.316 return retval;
5.317 }
5.318
5.319 -char *razor_uri_mkdtemp_near(const char *uri, const char *template,
5.320 - struct razor_error **error)
5.321 +RAZOR_EXPORT char *
5.322 +razor_uri_mkdtemp_near(const char *uri, const char *template,
5.323 + struct razor_error **error)
5.324 {
5.325 char *retval, *s;
5.326 char *path;
5.327 @@ -1011,7 +1162,8 @@
5.328 return retval;
5.329 }
5.330
5.331 -void *razor_uri_opendir(const char *uri, struct razor_error **error)
5.332 +RAZOR_EXPORT void *
5.333 +razor_uri_opendir(const char *uri, struct razor_error **error)
5.334 {
5.335 void *retval;
5.336 char *path;
5.337 @@ -1055,7 +1207,7 @@
5.338 return retval;
5.339 }
5.340
5.341 -char *razor_uri_readdir(void *dir, struct razor_error **error)
5.342 +RAZOR_EXPORT char *razor_uri_readdir(void *dir, struct razor_error **error)
5.343 {
5.344 int od;
5.345 char *retval;
5.346 @@ -1086,7 +1238,7 @@
5.347 return retval;
5.348 }
5.349
5.350 -int razor_uri_closedir(void *dir, struct razor_error **error)
5.351 +RAZOR_EXPORT int razor_uri_closedir(void *dir, struct razor_error **error)
5.352 {
5.353 int od;
5.354 int retval;
6.1 --- a/src/Makefile.am Mon Jul 04 10:48:18 2016 +0100
6.2 +++ b/src/Makefile.am Mon Jul 04 13:04:19 2016 +0100
6.3 @@ -24,7 +24,7 @@
6.4 pkgdata_DATA = test.xml
6.5 endif
6.6
6.7 -razor_SOURCES = main.c import-yum.c
6.8 +razor_SOURCES = main.c import.h import-yum.c
6.9 if HAVE_RPMLIB
6.10 razor_SOURCES += import-rpmdb.c
6.11 endif
7.1 --- a/src/import-rpmdb.c Mon Jul 04 10:48:18 2016 +0100
7.2 +++ b/src/import-rpmdb.c Mon Jul 04 13:04:19 2016 +0100
7.3 @@ -32,6 +32,7 @@
7.4 #include <rpm/rpmdb.h>
7.5
7.6 #include "razor.h"
7.7 +#include "import.h"
7.8
7.9 union rpm_entry {
7.10 void *p;
8.1 --- a/src/import-yum.c Mon Jul 04 10:48:18 2016 +0100
8.2 +++ b/src/import-yum.c Mon Jul 04 13:04:19 2016 +0100
8.3 @@ -23,6 +23,7 @@
8.4 #include <string.h>
8.5 #include <stdio.h>
8.6 #include <stdint.h>
8.7 +#include <assert.h>
8.8 #include <sys/stat.h>
8.9 #include <unistd.h>
8.10 #include <fcntl.h>
8.11 @@ -31,6 +32,7 @@
8.12 #include <expat.h>
8.13 #include <zlib.h>
8.14 #include "razor.h"
8.15 +#include "import.h"
8.16
8.17 /* Import a yum filelist as a razor package set. */
8.18
8.19 @@ -282,14 +284,76 @@
8.20
8.21 #define XML_BUFFER_SIZE 4096
8.22
8.23 +struct razor_stream {
8.24 + z_stream strm;
8.25 + void *in;
8.26 + size_t in_length;
8.27 +};
8.28 +
8.29 +static int razor_stream_open(struct razor_stream *rs, const char *uri,
8.30 + struct razor_error **error)
8.31 +{
8.32 + rs->strm.zalloc = Z_NULL;
8.33 + rs->strm.zfree = Z_NULL;
8.34 + rs->strm.opaque = Z_NULL;
8.35 + rs->strm.avail_in = 0;
8.36 + rs->strm.next_in = Z_NULL;
8.37 +
8.38 + if (inflateInit2(&rs->strm, 15 + 16) != Z_OK) {
8.39 + razor_set_error(error, RAZOR_GENERAL_ERROR,
8.40 + RAZOR_GENERAL_ERROR_FAILED, uri,
8.41 + "Failed to initialize inflator");
8.42 + return -1;
8.43 + }
8.44 +
8.45 + rs->in = razor_uri_get_contents(uri, &rs->in_length, 0, error);
8.46 + if (!rs->in) {
8.47 + (void)inflateEnd(&rs->strm);
8.48 + return -1;
8.49 + }
8.50 +
8.51 + rs->strm.avail_in = rs->in_length;
8.52 + rs->strm.next_in = rs->in;
8.53 +
8.54 + return 0;
8.55 +}
8.56 +
8.57 +static ssize_t
8.58 +razor_stream_read(struct razor_stream *rs, unsigned char *buf, size_t len)
8.59 +{
8.60 + int r;
8.61 +
8.62 + rs->strm.avail_out = len;
8.63 + rs->strm.next_out = buf;
8.64 +
8.65 + r = inflate(&rs->strm, Z_NO_FLUSH);
8.66 + assert(r != Z_STREAM_ERROR); /* state not clobbered */
8.67 + switch (r) {
8.68 + case Z_NEED_DICT:
8.69 + case Z_DATA_ERROR:
8.70 + case Z_MEM_ERROR:
8.71 + return -1;
8.72 + }
8.73 +
8.74 + return len - rs->strm.avail_out;
8.75 +}
8.76 +
8.77 +static void razor_stream_close(struct razor_stream *rs)
8.78 +{
8.79 + (void)inflateEnd(&rs->strm);
8.80 + (void)razor_uri_free_contents(rs->in, rs->in_length);
8.81 +}
8.82 +
8.83 struct razor_set *
8.84 -razor_set_create_from_yum(void)
8.85 +razor_set_create_from_yum(const char *yum_uri)
8.86 {
8.87 struct yum_context ctx={0};
8.88 + char *uri;
8.89 void *buf;
8.90 - int len;
8.91 - gzFile primary, filelists;
8.92 + ssize_t len;
8.93 XML_ParsingStatus status;
8.94 + struct razor_error *error = NULL;
8.95 + struct razor_stream primary, filelists;
8.96
8.97 ctx.importer = razor_importer_create();
8.98 ctx.state = YUM_STATE_BEGIN;
8.99 @@ -310,16 +374,37 @@
8.100 XML_SetCharacterDataHandler(ctx.filelists_parser,
8.101 yum_character_data);
8.102
8.103 - primary = gzopen("primary.xml.gz", "rb");
8.104 - if (primary == NULL) {
8.105 - perror("primary.xml.gz");
8.106 + uri = razor_path_relative_to_uri(yum_uri, "repodata/primary.xml.gz",
8.107 + &error);
8.108 + if (!uri) {
8.109 + fprintf(stderr, "%s: %s\n", yum_uri,
8.110 + razor_error_get_msg(error));
8.111 + razor_error_free(error);
8.112 return NULL;
8.113 }
8.114 - filelists = gzopen("filelists.xml.gz", "rb");
8.115 - if (filelists == NULL) {
8.116 - perror("filelists.xml.gz");
8.117 + if (razor_stream_open(&primary, uri, &error)) {
8.118 + fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error));
8.119 + free(uri);
8.120 return NULL;
8.121 }
8.122 + free(uri);
8.123 +
8.124 + uri = razor_path_relative_to_uri(yum_uri, "repodata/filelists.xml.gz",
8.125 + &error);
8.126 + if (!uri) {
8.127 + razor_stream_close(&primary);
8.128 + fprintf(stderr, "%s: %s\n", yum_uri,
8.129 + razor_error_get_msg(error));
8.130 + razor_error_free(error);
8.131 + return NULL;
8.132 + }
8.133 + if (razor_stream_open(&filelists, uri, &error)) {
8.134 + razor_stream_close(&primary);
8.135 + fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error));
8.136 + free(uri);
8.137 + return NULL;
8.138 + }
8.139 + free(uri);
8.140
8.141 ctx.current_parser = ctx.primary_parser;
8.142
8.143 @@ -336,9 +421,11 @@
8.144 buf = XML_GetBuffer(ctx.current_parser,
8.145 XML_BUFFER_SIZE);
8.146 if (ctx.current_parser == ctx.primary_parser)
8.147 - len = gzread(primary, buf, XML_BUFFER_SIZE);
8.148 + len = razor_stream_read(&primary, buf,
8.149 + XML_BUFFER_SIZE);
8.150 else
8.151 - len = gzread(filelists, buf, XML_BUFFER_SIZE);
8.152 + len = razor_stream_read(&filelists, buf,
8.153 + XML_BUFFER_SIZE);
8.154 if (len < 0) {
8.155 fprintf(stderr,
8.156 "couldn't read input: %s\n",
8.157 @@ -357,8 +444,8 @@
8.158 XML_ParserFree(ctx.primary_parser);
8.159 XML_ParserFree(ctx.filelists_parser);
8.160
8.161 - gzclose(primary);
8.162 - gzclose(filelists);
8.163 + razor_stream_close(&primary);
8.164 + razor_stream_close(&filelists);
8.165
8.166 printf ("\nsaving\n");
8.167 return razor_importer_finish(ctx.importer);
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/import.h Mon Jul 04 13:04:19 2016 +0100
9.3 @@ -0,0 +1,9 @@
9.4 +#ifndef _RAZOR_IMPORT_H_
9.5 +#define _RAZOR_IMPORT_H_
9.6 +
9.7 +#include "razor.h"
9.8 +
9.9 +struct razor_set *razor_set_create_from_yum(const char *yum_uri);
9.10 +struct razor_set *razor_set_create_from_rpmdb(void);
9.11 +
9.12 +#endif /* _RAZOR_IMPORT_H_ */
10.1 --- a/src/main.c Mon Jul 04 10:48:18 2016 +0100
10.2 +++ b/src/main.c Mon Jul 04 13:04:19 2016 +0100
10.3 @@ -46,6 +46,7 @@
10.4 #include <errno.h>
10.5 #include <getopt.h>
10.6 #include "razor.h"
10.7 +#include "import.h"
10.8
10.9 static const char system_repo_filename[] = "system.rzdb";
10.10 static const char next_repo_filename[] = "system-next.rzdb";
10.11 @@ -614,140 +615,121 @@
10.12 RAZOR_PROPERTY_PROVIDES);
10.13 }
10.14
10.15 -#ifndef HAVE_CURL
10.16 -static int
10.17 -download_local(const char *url, const char *file)
10.18 +#ifdef HAVE_CURL
10.19 +struct get_contents_with_curl_baton {
10.20 + void *buf;
10.21 + size_t buflen;
10.22 +};
10.23 +
10.24 +static size_t
10.25 +get_contents_with_curl_callback(void *contents, size_t size, size_t nmemb,
10.26 + void *data)
10.27 {
10.28 - FILE *wfp, *rfp;
10.29 - char buffer[256], *ptr, *local;
10.30 - size_t nb, n;
10.31 - struct razor_error *error = NULL;
10.32 + size_t nb = size * nmemb;
10.33 + struct get_contents_with_curl_baton *baton = data;
10.34
10.35 - local = razor_path_from_uri(url, &error);
10.36 -
10.37 - if (local == NULL) {
10.38 - fprintf(stderr, "%s: %s\n", file, razor_error_get_msg(error));
10.39 - razor_error_free(error);
10.40 - return -1;
10.41 - } else {
10.42 - rfp = fopen(local, "rb");
10.43 - if (rfp == NULL) {
10.44 - perror(local);
10.45 - free(local);
10.46 - return -1;
10.47 - }
10.48 -
10.49 - wfp = fopen(file, "wb");
10.50 - if (wfp == NULL) {
10.51 - perror(file);
10.52 - fclose(rfp);
10.53 - free(local);
10.54 - return -1;
10.55 - }
10.56 -
10.57 - while((nb = fread(buffer, 1, sizeof(buffer), rfp)) > 0) {
10.58 - ptr = buffer;
10.59 - while (nb > 0 && (n = fwrite(ptr, 1, nb, wfp)) > 0) {
10.60 - ptr += n;
10.61 - nb -= n;
10.62 - }
10.63 -
10.64 - if (nb != 0) {
10.65 - perror(file);
10.66 - fclose(wfp);
10.67 - fclose(rfp);
10.68 - unlink(file);
10.69 - free(local);
10.70 - return -1;
10.71 - }
10.72 - }
10.73 -
10.74 - if (ferror(rfp)) {
10.75 - perror(local);
10.76 - fclose(wfp);
10.77 - fclose(rfp);
10.78 - unlink(file);
10.79 - free(local);
10.80 - return -1;
10.81 - }
10.82 -
10.83 - fclose(wfp);
10.84 - fclose(rfp);
10.85 - free(local);
10.86 + baton->buf = realloc(baton->buf, baton->buflen + nb);
10.87 + if (!baton->buf) {
10.88 + fprintf(stderr, "Not enough memory to read file\n");
10.89 return 0;
10.90 }
10.91 +
10.92 + memcpy((char *)baton->buf + baton->buflen, contents, nb);
10.93 + baton->buflen += nb;
10.94 +
10.95 + return nb;
10.96 }
10.97 -#endif /* !HAVE_CURL */
10.98
10.99 +static void *get_contents_with_curl(const char *uri, size_t *length,
10.100 + int private, struct razor_error **error)
10.101 +{
10.102 + CURL *curl;
10.103 + char errbuf[256];
10.104 + CURLcode res;
10.105 + struct get_contents_with_curl_baton baton = {0,};
10.106 +
10.107 + curl = curl_easy_init();
10.108 + if (!curl) {
10.109 + razor_set_error(error, RAZOR_GENERAL_ERROR,
10.110 + RAZOR_GENERAL_ERROR_FAILED, uri,
10.111 + "Failed to initialize libcurl");
10.112 + return NULL;
10.113 + }
10.114 +
10.115 + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
10.116 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
10.117 + get_contents_with_curl_callback);
10.118 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&baton);
10.119 + curl_easy_setopt(curl, CURLOPT_URL, uri);
10.120 + curl_easy_setopt(curl, CURLOPT_USERAGENT, "razor/" VERSION);
10.121 + res = curl_easy_perform(curl);
10.122 + curl_easy_cleanup(curl);
10.123 +
10.124 + if (res != CURLE_OK) {
10.125 + razor_set_error(error, RAZOR_GENERAL_ERROR,
10.126 + RAZOR_GENERAL_ERROR_FAILED, uri, errbuf);
10.127 + free(baton.buf);
10.128 + return NULL;
10.129 + }
10.130 +
10.131 + *length = baton.buflen;
10.132 + return baton.buf;
10.133 +}
10.134 +
10.135 +int free_contents_with_curl(void *addr, size_t length)
10.136 +{
10.137 + free(addr);
10.138 +}
10.139 +#endif
10.140 +
10.141 +void init_uri_handler(void)
10.142 +{
10.143 #ifdef HAVE_CURL
10.144 -static int
10.145 -show_progress(void *clientp,
10.146 - double dltotal, double dlnow, double ultotal, double ulnow)
10.147 -{
10.148 - const char *file = clientp;
10.149 -
10.150 - if (!dlnow < dltotal)
10.151 - fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
10.152 - file, (int) dlnow / 1024, (int) dltotal / 1024);
10.153 -
10.154 - return 0;
10.155 + struct razor_uri_vtable uri_vtable={0,};
10.156 + uri_vtable.structure_size=sizeof(uri_vtable);
10.157 + uri_vtable.get_contents=get_contents_with_curl;
10.158 + uri_vtable.free_contents=free_contents_with_curl;
10.159 + razor_uri_set_vtable(NULL, &uri_vtable, NULL);
10.160 +#endif
10.161 }
10.162
10.163 static int
10.164 -download_with_curl(const char *url, const char *file)
10.165 +download_if_missing(const char *uri, const char *file)
10.166 {
10.167 + int retval = 0;
10.168 + struct stat buf;
10.169 + void *contents;
10.170 + size_t length;
10.171 + struct razor_error *error = NULL;
10.172 FILE *fp;
10.173 - CURL *curl;
10.174 - char error[256];
10.175 - CURLcode res;
10.176 - long response;
10.177 -
10.178 - curl = curl_easy_init();
10.179 - if (curl == NULL) {
10.180 - fprintf(stderr,
10.181 - "%s: download manually (curl failed)\n", file);
10.182 - return -1;
10.183 - }
10.184 -
10.185 - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
10.186 - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
10.187 - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
10.188 - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
10.189 -
10.190 - fp = fopen(file, "wb");
10.191 - if (fp == NULL) {
10.192 - perror(file);
10.193 - return -1;
10.194 - }
10.195 - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
10.196 - curl_easy_setopt(curl, CURLOPT_URL, url);
10.197 - res = curl_easy_perform(curl);
10.198 - fclose(fp);
10.199 - putc('\n', stderr);
10.200 - if (res != CURLE_OK) {
10.201 - fprintf(stderr, "curl error: %s\n", error);
10.202 - unlink(file);
10.203 - return -1;
10.204 - }
10.205 - curl_easy_cleanup(curl);
10.206 -
10.207 - return 0;
10.208 -}
10.209 -#endif /* HAVE_CURL */
10.210 -
10.211 -static int
10.212 -download_if_missing(const char *url, const char *file)
10.213 -{
10.214 - struct stat buf;
10.215
10.216 if (stat(file, &buf) >= 0)
10.217 return 0;
10.218
10.219 -#ifndef HAVE_CURL
10.220 - return download_local(url, file);
10.221 -#else
10.222 - return download_with_curl(url, file);
10.223 -#endif
10.224 + contents = razor_uri_get_contents(uri, &length, 0, &error);
10.225 +
10.226 + if (!contents) {
10.227 + fprintf(stderr, "%s: %s\n", uri, razor_error_get_msg(error));
10.228 + razor_error_free(error);
10.229 + return -1;
10.230 + }
10.231 +
10.232 + fp = fopen(file, "wb");
10.233 + if (!fp) {
10.234 + perror(file);
10.235 + razor_uri_free_contents(contents, length);
10.236 + return -1;
10.237 + }
10.238 +
10.239 + if (fwrite(contents, 1, length, fp) != length) {
10.240 + perror(file);
10.241 + retval = -1;
10.242 + }
10.243 +
10.244 + fclose(fp);
10.245 + razor_uri_free_contents(contents, length);
10.246 +
10.247 + return retval;
10.248 }
10.249
10.250 #define YUM_URL "http://download.fedora.redhat.com" \
10.251 @@ -773,17 +755,9 @@
10.252 return 1;
10.253 }
10.254
10.255 - printf("downloading from '%s'.\n", yum_url);
10.256 - snprintf(buffer, sizeof buffer,
10.257 - "%s/repodata/primary.xml.gz", yum_url);
10.258 - if (download_if_missing(buffer, "primary.xml.gz") < 0)
10.259 - return -1;
10.260 - snprintf(buffer, sizeof buffer,
10.261 - "%s/repodata/filelists.xml.gz", yum_url);
10.262 - if (download_if_missing(buffer, "filelists.xml.gz") < 0)
10.263 - return -1;
10.264 + printf("importing from '%s'.\n", yum_url);
10.265
10.266 - set = razor_set_create_from_yum();
10.267 + set = razor_set_create_from_yum(yum_url);
10.268 if (set == NULL)
10.269 return 1;
10.270 atomic = razor_atomic_open("Yum import repository");
10.271 @@ -1097,48 +1071,6 @@
10.272 return razor_concat(name, "-", v, ".", arch, ".rpm", NULL);
10.273 }
10.274
10.275 -static int
10.276 -download_packages(struct razor_set *system, struct razor_set *next)
10.277 -{
10.278 - struct razor_install_iterator *ii;
10.279 - struct razor_package *package;
10.280 - enum razor_install_action action;
10.281 - const char *name, *version, *arch;
10.282 - char *file, *url, *s;
10.283 - int errors = 0, count;
10.284 -
10.285 - ii = razor_set_create_install_iterator(system, next);
10.286 - while (razor_install_iterator_next(ii, &package, &action, &count)) {
10.287 - if (action != RAZOR_INSTALL_ACTION_ADD)
10.288 - continue;
10.289 -
10.290 - razor_package_get_details(next, package,
10.291 - RAZOR_DETAIL_NAME, &name,
10.292 - RAZOR_DETAIL_VERSION, &version,
10.293 - RAZOR_DETAIL_ARCH, &arch,
10.294 - RAZOR_DETAIL_LAST);
10.295 -
10.296 - s = rpm_filename(name, version, arch);
10.297 - file = razor_concat("Packages/", s, NULL);
10.298 - url = razor_path_relative_to_uri(yum_url, file, NULL);
10.299 - free(file);
10.300 - file = razor_concat("rpms/", s, NULL);
10.301 - free(s);
10.302 - if (download_if_missing(url, file) < 0)
10.303 - errors++;
10.304 - free(file);
10.305 - free(url);
10.306 - }
10.307 - razor_install_iterator_destroy(ii);
10.308 -
10.309 - if (errors > 0) {
10.310 - fprintf(stderr, "failed to download %d packages\n", errors);
10.311 - return -1;
10.312 - }
10.313 -
10.314 - return 0;
10.315 -}
10.316 -
10.317 static struct razor_set *
10.318 relocate_packages(struct razor_set *set, struct razor_atomic *atomic,
10.319 struct razor_relocations *relocations)
10.320 @@ -1179,12 +1111,7 @@
10.321 s = razor_concat("Packages/", filename, NULL);
10.322 uri = razor_path_relative_to_uri(yum_url, s, NULL);
10.323 free(s);
10.324 - file = razor_concat("rpms/", filename, NULL);
10.325 free(filename);
10.326 - download_if_missing(uri, file);
10.327 - free(uri);
10.328 - uri = razor_path_to_uri(file);
10.329 - free(file);
10.330 rpm = razor_rpm_open(uri, &error);
10.331 free(uri);
10.332 if (rpm == NULL) {
10.333 @@ -1255,14 +1182,15 @@
10.334 RAZOR_DETAIL_ARCH, &arch,
10.335 RAZOR_DETAIL_LAST);
10.336
10.337 + s = rpm_filename(name, version, arch);
10.338 + file = razor_concat("Packages/", s, NULL);
10.339 + free(s);
10.340 + uri = razor_path_relative_to_uri(yum_url, file, NULL);
10.341 + free(file);
10.342 +
10.343 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
10.344 - printf("install %s-%s\n", name, version);
10.345 + printf("install %s\n", uri);
10.346
10.347 - s = rpm_filename(name, version, arch);
10.348 - file = razor_concat("rpms/", s, NULL);
10.349 - free(s);
10.350 - uri = razor_path_to_uri(file);
10.351 - free(file);
10.352 rpm = razor_rpm_open(uri, &error);
10.353 free(uri);
10.354 if (rpm == NULL) {
10.355 @@ -1510,33 +1438,10 @@
10.356 }
10.357 }
10.358
10.359 - if (razor_atomic_create_dir(atomic, "file:rpms",
10.360 - S_IRWXU | S_IRWXG | S_IRWXO) ||
10.361 - razor_atomic_commit(atomic)) {
10.362 - fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
10.363 - razor_transaction_destroy(trans);
10.364 - razor_set_unref(upstream);
10.365 - razor_root_close(root);
10.366 - razor_atomic_destroy(atomic);
10.367 - if (relocations)
10.368 - razor_relocations_destroy(relocations);
10.369 - return 1;
10.370 - }
10.371 -
10.372 razor_atomic_destroy(atomic);
10.373
10.374 next = razor_transaction_commit(trans);
10.375
10.376 - if (download_packages(system, next) < 0) {
10.377 - razor_set_unref(next);
10.378 - razor_transaction_destroy(trans);
10.379 - razor_set_unref(upstream);
10.380 - razor_root_close(root);
10.381 - if (relocations)
10.382 - razor_relocations_destroy(relocations);
10.383 - return 1;
10.384 - }
10.385 -
10.386 retval = update_system(root, relocations, trans, next,
10.387 do_update ? "Update" : "Install");
10.388
10.389 @@ -1975,6 +1880,8 @@
10.390 return 1;
10.391 }
10.392
10.393 + init_uri_handler();
10.394 +
10.395 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
10.396 if (strcmp(razor_commands[i].name, argv[main_optind]) == 0)
10.397 return razor_commands[i].func(argc - main_optind,
11.1 --- a/test/Makefile.am Mon Jul 04 10:48:18 2016 +0100
11.2 +++ b/test/Makefile.am Mon Jul 04 13:04:19 2016 +0100
11.3 @@ -4,38 +4,60 @@
11.4 if HAVE_LUA
11.5 check_SCRIPTS += lua mult-install
11.6 endif
11.7 +if HAVE_ZIP
11.8 + check_SCRIPTS += archive
11.9 +endif
11.10 +if HAVE_CURL
11.11 +if !MSWIN_API
11.12 + check_SCRIPTS += curl
11.13 +endif
11.14 +endif
11.15 check_SCRIPTS += order non-ascii relative-root
11.16
11.17 -relocate: relocate.sh primary.xml.gz
11.18 +if !MSWIN_API
11.19 + check_PROGRAMS = tftpd
11.20 +endif
11.21 +
11.22 +if INSTALL_TEST_PROGRAMS
11.23 + bin_PROGRAMS = $(check_PROGRAMS)
11.24 +endif
11.25 +
11.26 +relocate: relocate.sh base/repodata/primary.xml.gz
11.27 cp $(srcdir)/relocate.sh relocate
11.28
11.29 -named-root: named-root.sh primary.xml.gz
11.30 +named-root: named-root.sh base/repodata/primary.xml.gz
11.31 cp $(srcdir)/named-root.sh named-root
11.32
11.33 -remove: remove.sh primary.xml.gz
11.34 +remove: remove.sh base/repodata/primary.xml.gz
11.35 cp $(srcdir)/remove.sh remove
11.36
11.37 update: update.sh base/repodata/primary.xml.gz updates/repodata/primary.xml.gz
11.38 cp $(srcdir)/update.sh update
11.39
11.40 -details: details.sh primary.xml.gz
11.41 +details: details.sh base/repodata/primary.xml.gz
11.42 cp $(srcdir)/details.sh details
11.43
11.44 -order: order.sh primary.xml.gz
11.45 +order: order.sh base/repodata/primary.xml.gz
11.46 cp $(srcdir)/order.sh order
11.47
11.48 -non-ascii: non-ascii.sh primary.xml.gz
11.49 +non-ascii: non-ascii.sh base/repodata/primary.xml.gz
11.50 cp $(srcdir)/non-ascii.sh non-ascii
11.51
11.52 -relative-root: relative-root.sh primary.xml.gz
11.53 +relative-root: relative-root.sh base/repodata/primary.xml.gz
11.54 cp $(srcdir)/relative-root.sh relative-root
11.55
11.56 -lua: lua.sh primary.xml.gz
11.57 +lua: lua.sh base/repodata/primary.xml.gz
11.58 cp $(srcdir)/lua.sh lua
11.59
11.60 -mult-install: mult-install.sh primary.xml.gz
11.61 +mult-install: mult-install.sh base/repodata/primary.xml.gz
11.62 cp $(srcdir)/mult-install.sh mult-install
11.63
11.64 +archive: archive.sh base.zip
11.65 + cp $(srcdir)/archive.sh archive
11.66 +
11.67 +curl: curl.sh tftpd base/repodata/primary.xml.gz
11.68 + cp $(srcdir)/curl.sh curl
11.69 +
11.70 base/repodata/primary.xml.gz: zsh.spec zsh2.spec zip.spec zap.spec \
11.71 filesystem.spec Makefile
11.72 rm -rf rpmbuild base
11.73 @@ -52,6 +74,9 @@
11.74 rm -rf rpmbuild
11.75 createrepo --simple-md-filenames base
11.76
11.77 +base.zip: base/repodata/primary.xml.gz
11.78 + (cd base && zip -r ../$@ *)
11.79 +
11.80 updates/repodata/primary.xml.gz: zip.spec Makefile
11.81 rm -rf rpmbuild updates
11.82 mkdir -p rpmbuild/BUILD rpmbuild/RPMS
11.83 @@ -62,11 +87,6 @@
11.84 rm -rf rpmbuild
11.85 createrepo --simple-md-filenames updates
11.86
11.87 -primary.xml.gz: base/repodata/primary.xml.gz
11.88 - cp base/repodata/primary.xml.gz base/repodata/filelists.xml.gz .
11.89 - rm -rf rpms
11.90 - ln -s base/Packages rpms
11.91 -
11.92 TESTS = $(check_SCRIPTS)
11.93
11.94 EXTRA_DIST = \
11.95 @@ -79,6 +99,8 @@
11.96 order.sh \
11.97 non-ascii.sh \
11.98 relative-root.sh \
11.99 + archive.sh \
11.100 + curl.sh \
11.101 mult-install.sh \
11.102 lua.sh \
11.103 remove.sh \
11.104 @@ -89,6 +111,7 @@
11.105 relocate.sh
11.106
11.107 MOSTLYCLEANFILES = \
11.108 + base.zip \
11.109 primary.xml.gz \
11.110 filelists.xml.gz \
11.111 $(check_SCRIPTS) \
11.112 @@ -97,4 +120,4 @@
11.113
11.114 clean-local :
11.115 rm -f *~
11.116 - rm -rf repodata rpms base updates
11.117 + rm -rf base updates
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/test/archive.sh Mon Jul 04 13:04:19 2016 +0100
12.3 @@ -0,0 +1,29 @@
12.4 +#!/bin/sh
12.5 +if [ $# -gt 0 ]; then
12.6 + razor="$1"
12.7 +else
12.8 + razor=`pwd`/../src/razor
12.9 +fi
12.10 +check_file()
12.11 +{
12.12 + (cd $scratchdir; $razor list-files) | grep -F -x "$1" > /dev/null
12.13 + if [ $? -ne 0 ]; then
12.14 + echo $1: Not in database >&2
12.15 + (cd $scratchdir; $razor list-files) >&2
12.16 + exit 1
12.17 + fi
12.18 + if [ ! -e "$tmproot$1" ]; then
12.19 + echo $1: Not in filesystem >&2
12.20 + ls -R "$tmproot" >&2
12.21 + exit 1
12.22 + fi
12.23 +}
12.24 +tmproot=`mktemp -dt` || exit 1
12.25 +export RAZOR_ROOT="file:$tmproot"
12.26 +scratchdir=`mktemp -dt` || exit 1
12.27 +(cd $scratchdir; $razor init) || exit 1
12.28 +export YUM_URL="file:`pwd`/base.zip"
12.29 +(cd $scratchdir; $razor import-yum) || exit 1
12.30 +(cd $scratchdir; $razor install zap) || exit 1
12.31 +check_file /usr/bin/zap
12.32 +rm -rf "$scratchdir" "$tmproot"
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/test/curl.sh Mon Jul 04 13:04:19 2016 +0100
13.3 @@ -0,0 +1,50 @@
13.4 +#!/bin/bash
13.5 +if [ $# -gt 0 ]; then
13.6 + razor="$1"
13.7 +else
13.8 + razor=`pwd`/../src/razor
13.9 +fi
13.10 +check_file()
13.11 +{
13.12 + $razor list-files | grep -F -x "$1" > /dev/null
13.13 + if [ $? -ne 0 ]; then
13.14 + echo $1: Not in database >&2
13.15 + $razor list-files >&2
13.16 + exit 1
13.17 + fi
13.18 + if [ ! -e "$tmproot$1" ]; then
13.19 + echo $1: Not in filesystem >&2
13.20 + ls -R "$tmproot" >&2
13.21 + exit 1
13.22 + fi
13.23 +}
13.24 +tmproot=`mktemp -dt` || exit 1
13.25 +export RAZOR_ROOT="file:$tmproot"
13.26 +scratchdir=`mktemp -dt` || exit 1
13.27 +(cd base && ../tftpd $scratchdir/tftpd.pid $scratchdir/tftpd.port) || exit 1
13.28 +cd $scratchdir
13.29 +port=`cat tftpd.port`
13.30 +pid=`cat tftpd.pid`
13.31 +export YUM_URL="tftp://localhost:$port/"
13.32 +if $razor init; then
13.33 + :
13.34 +else
13.35 + kill $pid
13.36 + exit 1
13.37 +fi
13.38 +if $razor import-yum; then
13.39 + :
13.40 +else
13.41 + kill $pid
13.42 + exit 1
13.43 +fi
13.44 +if $razor install zap; then
13.45 + :
13.46 +else
13.47 + kill $pid
13.48 + exit 1
13.49 +fi
13.50 +check_file /usr/bin/zap
13.51 +rm -rf "$scratchdir" "$tmproot"
13.52 +kill $pid
13.53 +exit 0
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/test/tftpd.c Mon Jul 04 13:04:19 2016 +0100
14.3 @@ -0,0 +1,231 @@
14.4 +/*
14.5 + * Copyright (C) 2016 J. Ali Harlow <ali@juiblex.co.uk>
14.6 + *
14.7 + * This program is free software; you can redistribute it and/or modify
14.8 + * it under the terms of the GNU General Public License as published by
14.9 + * the Free Software Foundation; either version 2 of the License, or
14.10 + * (at your option) any later version.
14.11 + *
14.12 + * This program is distributed in the hope that it will be useful,
14.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.15 + * GNU General Public License for more details.
14.16 + *
14.17 + * You should have received a copy of the GNU General Public License along
14.18 + * with this program; if not, write to the Free Software Foundation, Inc.,
14.19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14.20 + */
14.21 +
14.22 +#include "config.h"
14.23 +
14.24 +#include <stdlib.h>
14.25 +#include <string.h>
14.26 +#include <stdio.h>
14.27 +#include <errno.h>
14.28 +#include <unistd.h>
14.29 +#include <sys/types.h>
14.30 +#include <sys/socket.h>
14.31 +#include <netinet/in.h>
14.32 +#include <netinet/ip.h>
14.33 +#include <arpa/tftp.h>
14.34 +
14.35 +/*
14.36 + * A simple TFTP server suitable only for use on the loopback interface
14.37 + * (it has no support for retransmitting lost packets).
14.38 + */
14.39 +
14.40 +char inbuf[SEGSIZE+4];
14.41 +char outbuf[SEGSIZE+4];
14.42 +
14.43 +int send_error(int s, const struct sockaddr *client, socklen_t client_addr_len,
14.44 + unsigned short code,const char *message)
14.45 +{
14.46 + int r;
14.47 + char *buf;
14.48 + size_t len;
14.49 +
14.50 + len = 4 + strlen(message) + 1;
14.51 + buf = malloc(len);
14.52 + ((unsigned short *)buf)[0] = htons(ERROR);
14.53 + ((unsigned short *)buf)[1] = htons(code);
14.54 + strcpy(buf + 4, message);
14.55 + r = sendto(s, buf, len, 0, client, client_addr_len);
14.56 + free(buf);
14.57 +
14.58 + return r;
14.59 +}
14.60 +
14.61 +int send_file(int s, const struct sockaddr *client, socklen_t client_addr_len,
14.62 + const char *path, const char *mode)
14.63 +{
14.64 + const char *dotdot, *p;
14.65 + FILE *fp;
14.66 + size_t nb;
14.67 + int block = 0;
14.68 +
14.69 + if (strcasecmp(mode, "octet")) {
14.70 + send_error(s, client, client_addr_len, EBADOP, "Bad mode");
14.71 + return -1;
14.72 + }
14.73 +
14.74 + if (!*path || *path == '/') {
14.75 + send_error(s, client, client_addr_len, EACCESS,
14.76 + "Access denied");
14.77 + return -1;
14.78 + }
14.79 +
14.80 + for (p = path; *p;) {
14.81 + dotdot = strstr(p, "..");
14.82 + if (!dotdot)
14.83 + break;
14.84 + if ((dotdot == path || dotdot[-1] == '/') &&
14.85 + (dotdot[2] == '/' || dotdot[2] == '\0')) {
14.86 + send_error(s, client, client_addr_len, EACCESS,
14.87 + "Access denied");
14.88 + return -1;
14.89 + }
14.90 + p = dotdot + 2;
14.91 + }
14.92 +
14.93 + fp = fopen(path, "rb");
14.94 +
14.95 + if (!fp) {
14.96 + if (errno == ENOENT)
14.97 + send_error(s, client, client_addr_len, ENOTFOUND,
14.98 + strerror(errno));
14.99 + else if (errno == EACCES)
14.100 + send_error(s, client, client_addr_len, EACCESS,
14.101 + strerror(errno));
14.102 + else
14.103 + send_error(s, client, client_addr_len, EUNDEF,
14.104 + strerror(errno));
14.105 + return -1;
14.106 + }
14.107 +
14.108 + ((unsigned short *)outbuf)[0] = htons(DATA);
14.109 +
14.110 + while((nb = fread(outbuf + 4, 1, SEGSIZE, fp)) >= 0)
14.111 + {
14.112 + ((unsigned short *)outbuf)[1] = htons(++block);
14.113 + if (sendto(s, outbuf, nb + 4, 0, client, client_addr_len) < 0) {
14.114 + perror("sendto");
14.115 + fclose(fp);
14.116 + return -1;
14.117 + }
14.118 +
14.119 + /* Discard ACKs */
14.120 + (void)recvfrom(s, inbuf, sizeof(inbuf), 0, NULL, NULL);
14.121 +
14.122 + if (nb < SEGSIZE)
14.123 + break;
14.124 + }
14.125 +
14.126 + fclose(fp);
14.127 +
14.128 + return 0;
14.129 +}
14.130 +
14.131 +void serve(int s)
14.132 +{
14.133 + char *filename, *mode;
14.134 + struct sockaddr_storage client;
14.135 + socklen_t client_addr_len;
14.136 + ssize_t nb;
14.137 +
14.138 + for(;;) {
14.139 + client_addr_len = sizeof(client);
14.140 + nb = recvfrom(s, inbuf, sizeof(inbuf), 0,
14.141 + (struct sockaddr *)&client, &client_addr_len);
14.142 +
14.143 + if (nb < 0) {
14.144 + perror("recvfrom");
14.145 + exit(1);
14.146 + }
14.147 +
14.148 + if (nb >= 2) {
14.149 + switch (ntohs(*(unsigned short *)inbuf)) {
14.150 + case RRQ:
14.151 + filename = inbuf + 2;
14.152 + mode = memchr(filename, '\0', nb - 2);
14.153 + if (!mode) {
14.154 + send_error(s,
14.155 + (struct sockaddr *)&client,
14.156 + client_addr_len, EBADOP,
14.157 + "Bad request");
14.158 + break;
14.159 + }
14.160 + mode++;
14.161 + if (!memchr(mode, '\0', nb - (mode - inbuf))) {
14.162 + send_error(s,
14.163 + (struct sockaddr *)&client,
14.164 + client_addr_len, EBADOP,
14.165 + "Bad request");
14.166 + break;
14.167 + }
14.168 + send_file(s, (struct sockaddr *)&client,
14.169 + client_addr_len, filename, mode);
14.170 + break;
14.171 + case WRQ:
14.172 + send_error(s, (struct sockaddr *)&client,
14.173 + client_addr_len, EACCESS,
14.174 + "Access denied");
14.175 + break;
14.176 + case DATA:
14.177 + case ACK:
14.178 + case ERROR:
14.179 + break;
14.180 + }
14.181 + }
14.182 + }
14.183 +}
14.184 +
14.185 +main(int argc, char **argv)
14.186 +{
14.187 + int s;
14.188 + pid_t pid;
14.189 + FILE *fp;
14.190 + in_port_t port;
14.191 + struct sockaddr_in sin = {0,};
14.192 +
14.193 + s = socket(AF_INET, SOCK_DGRAM, 0);
14.194 + if (s < 0) {
14.195 + perror("socket");
14.196 + exit(1);
14.197 + }
14.198 +
14.199 + sin.sin_family = AF_INET;
14.200 + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
14.201 +
14.202 + for (port = 0;; port++) {
14.203 + sin.sin_port = htons(IPPORT_USERRESERVED + port);
14.204 + if (!bind(s, (struct sockaddr *)&sin, sizeof(sin)))
14.205 + break;
14.206 + if (errno != EADDRINUSE || port >= 1023) {
14.207 + perror("bind");
14.208 + exit(1);
14.209 + }
14.210 + }
14.211 +
14.212 + if (argc > 2) {
14.213 + fp = fopen(argv[2], "w");
14.214 + if (fp) {
14.215 + fprintf(fp, "%ld\n", (long)ntohs(sin.sin_port));
14.216 + fclose(fp);
14.217 + }
14.218 +
14.219 + pid = fork();
14.220 + if (pid) {
14.221 + fp = fopen(argv[1], "w");
14.222 + if (fp) {
14.223 + fprintf(fp, "%ld\n", (long)pid);
14.224 + fclose(fp);
14.225 + }
14.226 + exit(0);
14.227 + }
14.228 + } else
14.229 + printf("%d\n", ntohs(sin.sin_port));
14.230 +
14.231 + serve(s);
14.232 +
14.233 + exit(0);
14.234 +}