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