WIP -- reading configuration.
[libradsec.git] / lib / err.c
1 /* See the file COPYING for licensing information.  */
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <assert.h>
6 #include <radsec/radsec.h>
7 #include <radsec/radsec-impl.h>
8
9 const char *_errtxt[] = {
10   "SUCCESS",                    /* 0 RSE_OK */
11   "NOMEM",                      /* 1 RSE_NOMEM */
12   "NYI -- not yet implemented", /* 2 RSE_NOSYS */
13   "invalid handle"              /* 3 RSE_INVALID_CTX */
14   "invalid connection"          /* 4 RSE_INVALID_CONN */
15   "connection type mismatch"    /* 5 RSE_CONN_TYPE_MISMATCH */
16   "FreeRadius error"            /* 6 RSE_FR */
17   "bad hostname or port"        /* 7 RSE_BADADDR */
18   "no peer configured"          /* 8 RSE_NOPEER */
19   "libevent error"              /* 9 RSE_EVENT */
20   "connection error"            /* 10 RSE_CONNERR */
21   "invalid configuration file"  /* 11 RSE_CONFIG */
22   "ERR 12"                      /*  RSE_ */
23   "ERR 13"                      /*  RSE_ */
24   "ERR 14"                      /*  RSE_ */
25   "ERR 15"                      /*  RSE_ */
26   "ERR 16"                      /*  RSE_ */
27   "ERR 17"                      /*  RSE_ */
28   "ERR 18"                      /*  RSE_ */
29   "ERR 19"                      /*  RSE_ */
30   "ERR 20"                      /*  RSE_ */
31   "some error"                  /* 21 RSE_SOME_ERROR */
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_handle *ctx, int code, const char *file, int line, const char *fmt, va_list args)
83 {
84   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
85
86   if (err)
87     ctx->err = err;
88   return code;
89 }
90
91 int
92 rs_err_ctx_push (struct rs_handle *ctx, int code, const char *fmt, ...)
93 {
94   va_list args;
95   va_start (args, fmt);
96   _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args);
97   va_end (args);
98   return code;
99 }
100
101 int
102 rs_err_ctx_push_fl (struct rs_handle *ctx, int code, const char *file, int line, const char *fmt, ...)
103 {
104   va_list args;
105   va_start (args, fmt);
106   _ctx_err_vpush_fl (ctx, code, file, line, fmt, args);
107   va_end (args);
108   return code;
109 }
110
111 int
112 _rs_err_conn_push_err (struct rs_connection *conn, struct rs_error *err)
113 {
114   conn->err = err;              /* FIXME: use a stack */
115   return err->code;
116 }
117
118 static int
119 _conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, va_list args)
120 {
121   struct rs_error *err = _err_vcreate (code, file, line, fmt, args);
122
123   if (err)
124     _rs_err_conn_push_err (conn, err);
125   return code;
126 }
127
128 int
129 rs_err_conn_push (struct rs_connection *conn, int code, const char *fmt, ...)
130 {
131   va_list args;
132   va_start (args, fmt);
133   _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args);
134   va_end (args);
135   return code;
136 }
137
138 int
139 rs_err_conn_push_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, ...)
140 {
141   va_list args;
142   va_start (args, fmt);
143   _conn_err_vpush_fl (conn, code, file, line, fmt, args);
144   va_end (args);
145   return code;
146 }
147
148 struct rs_error *
149 rs_err_ctx_pop (struct rs_handle *ctx)
150 {
151   struct rs_error *err;
152
153   if (!ctx)
154     return NULL;                /* FIXME: RSE_INVALID_CTX.  */
155   err = ctx->err;
156   ctx->err = NULL;
157   return err;
158 }
159
160 struct rs_error *
161 rs_err_conn_pop (struct rs_connection *conn)
162 {
163   struct rs_error *err;
164
165   if (!conn)
166     return NULL;                /* FIXME: RSE_INVALID_CONN */
167   err = conn->err;
168   conn->err = NULL;
169   return err;
170 }
171
172 void
173 rs_err_free (struct rs_error *err)
174 {
175   assert (err);
176   if (err->msg)
177     free (err->msg);
178   free (err);
179 }
180
181 char *
182 rs_err_msg (struct rs_error *err, int dofree_flag)
183 {
184   char *msg;
185
186   if (!err)
187     return NULL;
188   if (err->msg)
189     msg = err->msg;
190   else
191     msg = strdup (err->buf);
192
193   if (dofree_flag)
194     rs_err_free (err);
195   return msg;
196 }
197
198 int
199 rs_err_code (struct rs_error *err, int dofree_flag)
200 {
201   int code;
202
203   if (!err)
204     return -1;
205   code = err->code;
206
207   if (dofree_flag)
208     rs_err_free(err);
209   return code;
210 }