Add error domains and codes
authorJ. Ali Harlow <ali@juiblex.co.uk>
Tue Sep 09 15:27:12 2014 +0100 (2014-09-09)
changeset 4470a5e583393e1
parent 446 4277359896dc
child 448 8476d35b048f
Add error domains and codes
librazor/atomic-actions.c
librazor/atomic-emulate.c
librazor/atomic-ktm.c
librazor/atomic.c
librazor/error.c
librazor/razor-internal.h
librazor/razor.c
librazor/razor.h
librazor/root.c
librazor/rpm.c
librazor/util.c
src/main.c
     1.1 --- a/librazor/atomic-actions.c	Tue Sep 09 15:04:24 2014 +0100
     1.2 +++ b/librazor/atomic-actions.c	Tue Sep 09 15:27:12 2014 +0100
     1.3 @@ -260,8 +260,7 @@
     1.4  
     1.5  	if (errno != EEXIST || chmod(action->args.path, mode) < 0) {
     1.6  		if (!atomic->error)
     1.7 -			atomic->error = razor_error_new_str(action->args.path,
     1.8 -							    strerror(errno));
     1.9 +			atomic->error = razor_error_new_posix(action->args.path);
    1.10  		atomic_action_free(action);
    1.11  		return NULL;
    1.12  	}
    1.13 @@ -279,8 +278,7 @@
    1.14  
    1.15  	if (rmdir(action->args.path) < 0) {
    1.16  		if (!atomic->error)
    1.17 -			atomic->error = razor_error_new_str(action->args.path,
    1.18 -							    strerror(errno));
    1.19 +			atomic->error = razor_error_new_posix(action->args.path);
    1.20  		atomic_action_free(action);
    1.21  		return NULL;
    1.22  	} else
    1.23 @@ -302,8 +300,7 @@
    1.24  	r = symlink(action->args.u.create_symlink.target, action->args.path);
    1.25  	if (r < 0) {
    1.26  		if (!atomic->error)
    1.27 -			atomic->error = razor_error_new_str(action->args.path,
    1.28 -							    strerror(errno));
    1.29 +			atomic->error = razor_error_new_posix(action->args.path);
    1.30  		atomic_action_free(action);
    1.31  		return NULL;
    1.32  	}
    1.33 @@ -322,8 +319,7 @@
    1.34  
    1.35  	if (unlink(action->args.path) < 0) {
    1.36  		if (!atomic->error)
    1.37 -			atomic->error = razor_error_new_str(action->args.path,
    1.38 -							    strerror(errno));
    1.39 +			atomic->error = razor_error_new_posix(action->args.path);
    1.40  		atomic_action_free(action);
    1.41  		return NULL;
    1.42  	}
    1.43 @@ -362,8 +358,7 @@
    1.44  #else
    1.45  	if (rename(path, dest)) {
    1.46  		if (!atomic->error)
    1.47 -			atomic->error = razor_error_new_str(dest,
    1.48 -							    strerror(errno));
    1.49 +			atomic->error = razor_error_new_posix(dest);
    1.50  		return -1;
    1.51  	}
    1.52  #endif
     2.1 --- a/librazor/atomic-emulate.c	Tue Sep 09 15:04:24 2014 +0100
     2.2 +++ b/librazor/atomic-emulate.c	Tue Sep 09 15:27:12 2014 +0100
     2.3 @@ -244,14 +244,12 @@
     2.4  
     2.5  		abspath = absolute_path(path);
     2.6  		if (!abspath) {
     2.7 -			atomic->error = razor_error_new_str(path,
     2.8 -							    strerror(errno));
     2.9 +			atomic->error = razor_error_new_posix(path);
    2.10  			return -1;
    2.11  		}
    2.12  
    2.13  		if (stat(abspath, &buf) < 0) {
    2.14 -			atomic->error = razor_error_new_str(abspath,
    2.15 -							    strerror(errno));
    2.16 +			atomic->error = razor_error_new_posix(abspath);
    2.17  			free(abspath);
    2.18  			return -1;
    2.19  		}
    2.20 @@ -269,8 +267,7 @@
    2.21  			}
    2.22  
    2.23  			if (stat(abspath, &buf) < 0) {
    2.24 -				atomic->error =
    2.25 -				  razor_error_new_str(abspath, strerror(errno));
    2.26 +				atomic->error = razor_error_new_posix(abspath);
    2.27  				free(abspath);
    2.28  				return -1;
    2.29  			}
    2.30 @@ -304,8 +301,7 @@
    2.31  
    2.32  #ifndef MSWIN_API
    2.33  			if (stat(".", &buf) < 0) {
    2.34 -				atomic->error =
    2.35 -				  razor_error_new_str(".", strerror(errno));
    2.36 +				atomic->error = razor_error_new_posix(".");
    2.37  				free(s);
    2.38  				free(atomic->toplevel);
    2.39  				atomic->toplevel = NULL;
    2.40 @@ -329,7 +325,8 @@
    2.41  		}
    2.42  #endif
    2.43  
    2.44 -		atomic->error = razor_error_new_str(atomic->toplevel,
    2.45 +		atomic->error = razor_error_new_str(RAZOR_POSIX_ERROR, err,
    2.46 +						    atomic->toplevel,
    2.47  						    strerror(err));
    2.48  
    2.49  		free(atomic->toplevel);
    2.50 @@ -434,7 +431,7 @@
    2.51  
    2.52  	return 0;
    2.53  #else
    2.54 -	atomic->error = razor_error_new_str(NULL,
    2.55 +	atomic->error = razor_error_new_str(RAZOR_POSIX_ERROR, ENOSYS, NULL,
    2.56  					    "Symbolic links not supported "
    2.57  					    "on this platform");
    2.58  
    2.59 @@ -460,7 +457,7 @@
    2.60  		  mode & (S_IRWXU | S_IRWXG | S_IRWXO));
    2.61  
    2.62  	if (fd == -1)
    2.63 -		atomic->error = razor_error_new_str(filename, strerror(errno));
    2.64 +		atomic->error = razor_error_new_posix(filename);
    2.65  	else {
    2.66  		a = atomic_action_new(ACTION_MOVE);
    2.67  		a->args.path = tmpnam;
     3.1 --- a/librazor/atomic-ktm.c	Tue Sep 09 15:04:24 2014 +0100
     3.2 +++ b/librazor/atomic-ktm.c	Tue Sep 09 15:27:12 2014 +0100
     3.3 @@ -214,7 +214,9 @@
     3.4  				}
     3.5  			} else if (!(fa.dwFileAttributes&
     3.6  				     FILE_ATTRIBUTE_DIRECTORY)) {
     3.7 -				razor_set_error2(&atomic->error, buffer->str,
     3.8 +				razor_set_error2(&atomic->error,
     3.9 +						 RAZOR_MSWIN_ERROR,
    3.10 +						 ERROR_DIRECTORY, buffer->str,
    3.11  						 "Not a directory");
    3.12  				razor_wstr_destroy(buffer);
    3.13  				return -1;
    3.14 @@ -378,8 +380,8 @@
    3.15  	 * and we don't always know that at the time when the
    3.16  	 * link is created, so it's a convienent lie for now.
    3.17  	 */
    3.18 -	razor_set_error(&atomic->error, NULL,
    3.19 -			"Symbolic links not supported on this platform");
    3.20 +	razor_set_error(&atomic->error, RAZOR_MSWIN_ERROR, ERROR_NOT_SUPPORTED,
    3.21 +			NULL, "Symbolic links not supported on this platform");
    3.22  
    3.23  	return -1;
    3.24  }
    3.25 @@ -398,7 +400,8 @@
    3.26  	files = realloc(atomic->files,
    3.27  			(atomic->n_files+1) * sizeof(struct razor_atomic_file));
    3.28  	if (!files) {
    3.29 -		razor_set_error(&atomic->error, NULL, "Not enough memory");
    3.30 +		razor_set_error(&atomic->error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    3.31 +				"Not enough memory");
    3.32  		return -1;
    3.33  	}
    3.34  	atomic->n_files++;
     4.1 --- a/librazor/atomic.c	Tue Sep 09 15:04:24 2014 +0100
     4.2 +++ b/librazor/atomic.c	Tue Sep 09 15:27:12 2014 +0100
     4.3 @@ -69,10 +69,20 @@
     4.4  }
     4.5  
     4.6  RAZOR_EXPORT void
     4.7 -razor_atomic_abort(struct razor_atomic *atomic, const char *error_msg)
     4.8 +razor_atomic_abort(struct razor_atomic *atomic, int domain, int code,
     4.9 +		   const char *error_msg)
    4.10  {
    4.11  	if (!atomic->error)
    4.12 -		atomic->error = razor_error_new_str(NULL, error_msg);
    4.13 +		atomic->error = razor_error_new_str(domain, code, NULL,
    4.14 +						    error_msg);
    4.15 +}
    4.16 +
    4.17 +RAZOR_EXPORT void
    4.18 +razor_atomic_propagate_error(struct razor_atomic *atomic,
    4.19 +			     struct razor_error *error, const char *summary)
    4.20 +{
    4.21 +	if (!atomic->error)
    4.22 +		atomic->error = razor_error_dup(error, summary);
    4.23  }
    4.24  
    4.25  RAZOR_EXPORT int
    4.26 @@ -121,8 +131,7 @@
    4.27  	while(size) {
    4.28  		written = write(fd, data, size);
    4.29  		if (written < 0) {
    4.30 -			atomic->error = razor_error_new_str(NULL,
    4.31 -							    strerror(errno));
    4.32 +			atomic->error = razor_error_new_posix(NULL);
    4.33  
    4.34  			(void)close(fd);
    4.35  
    4.36 @@ -143,7 +152,7 @@
    4.37  		return -1;
    4.38  
    4.39  	if (fsync(handle) < 0) {
    4.40 -		atomic->error = razor_error_new_str(NULL, strerror(errno));
    4.41 +		atomic->error = razor_error_new_posix(NULL);
    4.42  		return -1;
    4.43  	}
    4.44  
    4.45 @@ -157,7 +166,7 @@
    4.46  		return -1;
    4.47  
    4.48  	if (close(fd) < 0) {
    4.49 -		atomic->error = razor_error_new_str(NULL, strerror(errno));
    4.50 +		atomic->error = razor_error_new_posix(NULL);
    4.51  		return -1;
    4.52  	}
    4.53  
     5.1 --- a/librazor/error.c	Tue Sep 09 15:04:24 2014 +0100
     5.2 +++ b/librazor/error.c	Tue Sep 09 15:27:12 2014 +0100
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (C) 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     5.6 + * Copyright (C) 2011-2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
     5.7   *
     5.8   * This program is free software; you can redistribute it and/or modify
     5.9   * it under the terms of the GNU General Public License as published by
    5.10 @@ -27,15 +27,33 @@
    5.11  #include "razor.h"
    5.12  #include "razor-internal.h"
    5.13  
    5.14 -static const char *razor_error_get_path_str(struct razor_error *error)
    5.15 +RAZOR_EXPORT int
    5.16 +razor_error_get_domain(struct razor_error *error)
    5.17  {
    5.18 -	if (error->path_str)
    5.19 -		return error->path_str;
    5.20 +	return error->domain;
    5.21 +}
    5.22  
    5.23 -	if (error->path) {
    5.24 -		error->path_str = razor_concat(error->path, ": ",
    5.25 -					       error->str, NULL);
    5.26 -		return error->path_str;
    5.27 +RAZOR_EXPORT int
    5.28 +razor_error_get_code(struct razor_error *error)
    5.29 +{
    5.30 +	return error->code;
    5.31 +}
    5.32 +
    5.33 +RAZOR_EXPORT const char *
    5.34 +razor_error_get_object(struct razor_error *error)
    5.35 +{
    5.36 +	return error->object;
    5.37 +}
    5.38 +
    5.39 +static const char *razor_error_get_obj_str(struct razor_error *error)
    5.40 +{
    5.41 +	if (error->obj_str)
    5.42 +		return error->obj_str;
    5.43 +
    5.44 +	if (error->object) {
    5.45 +		error->obj_str = razor_concat(error->object, ": ",
    5.46 +					      error->str, NULL);
    5.47 +		return error->obj_str;
    5.48  	}
    5.49  
    5.50  	return error->str;
    5.51 @@ -46,7 +64,7 @@
    5.52   *
    5.53   * Retrieves the basic information about an error. If a summary has been set
    5.54   * then this will be returned. Otherwise the error string possibly prefixed
    5.55 - * by the path will be returned instead.
    5.56 + * by the object will be returned instead.
    5.57   *
    5.58   * Returns: Primary text of error.
    5.59   **/
    5.60 @@ -56,14 +74,14 @@
    5.61  	if (error->summary)
    5.62  		return error->summary;
    5.63  
    5.64 -	return razor_error_get_path_str(error);
    5.65 +	return razor_error_get_obj_str(error);
    5.66  }
    5.67  
    5.68  /**
    5.69   * razor_error_get_secondary_text:
    5.70   *
    5.71   * Retrieves more detailed information about an error, if any. If a summary
    5.72 - * has been set the error string possibly prefixed by the path will be
    5.73 + * has been set the error string possibly prefixed by the object will be
    5.74   * returned. Otherwise NULL will be returned.
    5.75   *
    5.76   * Returns: Secondary text of error or NULL.
    5.77 @@ -74,7 +92,7 @@
    5.78  	if (!error->summary)
    5.79  		return NULL;
    5.80  
    5.81 -	return razor_error_get_path_str(error);
    5.82 +	return razor_error_get_obj_str(error);
    5.83  }
    5.84  
    5.85  RAZOR_EXPORT const char *
    5.86 @@ -98,15 +116,18 @@
    5.87  
    5.88  #ifdef MSWIN_API
    5.89  struct razor_error *
    5.90 -razor_error_new_mswin(const wchar_t *path, DWORD err)
    5.91 +razor_error_new_mswin(const wchar_t *object, DWORD err)
    5.92  {
    5.93  	struct razor_error *error;
    5.94  	wchar_t *buf;
    5.95  
    5.96  	error = zalloc(sizeof *error);
    5.97  
    5.98 -	if (path)
    5.99 -		error->path = razor_utf16_to_utf8(path, -1);
   5.100 +	error->domain = RAZOR_MSWIN_ERROR;
   5.101 +	error->code = err;
   5.102 +
   5.103 +	if (object)
   5.104 +		error->object = razor_utf16_to_utf8(object, -1);
   5.105  
   5.106  	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|
   5.107  		       FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
   5.108 @@ -119,14 +140,18 @@
   5.109  }
   5.110  
   5.111  struct razor_error *
   5.112 -razor_error_new_str2(const wchar_t *path, const char *str)
   5.113 +razor_error_new_str2(int domain, int code, const wchar_t *object,
   5.114 +		     const char *str)
   5.115  {
   5.116  	struct razor_error *error;
   5.117  
   5.118  	error = zalloc(sizeof *error);
   5.119  
   5.120 -	if (path)
   5.121 -		error->path = razor_utf16_to_utf8(path, -1);
   5.122 +	error->domain = domain;
   5.123 +	error->code = code;
   5.124 +
   5.125 +	if (object)
   5.126 +		error->object = razor_utf16_to_utf8(object, -1);
   5.127  
   5.128  	error->str = strdup(str);
   5.129  
   5.130 @@ -135,14 +160,17 @@
   5.131  #endif	/* MSWIN_API */
   5.132  
   5.133  RAZOR_EXPORT struct razor_error *
   5.134 -razor_error_new_str(const char *path, const char *str)
   5.135 +razor_error_new_str(int domain, int code, const char *object, const char *str)
   5.136  {
   5.137  	struct razor_error *error;
   5.138  
   5.139  	error = zalloc(sizeof *error);
   5.140  
   5.141 -	if (path)
   5.142 -		error->path = strdup(path);
   5.143 +	error->domain = domain;
   5.144 +	error->code = code;
   5.145 +
   5.146 +	if (object)
   5.147 +		error->object = strdup(object);
   5.148  
   5.149  	error->str = strdup(str);
   5.150  
   5.151 @@ -156,13 +184,16 @@
   5.152  
   5.153  	error = zalloc(sizeof *error);
   5.154  
   5.155 +	error->domain = src->domain;
   5.156 +	error->code = src->code;
   5.157 +
   5.158  	if (summary)
   5.159  		error->summary = strdup(summary);
   5.160  	else if (src->summary)
   5.161  		error->summary = strdup(src->summary);
   5.162  
   5.163 -	if (src->path)
   5.164 -		error->path = strdup(src->path);
   5.165 +	if (src->object)
   5.166 +		error->object = strdup(src->object);
   5.167  
   5.168  	if (src->str)
   5.169  		error->str = strdup(src->str);
   5.170 @@ -173,9 +204,9 @@
   5.171  RAZOR_EXPORT void
   5.172  razor_error_free(struct razor_error *error)
   5.173  {
   5.174 -	free(error->path);
   5.175 +	free(error->object);
   5.176  	free(error->str);
   5.177 -	free(error->path_str);
   5.178 +	free(error->obj_str);
   5.179  	free(error->summary);
   5.180  	free(error->msg);
   5.181  	free(error);
     6.1 --- a/librazor/razor-internal.h	Tue Sep 09 15:04:24 2014 +0100
     6.2 +++ b/librazor/razor-internal.h	Tue Sep 09 15:27:12 2014 +0100
     6.3 @@ -1,7 +1,7 @@
     6.4  /*
     6.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     6.6   * Copyright (C) 2008  Red Hat, Inc
     6.7 - * Copyright (C) 2009, 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     6.8 + * Copyright (C) 2009, 2011-2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
     6.9   *
    6.10   * This program is free software; you can redistribute it and/or modify
    6.11   * it under the terms of the GNU General Public License as published by
    6.12 @@ -247,24 +247,35 @@
    6.13  
    6.14  /* Error functions */
    6.15  struct razor_error {
    6.16 -	char *path;
    6.17 +	int domain;
    6.18 +	int code;
    6.19 +	char *object;
    6.20  	char *str;
    6.21 -	char *path_str;
    6.22 +	char *obj_str;
    6.23  	char *summary;
    6.24  	char *msg;
    6.25  };
    6.26  
    6.27 +#define razor_error_new_posix(object) \
    6.28 +	razor_error_new_str(RAZOR_POSIX_ERROR, errno, object, strerror(errno))
    6.29 +#define razor_set_error_posix(error, object) \
    6.30 +	if (error) \
    6.31 +		*(error) = razor_error_new_posix(object); \
    6.32 +	else
    6.33 +
    6.34  #ifdef MSWIN_API
    6.35 -struct razor_error *razor_error_new_mswin(const wchar_t *path, DWORD error);
    6.36 -struct razor_error *razor_error_new_str2(const wchar_t *path, const char *str);
    6.37 +struct razor_error *razor_error_new_mswin(const wchar_t *object, DWORD error);
    6.38 +struct razor_error *razor_error_new_str2(int domain, int code,
    6.39 +					 const wchar_t *object,
    6.40 +					 const char *str);
    6.41  
    6.42 -#define razor_set_error_mswin(error, path, err) \
    6.43 +#define razor_set_error_mswin(error, object, err) \
    6.44  	if (error) \
    6.45 -		*(error) = razor_error_new_mswin(path, err); \
    6.46 +		*(error) = razor_error_new_mswin(object, err); \
    6.47  	else
    6.48 -#define razor_set_error2(error, path, str) \
    6.49 +#define razor_set_error2(error, domain, code, object, str) \
    6.50  	if (error) \
    6.51 -		*(error) = razor_error_new_str2(path, str); \
    6.52 +		*(error) = razor_error_new_str2(domain, code, object, str); \
    6.53  	else
    6.54  #endif	/* MSWIN_API */
    6.55  
     7.1 --- a/librazor/razor.c	Tue Sep 09 15:04:24 2014 +0100
     7.2 +++ b/librazor/razor.c	Tue Sep 09 15:27:12 2014 +0100
     7.3 @@ -147,11 +147,12 @@
     7.4  	struct razor_mapped_file *file;
     7.5  	const char *pool, *reason;
     7.6  	struct array *array;
     7.7 -	int i, j;
     7.8 +	int i, j, code;
     7.9  
    7.10  	file = zalloc(sizeof *file);
    7.11  	if (file == NULL) {
    7.12 -		razor_set_error(error, NULL, "Not enough memory");
    7.13 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    7.14 +				"Not enough memory");
    7.15  		return -1;
    7.16  	}
    7.17  
    7.18 @@ -163,18 +164,22 @@
    7.19  		return -1;
    7.20  	}
    7.21  
    7.22 -	if (file->size < sizeof *file->header)
    7.23 +	if (file->size < sizeof *file->header) {
    7.24 +		code = RAZOR_GENERAL_ERROR_DATABASE_CORRUPTED;
    7.25  		reason = "Premature EOF";
    7.26 -	else if (file->header->magic != RAZOR_MAGIC)
    7.27 +	} else if (file->header->magic != RAZOR_MAGIC) {
    7.28 +		code = RAZOR_GENERAL_ERROR_DATABASE_CORRUPTED;
    7.29  		reason = "Bad magic number";
    7.30 -	else if (file->header->version < RAZOR_HEADER_VERSION_MIN ||
    7.31 -		 file->header->version > RAZOR_HEADER_VERSION)
    7.32 +	} else if (file->header->version < RAZOR_HEADER_VERSION_MIN ||
    7.33 +		   file->header->version > RAZOR_HEADER_VERSION) {
    7.34 +		code = RAZOR_GENERAL_ERROR_DATABASE_INCOMPATIBLE;
    7.35  		reason = "Incompatible file version";
    7.36 -	else
    7.37 +	} else
    7.38  		reason = NULL;
    7.39  
    7.40  	if (reason) {
    7.41 -		razor_set_error(error, filename, reason);
    7.42 +		razor_set_error(error, RAZOR_GENERAL_ERROR, code, filename,
    7.43 +				reason);
    7.44  		razor_file_free_contents(file->header, file->size);
    7.45  		free(file);
    7.46  		return -1;
    7.47 @@ -222,7 +227,8 @@
    7.48  
    7.49  	set = zalloc(sizeof *set);
    7.50  	if (!set) {
    7.51 -		razor_set_error(error, NULL, "Not enough memory");
    7.52 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    7.53 +				"Not enough memory");
    7.54  		return NULL;
    7.55  	}
    7.56  
     8.1 --- a/librazor/razor.h	Tue Sep 09 15:04:24 2014 +0100
     8.2 +++ b/librazor/razor.h	Tue Sep 09 15:27:12 2014 +0100
     8.3 @@ -114,13 +114,14 @@
     8.4   */
     8.5  struct razor_error;
     8.6  
     8.7 -struct razor_error *razor_error_new_str(const char *path, const char *str);
     8.8 +struct razor_error *razor_error_new_str(int domain, int code,
     8.9 +					const char *object, const char *str);
    8.10  struct razor_error *razor_error_dup(struct razor_error *src,
    8.11  				    const char *summary);
    8.12  
    8.13 -#define razor_set_error(error, path, str) \
    8.14 +#define razor_set_error(error, domain, code, object, str) \
    8.15  	if (error) \
    8.16 -		*(error) = razor_error_new_str(path, str); \
    8.17 +		*(error) = razor_error_new_str(domain, code, object, str); \
    8.18  	else
    8.19  
    8.20  #define razor_propagate_error(dest, src, summary) \
    8.21 @@ -128,6 +129,26 @@
    8.22  		*(dest) = razor_error_dup(src, summary); \
    8.23  	else
    8.24  
    8.25 +#define RAZOR_ERROR_DOMAIN(i1,i2,i3,c) \
    8.26 +	(((i1)&0xff)<<24|((i2)&0xff)<<16|((i3)&0xff)<<8|(c)&0xff)
    8.27 +
    8.28 +#define RAZOR_GENERAL_ERROR	RAZOR_ERROR_DOMAIN('R','z','r',0)
    8.29 +#define RAZOR_POSIX_ERROR	RAZOR_ERROR_DOMAIN('R','z','r',1)
    8.30 +#define RAZOR_MSWIN_ERROR	RAZOR_ERROR_DOMAIN('R','z','r',2)
    8.31 +#define RAZOR_ZLIB_ERROR	RAZOR_ERROR_DOMAIN('R','z','r',3)
    8.32 +
    8.33 +enum razor_general_error {
    8.34 +	RAZOR_GENERAL_ERROR_FAILED,
    8.35 +	RAZOR_GENERAL_ERROR_DATABASE_CORRUPTED,
    8.36 +	RAZOR_GENERAL_ERROR_DATABASE_INCOMPATIBLE,
    8.37 +	RAZOR_GENERAL_ERROR_DATABASE_EXISTS,
    8.38 +	RAZOR_GENERAL_ERROR_DATABASE_LOCKED,
    8.39 +	RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
    8.40 +};
    8.41 +
    8.42 +int razor_error_get_domain(struct razor_error *error);
    8.43 +int razor_error_get_code(struct razor_error *error);
    8.44 +const char *razor_error_get_object(struct razor_error *error);
    8.45  const char *razor_error_get_primary_text(struct razor_error *error);
    8.46  const char *razor_error_get_secondary_text(struct razor_error *error);
    8.47  const char *razor_error_get_msg(struct razor_error *error);
    8.48 @@ -215,7 +236,10 @@
    8.49    const void *data, size_t size);
    8.50  int razor_atomic_close(struct razor_atomic *atomic, int handle);
    8.51  int razor_atomic_sync(struct razor_atomic *atomic, int handle);
    8.52 -void razor_atomic_abort(struct razor_atomic *atomic, const char *error_msg);
    8.53 +void razor_atomic_abort(struct razor_atomic *atomic, int domain, int code,
    8.54 +  const char *error_msg);
    8.55 +void razor_atomic_propagate_error(struct razor_atomic *atomic,
    8.56 +  struct razor_error *error, const char *summary);
    8.57  int razor_atomic_in_error_state(struct razor_atomic *atomic);
    8.58  
    8.59  /**
     9.1 --- a/librazor/root.c	Tue Sep 09 15:04:24 2014 +0100
     9.2 +++ b/librazor/root.c	Tue Sep 09 15:27:12 2014 +0100
     9.3 @@ -24,6 +24,7 @@
     9.4  #include <stdint.h>
     9.5  #include <stdio.h>
     9.6  #include <string.h>
     9.7 +#include <errno.h>
     9.8  #include <sys/stat.h>
     9.9  #include <dirent.h>
    9.10  #include <unistd.h>
    9.11 @@ -125,12 +126,13 @@
    9.12  		/* root is file system root */
    9.13  	} else if (stat(root, &buf) < 0) {
    9.14  		if (mkdir(root, 0777) < 0) {
    9.15 -			razor_set_error(error, root,
    9.16 +			razor_set_error(error, RAZOR_POSIX_ERROR, errno, root,
    9.17  					"Could not create install root");
    9.18  			return -1;
    9.19  		}
    9.20  	} else if (!S_ISDIR(buf.st_mode)) {
    9.21 -		razor_set_error(error, root, "Not a directory");
    9.22 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOTDIR, root,
    9.23 +				"Not a directory");
    9.24  		return -1;
    9.25  	}
    9.26  
    9.27 @@ -139,7 +141,8 @@
    9.28  	path = razor_path_add_root(file, root);
    9.29  	retval = !stat(path, &buf);
    9.30  	if (retval) {
    9.31 -		razor_set_error(error, NULL,
    9.32 +		razor_set_error(error, RAZOR_GENERAL_ERROR,
    9.33 +				RAZOR_GENERAL_ERROR_DATABASE_EXISTS, NULL,
    9.34  				"A razor install root is already initialized");
    9.35  		free(path);
    9.36  		free(file);
    9.37 @@ -175,14 +178,16 @@
    9.38  	razor_root_init();
    9.39  	image = malloc(sizeof *image);
    9.40  	if (image == NULL) {
    9.41 -		razor_set_error(error, NULL, "Not enough memory");
    9.42 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    9.43 +				"Not enough memory");
    9.44  		return NULL;
    9.45  	}
    9.46  
    9.47  	image->system = razor_set_create_without_root();
    9.48  	if (image->system == NULL) {
    9.49  		free(image);
    9.50 -		razor_set_error(error, NULL, "Not enough memory");
    9.51 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    9.52 +				"Not enough memory");
    9.53  		return NULL;
    9.54  	}
    9.55  
    9.56 @@ -195,7 +200,8 @@
    9.57  	free(lock_path);
    9.58  
    9.59  	if (r < 0) {
    9.60 -		razor_set_error(error, NULL,
    9.61 +		razor_set_error(error, RAZOR_GENERAL_ERROR,
    9.62 +				RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL,
    9.63  				"Failed to aquire exclusive system lock");
    9.64  		razor_set_unref(image->system);
    9.65  		free(image);
    9.66 @@ -228,7 +234,8 @@
    9.67  	razor_root_init();
    9.68  	set = razor_set_create_without_root();
    9.69  	if (set == NULL) {
    9.70 -		razor_set_error(error, NULL, "Not enough memory");
    9.71 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    9.72 +				"Not enough memory");
    9.73  		return NULL;
    9.74  	}
    9.75  
    9.76 @@ -237,7 +244,8 @@
    9.77  	free(s);
    9.78  
    9.79  	if (razor_set_aquire_lock(set, path, 0) < 0) {
    9.80 -		razor_set_error(error, NULL,
    9.81 +		razor_set_error(error, RAZOR_GENERAL_ERROR,
    9.82 +				RAZOR_GENERAL_ERROR_DATABASE_LOCKED, NULL,
    9.83  				"Failed to aquire non-exclusive system lock");
    9.84  		free(path);
    9.85  		razor_set_unref(set);
    10.1 --- a/librazor/rpm.c	Tue Sep 09 15:04:24 2014 +0100
    10.2 +++ b/librazor/rpm.c	Tue Sep 09 15:27:12 2014 +0100
    10.3 @@ -613,7 +613,8 @@
    10.4  
    10.5  	rpm = zalloc(sizeof *rpm);
    10.6  	if (rpm == NULL) {
    10.7 -		razor_set_error(error, NULL, "Not enough memory");
    10.8 +		razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
    10.9 +				"Not enough memory");
   10.10  		return NULL;
   10.11  	}
   10.12  	memset(rpm, 0, sizeof *rpm);
   10.13 @@ -650,7 +651,9 @@
   10.14  					      &count);
   10.15  		if (name) {
   10.16  			razor_rpm_close(rpm);
   10.17 -			razor_set_error(error, filename,
   10.18 +			razor_set_error(error, RAZOR_GENERAL_ERROR,
   10.19 +					RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
   10.20 +					filename,
   10.21  					"Old filenames not supported");
   10.22  			return NULL;
   10.23  		}
   10.24 @@ -670,7 +673,9 @@
   10.25  						&count);
   10.26  		if (prefix) {
   10.27  			razor_rpm_close(rpm);
   10.28 -			razor_set_error(error, filename,
   10.29 +			razor_set_error(error, RAZOR_GENERAL_ERROR,
   10.30 +					RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
   10.31 +					filename,
   10.32  					"Default prefix not supported");
   10.33  			return NULL;
   10.34  		}
   10.35 @@ -737,7 +742,8 @@
   10.36  	installer->stream.avail_out = length;
   10.37  	err = inflate(&installer->stream, Z_SYNC_FLUSH);
   10.38  	if (err != Z_OK && err != Z_STREAM_END) {
   10.39 -		razor_atomic_abort(installer->atomic, "Failed to inflate");
   10.40 +		razor_atomic_abort(installer->atomic, RAZOR_ZLIB_ERROR, err,
   10.41 +				   "Failed to inflate");
   10.42  		return -1;
   10.43  	}
   10.44  
   10.45 @@ -762,7 +768,8 @@
   10.46  
   10.47  	err = inflate(&installer->stream, Z_SYNC_FLUSH);
   10.48  	if (err != Z_OK && err != Z_STREAM_END) {
   10.49 -		razor_atomic_abort(installer->atomic, "Failed to inflate");
   10.50 +		razor_atomic_abort(installer->atomic, RAZOR_ZLIB_ERROR, err,
   10.51 +				   "Failed to inflate");
   10.52  		return -1;
   10.53  	}
   10.54  
   10.55 @@ -806,6 +813,8 @@
   10.56  			return -1;
   10.57  		if (installer->length >= sizeof installer->buffer) {
   10.58  			razor_atomic_abort(installer->atomic,
   10.59 +			  RAZOR_GENERAL_ERROR,
   10.60 +			  RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
   10.61  			  "Link target too long");
   10.62  			return -1;
   10.63  		}
   10.64 @@ -824,7 +833,8 @@
   10.65  		free(buffer);
   10.66  		buffer = razor_concat(s, " are not supported on this platform",
   10.67  		  NULL);
   10.68 -		razor_atomic_abort(installer->atomic, buffer);
   10.69 +		razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
   10.70 +		  RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, buffer);
   10.71  		free(buffer);
   10.72  		return -1;
   10.73  	case CDEV:
   10.74 @@ -838,7 +848,8 @@
   10.75  		goto unsupported;
   10.76  	default:
   10.77  		free(buffer);
   10.78 -		razor_atomic_abort(installer->atomic, "Unknown file type");
   10.79 +		razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
   10.80 +		  RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED, "Unknown file type");
   10.81  		return -1;
   10.82  	}
   10.83  }
   10.84 @@ -1048,7 +1059,8 @@
   10.85  
   10.86  	gz_header = installer->rpm->payload;
   10.87  	if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
   10.88 -		razor_atomic_abort(installer->atomic, 
   10.89 +		razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
   10.90 +				   RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
   10.91  				   "Payload section doesn't have gz header");
   10.92  		return -1;
   10.93  	}
   10.94 @@ -1057,7 +1069,8 @@
   10.95  	flags = gz_header[3];
   10.96  
   10.97  	if (method != Z_DEFLATED || flags != 0) {
   10.98 -		razor_atomic_abort(installer->atomic, 
   10.99 +		razor_atomic_abort(installer->atomic, RAZOR_GENERAL_ERROR,
  10.100 +				   RAZOR_GENERAL_ERROR_RPM_UNSUPPORTED,
  10.101  				   "Unknown payload compression method or "
  10.102  				   "flags set");
  10.103  		return -1;
  10.104 @@ -1078,7 +1091,7 @@
  10.105  	if (err != Z_OK) {
  10.106  		sprintf(buffer, "%d", err);
  10.107  		s = razor_concat("inflateEnd error: ", buffer, NULL);
  10.108 -		razor_atomic_abort(installer->atomic, s);
  10.109 +		razor_atomic_abort(installer->atomic, RAZOR_ZLIB_ERROR, err, s);
  10.110  		free(s);
  10.111  		return -1;
  10.112  	}
  10.113 @@ -1097,7 +1110,7 @@
  10.114  	if (err != Z_OK) {
  10.115  		sprintf(buffer, "%d", err);
  10.116  		s = razor_concat("inflateEnd error: ", buffer, NULL);
  10.117 -		razor_atomic_abort(installer->atomic, s);
  10.118 +		razor_atomic_abort(installer->atomic, RAZOR_ZLIB_ERROR, err, s);
  10.119  		free(s);
  10.120  	}
  10.121  
  10.122 @@ -1132,7 +1145,7 @@
  10.123  	const char *path;
  10.124  	size_t filesize;
  10.125  	char *s;
  10.126 -	int retval = 0;
  10.127 +	int retval = 0, code;
  10.128  
  10.129  	assert (rpm != NULL);
  10.130  	assert (root != NULL);
  10.131 @@ -1142,9 +1155,10 @@
  10.132  	installer.atomic = atomic;
  10.133  
  10.134  	/* FIXME: Only do this before a transaction, not per rpm. */
  10.135 -	if (*root && (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode))) {
  10.136 +	if (*root && ((retval = stat(root, &buf)) || !S_ISDIR(buf.st_mode))) {
  10.137 +		code = retval ? errno : ENOTDIR;
  10.138  		s = razor_concat(root, ": Directory does not exist", NULL);
  10.139 -		razor_atomic_abort(atomic, s);
  10.140 +		razor_atomic_abort(atomic, RAZOR_POSIX_ERROR, code, s);
  10.141  		free(s);
  10.142  		return -1;
  10.143  	}
    11.1 --- a/librazor/util.c	Tue Sep 09 15:04:24 2014 +0100
    11.2 +++ b/librazor/util.c	Tue Sep 09 15:27:12 2014 +0100
    11.3 @@ -74,12 +74,12 @@
    11.4  
    11.5  	fd = open(filename, O_RDONLY | O_BINARY);
    11.6  	if (fd < 0) {
    11.7 -		razor_set_error(error, filename, strerror(errno));
    11.8 +		razor_set_error_posix(error, filename);
    11.9  		return NULL;
   11.10  	}
   11.11  
   11.12  	if (fstat(fd, &st) < 0) {
   11.13 -		razor_set_error(error, filename, strerror(errno));
   11.14 +		razor_set_error_posix(error, filename);
   11.15  		close(fd);
   11.16  		return NULL;
   11.17  	}
   11.18 @@ -99,8 +99,7 @@
   11.19  			while(nb < st.st_size) {
   11.20  				res = read(fd, addr + nb, st.st_size - nb);
   11.21  				if (res <= 0) {
   11.22 -					razor_set_error(error, filename,
   11.23 -							strerror(errno));
   11.24 +					razor_set_error_posix(error, filename);
   11.25  					free(addr);
   11.26  					addr = NULL;
   11.27  					break;
   11.28 @@ -108,7 +107,8 @@
   11.29  				nb += res;
   11.30  			}
   11.31  		} else
   11.32 -			razor_set_error(error, NULL, "Not enough memory");
   11.33 +			razor_set_error(error, RAZOR_POSIX_ERROR, ENOMEM, NULL,
   11.34 +					"Not enough memory");
   11.35  	}
   11.36  	close(fd);
   11.37  
    12.1 --- a/src/main.c	Tue Sep 09 15:04:24 2014 +0100
    12.2 +++ b/src/main.c	Tue Sep 09 15:27:12 2014 +0100
    12.3 @@ -1110,7 +1110,7 @@
    12.4  		rpm = razor_rpm_open(file, &error);
    12.5  		free(file);
    12.6  		if (rpm == NULL) {
    12.7 -			razor_atomic_abort(atomic, razor_error_get_msg(error));
    12.8 +			razor_atomic_propagate_error(atomic, error, NULL);
    12.9  			razor_error_free(error);
   12.10  			razor_package_iterator_destroy(pkg_iter);
   12.11  			razor_importer_destroy(importer);
   12.12 @@ -1187,7 +1187,7 @@
   12.13  	rpm = razor_rpm_open(file, &error);
   12.14  	free(file);
   12.15  	if (rpm == NULL) {
   12.16 -		razor_atomic_abort(atomic, razor_error_get_msg(error));
   12.17 +		razor_atomic_propagate_error(atomic, error, NULL);
   12.18  		fprintf(stderr, "%s\n", razor_error_get_msg(error));
   12.19  		razor_error_free(error);
   12.20  		return -1;