#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <fcntl.h>
#include <dirent.h>
#include <curl/curl.h>
#include <fnmatch.h>
struct razor_transaction *trans;
char path[PATH_MAX], new_path[PATH_MAX];
CURL *curl;
- int errors;
+ int errors, fd;
+
+ /* Create the new next repo file up front to ensure exclusive
+ * access. */
+ snprintf(new_path, sizeof new_path,
+ "%s%s/%s", root, razor_root_path, next_repo_filename);
+ fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
+ if (fd < 0) {
+ fprintf(stderr, "failed to get lock file, "
+ "maybe previous operation crashed?\n");
+
+ /* FIXME: Use fcntl advisory locking to figure out
+ * whether previous operation crashed or is still in
+ * progress. */
+
+ return -1;
+ }
upstream = razor_set_open(rawhide_repo_filename);
snprintf(path, sizeof path,
"%s%s/%s", root, razor_root_path, system_repo_filename);
system = razor_set_open(path);
- if (system == NULL || upstream == NULL)
+ if (system == NULL || upstream == NULL) {
+ unlink(new_path);
return 1;
+ }
trans = razor_transaction_create(system, upstream,
argc, argv, 0, NULL);
errors = razor_transaction_describe(trans);
- if (errors)
+ if (errors) {
+ unlink(new_path);
return 1;
+ }
next = razor_transaction_finish(trans);
- /* FIXME: Need razor_set_write_to_fd() so we can open it excl
- * up front here or fail if it already exists. */
- snprintf(new_path, sizeof new_path,
- "%s%s/%s", root, razor_root_path, next_repo_filename);
-
- razor_set_write(next, new_path);
+ razor_set_write_to_fd(next, fd);
printf("wrote %s\n", new_path);
curl = curl_easy_init();
- if (curl == NULL)
+ if (curl == NULL) {
+ unlink(new_path);
return 1;
+ }
razor_set_diff(system, next, download_package, curl);
curl_easy_cleanup(curl);
}
int
-razor_set_write(struct razor_set *set, const char *filename)
+razor_set_write_to_fd(struct razor_set *set, int fd)
{
char data[4096];
struct razor_set_header *header = (struct razor_set_header *) data;
struct array *a;
uint32_t offset;
- int i, fd;
+ int i;
memset(data, 0, sizeof data);
header->magic = RAZOR_MAGIC;
header->sections[i].offset = 0;
header->sections[i].size = 0;
- fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
- if (fd < 0)
- return -1;
-
razor_write(fd, data, sizeof data);
memset(data, 0, sizeof data);
for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
}
- close(fd);
-
return 0;
}
+int
+razor_set_write(struct razor_set *set, const char *filename)
+{
+ int fd, status;
+
+ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+ if (fd < 0)
+ return -1;
+
+ status = razor_set_write_to_fd(set, fd);
+ if (status) {
+ close(fd);
+ return status;
+ }
+
+ return close(fd);
+}
+
void
razor_build_evr(char *evr_buf, int size, const char *epoch,
const char *version, const char *release)