1.1 --- a/librazor/razor.c Wed Apr 28 11:59:02 2010 +0100
1.2 +++ b/librazor/razor.c Thu Nov 10 10:35:21 2011 +0000
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
1.6 * Copyright (C) 2008 Red Hat, Inc
1.7 - * Copyright (C) 2009, 2010 J. Ali Harlow <ali@juiblex.co.uk>
1.8 + * Copyright (C) 2009-2011 J. Ali Harlow <ali@juiblex.co.uk>
1.9 *
1.10 * This program is free software; you can redistribute it and/or modify
1.11 * it under the terms of the GNU General Public License as published by
1.12 @@ -93,10 +93,16 @@
1.13
1.14 set = zalloc(sizeof *set);
1.15
1.16 - empty = array_add(&set->string_pool, 1);
1.17 - *empty = '\0';
1.18 + if (set) {
1.19 + empty = array_add(&set->string_pool, 1);
1.20 + *empty = '\0';
1.21
1.22 - set->lock_fd = -1;
1.23 + set->lock_fd = -1;
1.24 +
1.25 + set->ref_count = 1;
1.26 +
1.27 + set->header_version = RAZOR_HEADER_VERSION;
1.28 + }
1.29
1.30 return set;
1.31 }
1.32 @@ -118,6 +124,24 @@
1.33 return set;
1.34 }
1.35
1.36 +RAZOR_EXPORT uint32_t
1.37 +razor_set_get_header_version(struct razor_set *set)
1.38 +{
1.39 + return set->header_version;
1.40 +}
1.41 +
1.42 +RAZOR_EXPORT int
1.43 +razor_set_set_header_version(struct razor_set *set, uint32_t header_version)
1.44 +{
1.45 + if (header_version<RAZOR_HEADER_VERSION_MIN ||
1.46 + header_version>RAZOR_HEADER_VERSION)
1.47 + return -1;
1.48 + else {
1.49 + set->header_version = header_version;
1.50 + return 0;
1.51 + }
1.52 +}
1.53 +
1.54 struct razor_mapped_file {
1.55 struct razor_set_header *header;
1.56 size_t size;
1.57 @@ -125,32 +149,52 @@
1.58 };
1.59
1.60 RAZOR_EXPORT int
1.61 -razor_set_bind_sections(struct razor_set *set, const char *filename)
1.62 +razor_set_bind_sections(struct razor_set *set, struct razor_atomic *atomic,
1.63 + const char *filename)
1.64 {
1.65 struct razor_set_section *s, *sections;
1.66 struct razor_mapped_file *file;
1.67 - const char *pool;
1.68 + const char *pool, *reason;
1.69 + char *msg;
1.70 struct array *array;
1.71 int i, j;
1.72
1.73 file = zalloc(sizeof *file);
1.74 - if (file == NULL)
1.75 + if (file == NULL) {
1.76 + razor_atomic_abort(atomic, "Not enough memory");
1.77 return -1;
1.78 + }
1.79
1.80 file->header = razor_file_get_contents(filename, &file->size);
1.81 if (!file->header) {
1.82 + msg = razor_concat(filename, ": ", strerror(errno), NULL);
1.83 + razor_atomic_abort(atomic, msg);
1.84 + free(msg);
1.85 free(file);
1.86 return -1;
1.87 }
1.88
1.89 - if (file->size < sizeof *file->header ||
1.90 - file->header->magic != RAZOR_MAGIC ||
1.91 - file->header->version != RAZOR_VERSION) {
1.92 + if (file->size < sizeof *file->header)
1.93 + reason = "Premature EOF";
1.94 + else if (file->header->magic != RAZOR_MAGIC)
1.95 + reason = "Bad magic number";
1.96 + else if (file->header->version < RAZOR_HEADER_VERSION_MIN ||
1.97 + file->header->version > RAZOR_HEADER_VERSION)
1.98 + reason = "Incompatible file version";
1.99 + else
1.100 + reason = NULL;
1.101 +
1.102 + if (reason) {
1.103 + msg = razor_concat(filename, ": ", reason, NULL);
1.104 + razor_atomic_abort(atomic, msg);
1.105 + free(msg);
1.106 razor_file_free_contents(file->header, file->size);
1.107 free(file);
1.108 return -1;
1.109 }
1.110
1.111 + set->header_version = file->header->version;
1.112 +
1.113 if (set->mapped_files == NULL) {
1.114 for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
1.115 array = (void *) set + razor_sections[i].offset;
1.116 @@ -182,13 +226,18 @@
1.117 }
1.118
1.119 RAZOR_EXPORT struct razor_set *
1.120 -razor_set_open(const char *filename)
1.121 +razor_set_open(const char *filename, struct razor_atomic *atomic)
1.122 {
1.123 struct razor_set *set;
1.124
1.125 set = zalloc(sizeof *set);
1.126 + if (!set) {
1.127 + razor_atomic_abort(atomic, "Not enough memory");
1.128 + return NULL;
1.129 + }
1.130 +
1.131 set->lock_fd = -1;
1.132 - if (razor_set_bind_sections(set, filename)){
1.133 + if (razor_set_bind_sections(set, atomic, filename)) {
1.134 free(set);
1.135 return NULL;
1.136 }
1.137 @@ -215,12 +264,14 @@
1.138
1.139 if (exclusive)
1.140 flags |= LOCKFILE_EXCLUSIVE_LOCK;
1.141 - if (fd >= 0 && !LockFileEx(_get_osfhandle(fd), flags, 0, 1, 0, &lock)) {
1.142 + if (fd >= 0 && !LockFileEx((HANDLE)_get_osfhandle(fd), flags, 0, 1, 0,
1.143 + &lock)) {
1.144 close(fd);
1.145 return -1;
1.146 }
1.147 if (set->lock_fd >= 0)
1.148 - (void)UnlockFile(_get_osfhandle(set->lock_fd), 0, 0, 1, 0);
1.149 + (void)UnlockFile((HANDLE)_get_osfhandle(set->lock_fd), 0, 0, 1,
1.150 + 0);
1.151 #else
1.152 struct flock lock = {0};
1.153
1.154 @@ -245,7 +296,7 @@
1.155 return 0;
1.156 }
1.157
1.158 -RAZOR_EXPORT void
1.159 +static void
1.160 razor_set_destroy(struct razor_set *set)
1.161 {
1.162 struct razor_mapped_file *file, *next;
1.163 @@ -271,8 +322,24 @@
1.164 free(set);
1.165 }
1.166
1.167 -RAZOR_EXPORT int
1.168 -razor_set_write_to_fd(struct razor_set *set, int fd, uint32_t section_mask)
1.169 +RAZOR_EXPORT void
1.170 +razor_set_unref(struct razor_set *set)
1.171 +{
1.172 + if (set && !--set->ref_count)
1.173 + razor_set_destroy(set);
1.174 +}
1.175 +
1.176 +RAZOR_EXPORT struct razor_set *
1.177 +razor_set_ref(struct razor_set *set)
1.178 +{
1.179 + if (set)
1.180 + set->ref_count++;
1.181 + return set;
1.182 +}
1.183 +
1.184 +RAZOR_EXPORT void
1.185 +razor_set_write_to_handle(struct razor_set *set, struct razor_atomic *atomic,
1.186 + int handle, uint32_t section_mask)
1.187 {
1.188 struct razor_set_header header;
1.189 struct razor_set_section sections[ARRAY_SIZE(razor_sections)];
1.190 @@ -298,7 +365,7 @@
1.191
1.192 count = j;
1.193 header.magic = RAZOR_MAGIC;
1.194 - header.version = RAZOR_VERSION;
1.195 + header.version = set->header_version;
1.196 header.num_sections = count;
1.197 offset = sizeof header + count * sizeof *sections + ALIGN(pool.size, 4);
1.198
1.199 @@ -308,38 +375,36 @@
1.200 offset += ALIGN(arrays[i]->size, 4);
1.201 }
1.202
1.203 - razor_write(fd, &header, sizeof header);
1.204 - razor_write(fd, sections, count * sizeof *sections);
1.205 - razor_write(fd, pool.data, pool.size);
1.206 - razor_write(fd, padding, PADDING(pool.size, 4));
1.207 + razor_atomic_write(atomic, handle, &header, sizeof header);
1.208 + razor_atomic_write(atomic, handle, sections, count * sizeof *sections);
1.209 + razor_atomic_write(atomic, handle, pool.data, pool.size);
1.210 + razor_atomic_write(atomic, handle, padding, PADDING(pool.size, 4));
1.211
1.212 for (i = 0; i < count; i++) {
1.213 - razor_write(fd, arrays[i]->data, arrays[i]->size);
1.214 - razor_write(fd, padding, PADDING(arrays[i]->size, 4));
1.215 + razor_atomic_write(atomic, handle, arrays[i]->data,
1.216 + arrays[i]->size);
1.217 + razor_atomic_write(atomic, handle, padding,
1.218 + PADDING(arrays[i]->size, 4));
1.219 }
1.220
1.221 array_release(&pool);
1.222 hashtable_release(&table);
1.223 -
1.224 - return 0;
1.225 }
1.226
1.227 RAZOR_EXPORT int
1.228 -razor_set_write(struct razor_set *set, const char *filename, uint32_t sections)
1.229 +razor_set_write(struct razor_set *set, struct razor_atomic *atomic,
1.230 + const char *filename, uint32_t sections)
1.231 {
1.232 - int fd, status;
1.233 + int h;
1.234
1.235 - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0666);
1.236 - if (fd < 0)
1.237 + h = razor_atomic_create_file(atomic, filename,
1.238 + S_IRWXU | S_IRWXG | S_IRWXO);
1.239 + if (h < 0)
1.240 return -1;
1.241
1.242 - status = razor_set_write_to_fd(set, fd, sections);
1.243 - if (status) {
1.244 - close(fd);
1.245 - return status;
1.246 - }
1.247 + razor_set_write_to_handle(set, atomic, h, sections);
1.248
1.249 - return close(fd);
1.250 + return razor_atomic_close(atomic, h);
1.251 }
1.252
1.253 RAZOR_EXPORT void
1.254 @@ -554,74 +619,86 @@
1.255 * @package: a %razor_package
1.256 * @root: the root into which the package is currently installed
1.257 * @install_count: the value to pass to uninstall scripts
1.258 + * @stage: Limit the removal to just the scripts or the files
1.259 *
1.260 * Removes an installed package.
1.261 **/
1.262 RAZOR_EXPORT int
1.263 razor_package_remove(struct razor_set *prev, struct razor_set *next,
1.264 - struct razor_package *package, const char *root,
1.265 - int install_count)
1.266 + struct razor_atomic *atomic, struct razor_package *package,
1.267 + const char *root, int install_count,
1.268 + enum razor_stage_type stage)
1.269 {
1.270 struct razor_file_iterator *fi;
1.271 struct razor_package_iterator *pi;
1.272 struct razor_package *p;
1.273 - char buffer[PATH_MAX];
1.274 + char *buffer;
1.275 const char *name, *program, *script;
1.276 - int retval = 0, i, count;
1.277 + int i, count;
1.278 struct environment env;
1.279 struct list *link;
1.280 const char *prefix;
1.281
1.282 - environment_init(&env);
1.283 - link = list_first(&package->install_prefixes, &prev->prefix_pool);
1.284 - for (i = 0; link; i++) {
1.285 - prefix = (const char *)prev->string_pool.data + link->data;
1.286 - sprintf(buffer, "RPM_INSTALL_PREFIX%d", i);
1.287 - environment_add_variable(&env, buffer, prefix);
1.288 - link = list_next(link);
1.289 + if (stage & RAZOR_STAGE_SCRIPTS) {
1.290 + environment_init(&env);
1.291 + link = list_first(&package->install_prefixes,
1.292 + &prev->prefix_pool);
1.293 + for (i = 0; link; i++) {
1.294 + prefix = (const char *)prev->string_pool.data +
1.295 + link->data;
1.296 + sprintf(buffer, "RPM_INSTALL_PREFIX%d", i);
1.297 + environment_add_variable(&env, buffer, prefix);
1.298 + link = list_next(link);
1.299 + }
1.300 + environment_set(&env);
1.301 }
1.302 - environment_set(&env);
1.303
1.304 - razor_package_get_details(prev, package,
1.305 - RAZOR_DETAIL_PREUNPROG, &program,
1.306 - RAZOR_DETAIL_PREUN, &script,
1.307 - RAZOR_DETAIL_LAST);
1.308 + if (stage & RAZOR_STAGE_SCRIPTS_PRE) {
1.309 + razor_package_get_details(prev, package,
1.310 + RAZOR_DETAIL_PREUNPROG, &program,
1.311 + RAZOR_DETAIL_PREUN, &script,
1.312 + RAZOR_DETAIL_LAST);
1.313
1.314 - retval = razor_run_script(root, RAZOR_PROPERTY_PREUN, program, script,
1.315 - install_count);
1.316 + razor_run_script(root, RAZOR_PROPERTY_PREUN, program,
1.317 + script, install_count);
1.318 + }
1.319
1.320 - fi = razor_file_iterator_create(prev, package, 1);
1.321 + if (stage & RAZOR_STAGE_FILES) {
1.322 + fi = razor_file_iterator_create(prev, package, 1);
1.323
1.324 - while (razor_file_iterator_next(fi, &name)) {
1.325 - pi = razor_package_iterator_create_for_file(next, name);
1.326 - count = 0;
1.327 - while (razor_package_iterator_next(pi, &p, RAZOR_DETAIL_LAST))
1.328 - count++;
1.329 - razor_package_iterator_destroy(pi);
1.330 - if (count <= 0) {
1.331 - snprintf(buffer, sizeof buffer, "%s%s", root, name);
1.332 - if (razor_remove(buffer) && errno != ENOENT) {
1.333 - perror(name);
1.334 - retval = -1;
1.335 + while (razor_file_iterator_next(fi, &name)) {
1.336 + pi = razor_package_iterator_create_for_file(next, name);
1.337 + count = 0;
1.338 + while (razor_package_iterator_next(pi, &p,
1.339 + RAZOR_DETAIL_LAST))
1.340 + count++;
1.341 + razor_package_iterator_destroy(pi);
1.342 + if (count <= 0) {
1.343 + buffer = razor_concat(root, name, NULL);
1.344 + razor_atomic_remove(atomic, buffer);
1.345 + free(buffer);
1.346 }
1.347 }
1.348 +
1.349 + razor_file_iterator_destroy(fi);
1.350 }
1.351
1.352 - razor_file_iterator_destroy(fi);
1.353 + if (stage & RAZOR_STAGE_SCRIPTS_POST) {
1.354 + razor_package_get_details(prev, package,
1.355 + RAZOR_DETAIL_POSTUNPROG, &program,
1.356 + RAZOR_DETAIL_POSTUN, &script,
1.357 + RAZOR_DETAIL_LAST);
1.358
1.359 - razor_package_get_details(prev, package,
1.360 - RAZOR_DETAIL_POSTUNPROG, &program,
1.361 - RAZOR_DETAIL_POSTUN, &script,
1.362 - RAZOR_DETAIL_LAST);
1.363 + razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script,
1.364 + install_count);
1.365 + }
1.366
1.367 - if (razor_run_script(root, RAZOR_PROPERTY_POSTUN, program, script,
1.368 - install_count))
1.369 - retval = -1;
1.370 + if (stage & RAZOR_STAGE_SCRIPTS) {
1.371 + environment_unset(&env);
1.372 + environment_release(&env);
1.373 + }
1.374
1.375 - environment_unset(&env);
1.376 - environment_release(&env);
1.377 -
1.378 - return retval;
1.379 + return razor_atomic_in_error_state(atomic);
1.380 }
1.381
1.382 RAZOR_EXPORT const char *
1.383 @@ -887,7 +964,7 @@
1.384 struct razor_set *set;
1.385 struct razor_set *next;
1.386 struct array actions;
1.387 - struct deque *order;
1.388 + struct deque *order, *left;
1.389 };
1.390
1.391 static void
1.392 @@ -989,6 +1066,7 @@
1.393 }
1.394
1.395 ii->order = graph_sort(&follows);
1.396 + ii->left = deque_dup(ii->order);
1.397 graph_release(&follows);
1.398
1.399 return ii;
1.400 @@ -1005,10 +1083,10 @@
1.401 struct razor_package *pkg;
1.402 const char *removing, *name;
1.403
1.404 - if (deque_empty(ii->order))
1.405 + if (deque_empty(ii->left))
1.406 return 0;
1.407
1.408 - a = (struct install_action *)ii->actions.data + deque_pop(ii->order);
1.409 + a = (struct install_action *)ii->actions.data + deque_pop(ii->left);
1.410 *package = a->package;
1.411 *action = a->action;
1.412 *count = 0;
1.413 @@ -1026,15 +1104,24 @@
1.414 (*count)++;
1.415 }
1.416 razor_package_iterator_destroy(pi);
1.417 - }
1.418 + } else
1.419 + *count = 1;
1.420
1.421 return 1;
1.422 }
1.423
1.424 RAZOR_EXPORT void
1.425 +razor_install_iterator_rewind(struct razor_install_iterator *ii)
1.426 +{
1.427 + deque_free(ii->left);
1.428 + ii->left=deque_dup(ii->order);
1.429 +}
1.430 +
1.431 +RAZOR_EXPORT void
1.432 razor_install_iterator_destroy(struct razor_install_iterator *ii)
1.433 {
1.434 array_release(&ii->actions);
1.435 deque_free(ii->order);
1.436 + deque_free(ii->left);
1.437 free(ii);
1.438 }