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