librazor/atomic-actions.c
changeset 493 06f70d662e39
parent 471 a3e5e3eaf224
     1.1 --- a/librazor/atomic-actions.c	Thu Jun 09 17:37:09 2016 +0100
     1.2 +++ b/librazor/atomic-actions.c	Mon Mar 05 09:43:14 2018 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (C) 2012  J. Ali Harlow <ali@juiblex.co.uk>
     1.6 + * Copyright (C) 2012, 2016  J. Ali Harlow <ali@juiblex.co.uk>
     1.7   *
     1.8   * This program is free software; you can redistribute it and/or modify
     1.9   * it under the terms of the GNU General Public License as published by
    1.10 @@ -25,9 +25,6 @@
    1.11  #include <string.h>
    1.12  #include <limits.h>
    1.13  #include <errno.h>
    1.14 -#include <sys/stat.h>
    1.15 -#include <sys/types.h>
    1.16 -#include <dirent.h>
    1.17  #include <assert.h>
    1.18  #include "razor-internal.h"
    1.19  
    1.20 @@ -87,7 +84,7 @@
    1.21  	while(action) {
    1.22  		a = atomic_action_list_pop_head(&action);
    1.23  
    1.24 -		free(a->args.path);
    1.25 +		free(a->args.uri);
    1.26  
    1.27  		switch(a->type) {
    1.28  		case ACTION_MAKE_DIRS:
    1.29 @@ -166,13 +163,11 @@
    1.30  
    1.31  	strcpy(buffer, action->args.u.make_dirs.root);
    1.32  	p = buffer + strlen(buffer);
    1.33 -	slash = action->args.path;
    1.34 +	slash = action->args.uri;
    1.35 +	if (p > buffer && p[-1] != ':' && p[-1] != '/' && *slash != '/')
    1.36 +		*p++ = '/';
    1.37  	for (; *slash != '\0'; slash = next) {
    1.38 -#ifdef MSWIN_API
    1.39 -		next = strpbrk(slash + 1, "/\\");
    1.40 -#else
    1.41  		next = strchr(slash + 1, '/');
    1.42 -#endif
    1.43  		if (next == NULL)
    1.44  			break;
    1.45  
    1.46 @@ -184,7 +179,7 @@
    1.47  			continue;
    1.48  
    1.49  		prim = atomic_action_new(ACTION_CREATE_DIR);
    1.50 -		prim->args.path = strdup(buffer);
    1.51 +		prim->args.uri = strdup(buffer);
    1.52  		prim->args.u.create_dir.mode = S_IRWXU | S_IRWXG | S_IRWXO;
    1.53  		primitives = atomic_action_list_prepend(primitives, prim);
    1.54  	}
    1.55 @@ -198,12 +193,8 @@
    1.56  static struct atomic_action *
    1.57  atomic_action_remove(struct razor_atomic *atomic, struct atomic_action *action)
    1.58  {
    1.59 -#ifdef MSWIN_API
    1.60 -	wchar_t *path;
    1.61 -	_WDIR *dir;
    1.62 -#else
    1.63 -	DIR *dir;
    1.64 -#endif
    1.65 +	void *dir;
    1.66 +	char *name;
    1.67  	struct atomic_action *prim;
    1.68  
    1.69  	if (razor_atomic_in_error_state(atomic)) {
    1.70 @@ -214,27 +205,20 @@
    1.71  	/*
    1.72  	 * Non-empty directories should NOT be removed
    1.73  	 */
    1.74 -#ifdef MSWIN_API
    1.75 -	path = razor_utf8_to_utf16(action->args.path, -1);
    1.76 -
    1.77 -	dir = _wopendir(path);
    1.78 -	if (dir && _wreaddir(dir)) {
    1.79 -		atomic_action_free(action);
    1.80 -		action = NULL;
    1.81 +	dir = razor_uri_opendir(action->args.uri, NULL);
    1.82 +	if (dir) {
    1.83 +		name = razor_uri_readdir(dir, NULL);
    1.84 +		razor_uri_closedir(dir, NULL);
    1.85 +		if (name) {
    1.86 +			free(name);
    1.87 +			atomic_action_free(action);
    1.88 +			action = NULL;
    1.89 +		}
    1.90  	}
    1.91 -	_wclosedir(dir);
    1.92 -#else
    1.93 -	dir = opendir(action->args.path);
    1.94 -	if (dir && readdir(dir)) {
    1.95 -		atomic_action_free(action);
    1.96 -		action = NULL;
    1.97 -	}
    1.98 -	closedir(dir);
    1.99 -#endif
   1.100  
   1.101  	if (action) {
   1.102  		prim = atomic_action_new(ACTION_MOVE);
   1.103 -		prim->args.path = strdup(action->args.path);
   1.104 +		prim->args.uri = strdup(action->args.uri);
   1.105  		prim->args.u.move.dest = atomic_action_attic_tmpnam(atomic);
   1.106  
   1.107  		atomic_action_free(action);
   1.108 @@ -249,7 +233,7 @@
   1.109  			 struct atomic_action *action)
   1.110  {
   1.111  	mode_t mode;
   1.112 -	struct stat buf;
   1.113 +	struct razor_error **error;
   1.114  
   1.115  	if (razor_atomic_in_error_state(atomic)) {
   1.116  		atomic_action_free(action);
   1.117 @@ -258,21 +242,14 @@
   1.118  
   1.119  	mode = action->args.u.create_dir.mode & (S_IRWXU | S_IRWXG | S_IRWXO);
   1.120  
   1.121 -	if (!mkdir(action->args.path, mode))
   1.122 +	if (atomic->error)
   1.123 +		error = NULL;
   1.124 +	else
   1.125 +		error = &atomic->error;
   1.126 +
   1.127 +	if (!razor_uri_mkdir(action->args.uri, mode, error))
   1.128  		return action;
   1.129  
   1.130 -	if (errno != EEXIST || stat(action->args.path, &buf)) {
   1.131 -		if (!atomic->error)
   1.132 -			atomic->error = razor_error_new_posix(action->args.path);
   1.133 -		atomic_action_free(action);
   1.134 -		return NULL;
   1.135 -	}
   1.136 -
   1.137 -	if (!S_ISDIR(buf.st_mode) && !atomic->error)
   1.138 -		atomic->error = razor_error_new_str(RAZOR_POSIX_ERROR, EEXIST,
   1.139 -						    action->args.path,
   1.140 -						    "Not a directory");
   1.141 -
   1.142  	atomic_action_free(action);
   1.143  	return NULL;
   1.144  }
   1.145 @@ -285,9 +262,9 @@
   1.146  		return NULL;
   1.147  	}
   1.148  
   1.149 -	if (rmdir(action->args.path) < 0) {
   1.150 +	if (rmdir(action->args.uri) < 0) {
   1.151  		if (!atomic->error)
   1.152 -			atomic->error = razor_error_new_posix(action->args.path);
   1.153 +			atomic->error = razor_error_new_posix(action->args.uri);
   1.154  		atomic_action_free(action);
   1.155  		return NULL;
   1.156  	} else
   1.157 @@ -306,10 +283,10 @@
   1.158  		return NULL;
   1.159  	}
   1.160  
   1.161 -	r = symlink(action->args.u.create_symlink.target, action->args.path);
   1.162 +	r = symlink(action->args.u.create_symlink.target, action->args.uri);
   1.163  	if (r < 0) {
   1.164  		if (!atomic->error)
   1.165 -			atomic->error = razor_error_new_posix(action->args.path);
   1.166 +			atomic->error = razor_error_new_posix(action->args.uri);
   1.167  		atomic_action_free(action);
   1.168  		return NULL;
   1.169  	}
   1.170 @@ -321,14 +298,19 @@
   1.171  atomic_action_remove_symlink(struct razor_atomic *atomic,
   1.172  			     struct atomic_action *action)
   1.173  {
   1.174 +	struct razor_error **error;
   1.175 +
   1.176  	if (razor_atomic_in_error_state(atomic)) {
   1.177  		atomic_action_free(action);
   1.178  		return NULL;
   1.179  	}
   1.180  
   1.181 -	if (unlink(action->args.path) < 0) {
   1.182 -		if (!atomic->error)
   1.183 -			atomic->error = razor_error_new_posix(action->args.path);
   1.184 +	if (atomic->error)
   1.185 +		error = NULL;
   1.186 +	else
   1.187 +		error = &atomic->error;
   1.188 +
   1.189 +	if (razor_uri_unlink(action->args.uri, error)) {
   1.190  		atomic_action_free(action);
   1.191  		return NULL;
   1.192  	}
   1.193 @@ -338,52 +320,16 @@
   1.194  #endif
   1.195  
   1.196  static int
   1.197 -move_file(struct razor_atomic *atomic, const char *path, const char *dest)
   1.198 +move_file(struct razor_atomic *atomic, const char *uri, const char *dest)
   1.199  {
   1.200 -#ifdef MSWIN_API
   1.201 -	wchar_t *oldbuf, *newbuf;
   1.202 -	const DWORD flags = MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING;
   1.203 +	struct razor_error **error;
   1.204  
   1.205 -	newbuf = razor_utf8_to_utf16(dest, -1);
   1.206 -	oldbuf = razor_utf8_to_utf16(path, -1);
   1.207 +	if (atomic->error)
   1.208 +		error = NULL;
   1.209 +	else
   1.210 +		error = &atomic->error;
   1.211  
   1.212 -	/*
   1.213 -	 * Passing MOVEFILE_REPLACE_EXISTING to MoveFileEx() will
   1.214 -	 * cover every case we care about _except_ replacing an empty
   1.215 -	 * directory with a file. Calling RemoveDirectory() will deal
   1.216 -	 * with this case while having no effect in all other cases.
   1.217 -	 */
   1.218 -	(void)RemoveDirectoryW(newbuf);
   1.219 -
   1.220 -	if (!MoveFileExW(oldbuf, newbuf, flags)) {
   1.221 -		if (!atomic->error)
   1.222 -			atomic->error = razor_error_new_mswin(newbuf,
   1.223 -							      GetLastError());
   1.224 -		return -1;
   1.225 -	}
   1.226 -
   1.227 -	free(newbuf);
   1.228 -	free(oldbuf);
   1.229 -#else
   1.230 -	int code;
   1.231 -	const char *object;
   1.232 -
   1.233 -	if (rename(path, dest)) {
   1.234 -		if (!atomic->error) {
   1.235 -			code = errno;
   1.236 -			if (access(path, F_OK) < 0)
   1.237 -				object = path;
   1.238 -			else
   1.239 -				object = dest;
   1.240 -			atomic->error = razor_error_new_str(RAZOR_POSIX_ERROR,
   1.241 -							    code, object,
   1.242 -							    strerror(code));
   1.243 -		}
   1.244 -		return -1;
   1.245 -	}
   1.246 -#endif
   1.247 -
   1.248 -	return 0;
   1.249 +	return razor_uri_move(uri, dest, error);
   1.250  }
   1.251  
   1.252  static struct atomic_action *
   1.253 @@ -394,7 +340,7 @@
   1.254  		return NULL;
   1.255  	}
   1.256  
   1.257 -	if (move_file(atomic, action->args.path, action->args.u.move.dest)) {
   1.258 +	if (move_file(atomic, action->args.uri, action->args.u.move.dest)) {
   1.259  		atomic_action_free(action);
   1.260  		return NULL;
   1.261  	}
   1.262 @@ -410,7 +356,7 @@
   1.263  		return NULL;
   1.264  	}
   1.265  
   1.266 -	if (move_file(atomic, action->args.u.move.dest, action->args.path)) {
   1.267 +	if (move_file(atomic, action->args.u.move.dest, action->args.uri)) {
   1.268  		atomic_action_free(action);
   1.269  		return NULL;
   1.270  	}