d111115f9c9eb9b9d1d7c2fac4ee01d8d6900033
[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   "connection error",           /* 10 RSE_CONNERR */
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   "ERR 15",                     /*  RSE_ */
30   "ERR 16",                     /*  RSE_ */
31   "ERR 17",                     /*  RSE_ */
32   "ERR 18",                     /*  RSE_ */
33   "ERR 19",                     /*  RSE_ */
34   "ERR 20",                     /*  RSE_ */
35   "some error",                 /* 21 RSE_SOME_ERROR */
36 };
37 #define ERRTXT_SIZE (sizeof(_errtxt) / sizeof(*_errtxt))
38
39 static struct rs_error *
40 _err_vcreate (unsigned int code, const char *file, int line, const char *fmt,
41               va_list args)
42 {
43   struct rs_error *err;
44
45   err = malloc (sizeof(struct rs_error));
46   if (err)
47     {
48       int n;
49       memset (err, 0, sizeof(struct rs_error));
50       err->code = code;
51       if (fmt)
52         n = vsnprintf (err->buf, sizeof(err->buf), fmt, args);
53       else
54         {
55           strncpy (err->buf,
56                    err->code < ERRTXT_SIZE ? _errtxt[err->code] : "",
57                    sizeof(err->buf));
58           n = strlen (err->buf);
59         }
60       if (n >= 0 && file)
61         {
62           char *sep = strrchr (file, '/');
63           if (sep)
64             file = sep + 1;
65           snprintf (err->buf + n, sizeof(err->buf) - n, " (%s:%d)", file,
66                     line);
67         }
68     }
69   return err;
70 }
71
72 struct rs_error *
73 _rs_err_create (unsigned int code, const char *file, int line, const char *fmt,
74                 ...)
75 {
76   struct rs_error *err;
77
78   va_list args;
79   va_start (args, fmt);
80   err = _err_vcreate (code, file, line, fmt, args);
81   va_end (args);
82   return err;
83 }
84
85 static int
86 _ctx_err_vpush_fl (struct rs_context *ctx, int code, const char *file,
87                    int line, const char *fmt, va_list args)
88 {
89   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
90
91   if (err)
92     ctx->err = err;
93   return code;
94 }
95
96 int
97 rs_err_ctx_push (struct rs_context *ctx, int code, const char *fmt, ...)
98 {
99   va_list args;
100   va_start (args, fmt);
101   _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args);
102   va_end (args);
103   return code;
104 }
105
106 int
107 rs_err_ctx_push_fl (struct rs_context *ctx, int code, const char *file,
108                     int line, const char *fmt, ...)
109 {
110   va_list args;
111   va_start (args, fmt);
112   _ctx_err_vpush_fl (ctx, code, file, line, fmt, args);
113   va_end (args);
114   return code;
115 }
116
117 int
118 _rs_err_conn_push_err (struct rs_connection *conn, struct rs_error *err)
119 {
120   conn->err = err;              /* FIXME: use a stack */
121   return err->code;
122 }
123
124 static int
125 _conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file,
126                     int line, const char *fmt, va_list args)
127 {
128   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
129
130   if (err)
131     _rs_err_conn_push_err (conn, err);
132   return code;
133 }
134
135 int
136 rs_err_conn_push (struct rs_connection *conn, int code, const char *fmt, ...)
137 {
138   va_list args;
139   va_start (args, fmt);
140   _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args);
141   va_end (args);
142   return code;
143 }
144
145 int
146 rs_err_conn_push_fl (struct rs_connection *conn, int code, const char *file,
147                      int line, const char *fmt, ...)
148 {
149   va_list args;
150   va_start (args, fmt);
151   _conn_err_vpush_fl (conn, code, file, line, fmt, args);
152   va_end (args);
153   return code;
154 }
155
156 struct rs_error *
157 rs_err_ctx_pop (struct rs_context *ctx)
158 {
159   struct rs_error *err;
160
161   if (!ctx)
162     return NULL;                /* FIXME: RSE_INVALID_CTX.  */
163   err = ctx->err;
164   ctx->err = NULL;
165   return err;
166 }
167
168 struct rs_error *
169 rs_err_conn_pop (struct rs_connection *conn)
170 {
171   struct rs_error *err;
172
173   if (!conn)
174     return NULL;                /* FIXME: RSE_INVALID_CONN */
175   err = conn->err;
176   conn->err = NULL;
177   return err;
178 }
179
180 void
181 rs_err_free (struct rs_error *err)
182 {
183   assert (err);
184   if (err->msg)
185     free (err->msg);
186   free (err);
187 }
188
189 char *
190 rs_err_msg (struct rs_error *err, int dofree_flag)
191 {
192   char *msg;
193
194   if (!err)
195     return NULL;
196   if (err->msg)
197     msg = err->msg;
198   else
199     msg = strdup (err->buf);
200
201   if (dofree_flag)
202     rs_err_free (err);
203   return msg;
204 }
205
206 int
207 rs_err_code (struct rs_error *err, int dofree_flag)
208 {
209   int code;
210
211   if (!err)
212     return -1;
213   code = err->code;
214
215   if (dofree_flag)
216     rs_err_free(err);
217   return code;
218 }