1 /*
2 This code (with some modifications) is from GNU Parted
3 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
4 */
5
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9
10 #include <reiserfs/reiserfs.h>
11 #include <reiserfs/debug.h>
12
13 #define N_(String) (String)
14 #if ENABLE_NLS
15 # include <libintl.h>
16 # define _(String) dgettext (PACKAGE, String)
17 #else
18 # define _(String) (String)
19 #endif
20
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <stdlib.h>
24
25 static reiserfs_exception_option_t default_handler(reiserfs_exception_t *ex);
26 static reiserfs_exception_handler_t exception_handler = default_handler;
27 static reiserfs_exception_t *exception = NULL;
28
29 static int fetch_count = 0;
30 static int libreiserfs_exception = 0;
31
32 static char *type_strings[] = {
33 N_("Information"),
34 N_("Warning"),
35 N_("Error"),
36 N_("Fatal"),
37 N_("Bug")
38 };
39
40 static char *option_strings[] = {
41 N_("Yes"),
42 N_("No"),
43 N_("OK"),
44 N_("Retry"),
45 N_("Ignore"),
46 N_("Cancel")
47 };
48
libreiserfs_exception_type_string(reiserfs_exception_type_t type)49 char *libreiserfs_exception_type_string(reiserfs_exception_type_t type) {
50 return type_strings[type - 1];
51 }
52
libreiserfs_exception_type(reiserfs_exception_t * ex)53 reiserfs_exception_type_t libreiserfs_exception_type(reiserfs_exception_t *ex) {
54 return ex->type;
55 }
56
libreiserfs_exception_option_string(reiserfs_exception_option_t opt)57 char *libreiserfs_exception_option_string(reiserfs_exception_option_t opt) {
58 return option_strings[reiserfs_tools_log2(opt)];
59 }
60
libreiserfs_exception_option(reiserfs_exception_t * ex)61 reiserfs_exception_option_t libreiserfs_exception_option(reiserfs_exception_t *ex) {
62 return ex->options;
63 }
64
libreiserfs_exception_message(reiserfs_exception_t * ex)65 char *libreiserfs_exception_message(reiserfs_exception_t *ex) {
66 return ex->message;
67 }
68
default_handler(reiserfs_exception_t * ex)69 static reiserfs_exception_option_t default_handler(reiserfs_exception_t *ex) {
70 if (ex->type == EXCEPTION_BUG)
71 fprintf (stderr, _("A bug has been detected in libreiserfs. "
72 "Please email a bug report to torque@ukrpost.net containing the version (%s) "
73 "and the following message: "), VERSION);
74 else
75 fprintf (stderr, "%s: ", libreiserfs_exception_type_string(ex->type));
76
77 fprintf (stderr, "%s\n", ex->message);
78
79 switch (ex->options) {
80 case EXCEPTION_OK:
81 case EXCEPTION_CANCEL:
82 case EXCEPTION_IGNORE:
83 return ex->options;
84
85 default:
86 return EXCEPTION_UNHANDLED;
87 }
88 }
89
libreiserfs_exception_set_handler(reiserfs_exception_handler_t handler)90 void libreiserfs_exception_set_handler(reiserfs_exception_handler_t handler) {
91 if (handler)
92 exception_handler = handler;
93 else
94 exception_handler = default_handler;
95 }
96
libreiserfs_exception_catch(void)97 void libreiserfs_exception_catch(void) {
98 if (libreiserfs_exception) {
99 libreiserfs_exception = 0;
100 libreiserfs_free(exception->message);
101 libreiserfs_free(exception);
102 exception = NULL;
103 }
104 }
105
do_throw(void)106 static reiserfs_exception_option_t do_throw(void) {
107 reiserfs_exception_option_t opt;
108
109 libreiserfs_exception = 1;
110
111 if (fetch_count)
112 return EXCEPTION_UNHANDLED;
113 else {
114 opt = exception_handler(exception);
115 libreiserfs_exception_catch();
116 return opt;
117 }
118 }
119
libreiserfs_exception_throw(reiserfs_exception_type_t type,reiserfs_exception_option_t opts,const char * message,...)120 reiserfs_exception_option_t libreiserfs_exception_throw(reiserfs_exception_type_t type,
121 reiserfs_exception_option_t opts, const char* message, ...)
122 {
123 va_list arg_list;
124 reiserfs_gauge_t *libreiserfs_gauge;
125
126 if (exception)
127 libreiserfs_exception_catch();
128
129 if (!(exception = (reiserfs_exception_t *)libreiserfs_calloc(sizeof(reiserfs_exception_t), 0)))
130 goto no_memory;
131
132 if (!(exception->message = (char *)libreiserfs_calloc(4096, 0)))
133 goto no_memory;
134
135 exception->type = type;
136 exception->options = opts;
137
138 va_start(arg_list, message);
139
140 #ifdef DJGPP
141 vsprintf(exception->message, message, arg_list);
142 #else
143 vsnprintf(exception->message, 4096, message, arg_list);
144 #endif
145
146 va_end(arg_list);
147
148 if ((libreiserfs_gauge = libreiserfs_get_gauge())) {
149
150 if (libreiserfs_gauge->state != REISERFS_GAUGE_DONE &&
151 libreiserfs_gauge->state != REISERFS_GAUGE_FAILED)
152 libreiserfs_gauge_finish(libreiserfs_gauge, 0);
153 }
154
155 return do_throw();
156
157 no_memory:
158 fprintf(stderr, "Out of memory in exception handler!\n");
159
160 va_start(arg_list, message);
161 vprintf(message, arg_list);
162 va_end(arg_list);
163
164 return EXCEPTION_UNHANDLED;
165 }
166
libreiserfs_exception_rethrow(void)167 reiserfs_exception_option_t libreiserfs_exception_rethrow(void) {
168 return do_throw();
169 }
170
libreiserfs_exception_fetch_all(void)171 void libreiserfs_exception_fetch_all(void) {
172 fetch_count++;
173 }
174
libreiserfs_exception_leave_all(void)175 void libreiserfs_exception_leave_all(void) {
176 ASSERT(fetch_count > 0, return);
177 fetch_count--;
178 }
179
180