Rename and move around a few helper functions.
[radsecproxy.git] / lib / err.c
1 /* Copyright 2010, 2011 NORDUnet A/S. All rights reserved.
2    See the file COPYING for licensing information.  */
3
4 #if defined HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <assert.h>
11 #include <radsec/radsec.h>
12 #include <radsec/radsec-impl.h>
13
14 static const char *_errtxt[] = {
15   "SUCCESS",                    /* 0 RSE_OK */
16   "out of memory",              /* 1 RSE_NOMEM */
17   "not yet implemented",        /* 2 RSE_NOSYS */
18   "invalid handle",             /* 3 RSE_INVALID_CTX */
19   "invalid connection",         /* 4 RSE_INVALID_CONN */
20   "connection type mismatch",   /* 5 RSE_CONN_TYPE_MISMATCH */
21   "FreeRadius error",           /* 6 RSE_FR */
22   "bad hostname or port",       /* 7 RSE_BADADDR */
23   "no peer configured",         /* 8 RSE_NOPEER */
24   "libevent error",             /* 9 RSE_EVENT */
25   "socket error",               /* 10 RSE_SOCKERR */
26   "invalid configuration file", /* 11 RSE_CONFIG */
27   "authentication failed",      /* 12 RSE_BADAUTH */
28   "internal error",             /* 13 RSE_INTERNAL */
29   "SSL error",                  /* 14 RSE_SSLERR */
30   "invalid packet",             /* 15 RSE_INVALID_PKT */
31   "connect timeout",            /* 16 RSE_TIMEOUT_CONN */
32   "invalid argument",           /* 17 RSE_INVAL */
33   "I/O timeout",                /* 18 RSE_TIMEOUT_IO */
34   "timeout",                    /* 19 RSE_TIMEOUT */
35 };
36 #define ERRTXT_SIZE (sizeof(_errtxt) / sizeof(*_errtxt))
37
38 static struct rs_error *
39 _err_vcreate (unsigned int code, const char *file, int line, const char *fmt,
40               va_list args)
41 {
42   struct rs_error *err = NULL;
43
44   err = malloc (sizeof(struct rs_error));
45   if (err)
46     {
47       int n;
48       memset (err, 0, sizeof(struct rs_error));
49       err->code = code;
50       if (fmt)
51         n = vsnprintf (err->buf, sizeof(err->buf), fmt, args);
52       else
53         {
54           strncpy (err->buf,
55                    err->code < ERRTXT_SIZE ? _errtxt[err->code] : "",
56                    sizeof(err->buf));
57           n = strlen (err->buf);
58         }
59       if (n >= 0 && file)
60         {
61           char *sep = strrchr (file, '/');
62           if (sep)
63             file = sep + 1;
64           snprintf (err->buf + n, sizeof(err->buf) - n, " (%s:%d)", file,
65                     line);
66         }
67     }
68   return err;
69 }
70
71 struct rs_error *
72 err_create (unsigned int code,
73             const char *file,
74             int line,
75             const char *fmt,
76             ...)
77 {
78   struct rs_error *err = NULL;
79
80   va_list args;
81   va_start (args, fmt);
82   err = _err_vcreate (code, file, line, fmt, args);
83   va_end (args);
84
85   return err;
86 }
87
88 static int
89 _ctx_err_vpush_fl (struct rs_context *ctx, int code, const char *file,
90                    int line, const char *fmt, va_list args)
91 {
92   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
93
94   if (!err)
95     return RSE_NOMEM;
96
97   /* TODO: Implement a stack.  */
98   if (ctx->err)
99     rs_err_free (ctx->err);
100   ctx->err = err;
101
102   return err->code;
103 }
104
105 int
106 rs_err_ctx_push (struct rs_context *ctx, int code, const char *fmt, ...)
107 {
108   int r = 0;
109   va_list args;
110
111   va_start (args, fmt);
112   r = _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args);
113   va_end (args);
114
115   return r;
116 }
117
118 int
119 rs_err_ctx_push_fl (struct rs_context *ctx, int code, const char *file,
120                     int line, const char *fmt, ...)
121 {
122   int r = 0;
123   va_list args;
124
125   va_start (args, fmt);
126   r = _ctx_err_vpush_fl (ctx, code, file, line, fmt, args);
127   va_end (args);
128
129   return r;
130 }
131
132 int
133 err_conn_push_err (struct rs_connection *conn, struct rs_error *err)
134 {
135
136   if (conn->err)
137     rs_err_free (conn->err);
138   conn->err = err;              /* FIXME: use a stack */
139
140   return err->code;
141 }
142
143 static int
144 _conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file,
145                     int line, const char *fmt, va_list args)
146 {
147   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
148
149   if (!err)
150     return RSE_NOMEM;
151
152   return err_conn_push_err (conn, err);
153 }
154
155 int
156 rs_err_conn_push (struct rs_connection *conn, int code, const char *fmt, ...)
157 {
158   int r = 0;
159
160   va_list args;
161   va_start (args, fmt);
162   r = _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args);
163   va_end (args);
164
165   return r;
166 }
167
168 int
169 rs_err_conn_push_fl (struct rs_connection *conn, int code, const char *file,
170                      int line, const char *fmt, ...)
171 {
172   int r = 0;
173
174   va_list args;
175   va_start (args, fmt);
176   r = _conn_err_vpush_fl (conn, code, file, line, fmt, args);
177   va_end (args);
178
179   return r;
180 }
181
182 struct rs_error *
183 rs_err_ctx_pop (struct rs_context *ctx)
184 {
185   struct rs_error *err;
186
187   if (!ctx)
188     return NULL;                /* FIXME: RSE_INVALID_CTX.  */
189   err = ctx->err;
190   ctx->err = NULL;
191
192   return err;
193 }
194
195 struct rs_error *
196 rs_err_conn_pop (struct rs_connection *conn)
197 {
198   struct rs_error *err;
199
200   if (!conn)
201     return NULL;                /* FIXME: RSE_INVALID_CONN */
202   err = conn->err;
203   conn->err = NULL;
204
205   return err;
206 }
207
208 int
209 rs_err_conn_peek_code (struct rs_connection *conn)
210 {
211   if (!conn)
212     return -1;                  /* FIXME: RSE_INVALID_CONN */
213   if (conn->err)
214     return conn->err->code;
215
216   return RSE_OK;
217 }
218
219 void
220 rs_err_free (struct rs_error *err)
221 {
222   assert (err);
223   free (err);
224 }
225
226 char *
227 rs_err_msg (struct rs_error *err)
228 {
229   if (!err)
230     return NULL;
231
232   return err->buf;
233 }
234
235 int
236 rs_err_code (struct rs_error *err, int dofree_flag)
237 {
238   int code;
239
240   if (!err)
241     return -1;
242   code = err->code;
243
244   if (dofree_flag)
245     rs_err_free (err);
246
247   return code;
248 }