WIP.
[radsecproxy.git] / lib / err.c
1 #include <stdio.h>
2 #include <assert.h>
3 #include "libradsec.h"
4 #include "libradsec-impl.h"
5
6 const char *_errtxt[] = {
7   "SUCCESS",                    /* 0 RSE_OK */
8   "NOMEM",                      /* 1 RSE_NOMEM */
9   "NYI -- not yet implemented", /* 2 RSE_NOSYS */
10   "invalid handle"              /* 3 RSE_INVALID_CTX */
11   "invalid connection"          /* 4 RSE_INVALID_CONN */
12   "connection type mismatch"    /* 5 RSE_CONN_TYPE_MISMATCH */
13   "FreeRadius error"            /* 6 RSE_FR */
14   "ERR 7"                       /*  RSE_ */
15   "ERR 8"                       /*  RSE_ */
16   "ERR 9"                       /*  RSE_ */
17   "ERR 10"                      /*  RSE_ */
18   "ERR 11"                      /*  RSE_ */
19   "ERR 12"                      /*  RSE_ */
20   "ERR 13"                      /*  RSE_ */
21   "ERR "                        /*  RSE_ */
22   "ERR "                        /*  RSE_ */
23   "ERR "                        /*  RSE_ */
24   "ERR "                        /*  RSE_ */
25   "ERR "                        /*  RSE_ */
26   "ERR "                        /*  RSE_ */
27   "ERR "                        /*  RSE_ */
28   "some error"                  /* 21 RSE_SOME_ERROR */
29 };
30
31 static struct rs_error *
32 _err_new (unsigned int code, const char *file, int line, const char *fmt, va_list args)
33 {
34   struct rs_error *err;
35
36   err = malloc (sizeof(struct rs_error));
37   if (err)
38     {
39       int n;
40       memset (err, 0, sizeof(struct rs_error));
41       err->code = code;
42       n = vsnprintf (err->buf, sizeof(err->buf), fmt, args);
43       if (n > 0)
44         {
45           char *sep = strrchr (file, '/');
46           if (sep)
47             file = sep + 1;
48           snprintf (err->buf + n, sizeof(err->buf) - n, " (%s: %d)", file,
49                     line);
50         }
51     }
52   return err;
53 }
54
55 static int
56 _ctx_err_vpush_fl (struct rs_handle *ctx, int code, const char *file, int line, const char *fmt, va_list args)
57 {
58   struct rs_error *err = _err_new (code, file, line, fmt, args);
59
60   if (err)
61     ctx->err = err;
62   return code;
63 }
64
65 int
66 rs_ctx_err_push (struct rs_handle *ctx, int code, const char *fmt, ...)
67 {
68   va_list args;
69   va_start (args, fmt);
70   _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args);
71   va_end (args);
72   return code;
73 }
74
75 static int
76 _conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, va_list args)
77 {
78   struct rs_error *err = _err_new (code, file, line, fmt, args);
79
80   if (err)
81     conn->err = err;
82   return code;
83 }
84
85 int
86 rs_conn_err_push (struct rs_connection *conn, int code, const char *fmt, ...)
87 {
88   va_list args;
89   va_start (args, fmt);
90   _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args);
91   va_end (args);
92   return code;
93 }
94
95 int
96 rs_conn_err_push_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, ...)
97 {
98   va_list args;
99   va_start (args, fmt);
100   _conn_err_vpush_fl (conn, code, file, line, fmt, args);
101   va_end (args);
102   return code;
103 }
104
105 struct rs_error *
106 rs_ctx_err_pop (struct rs_handle *ctx)
107 {
108   struct rs_error *err;
109
110   if (!ctx)
111     return NULL;                /* FIXME: RSE_INVALID_CTX.  */
112   err = ctx->err;
113   ctx->err = NULL;
114   return err;
115 }
116
117 struct rs_error *
118 rs_conn_err_pop (struct rs_connection *conn)
119 {
120   struct rs_error *err;
121
122   if (!conn)
123     return NULL;                /* FIXME: RSE_INVALID_CONN */
124   err = conn->err;
125   conn->err = NULL;
126   return err;
127 }
128
129 void
130 rs_err_free (struct rs_error *err)
131 {
132   assert (err);
133   if (err->msg)
134     free (err->msg);
135   free (err);
136 }
137
138 char *
139 rs_err_msg (struct rs_error *err, int dofree_flag)
140 {
141   char *msg;
142
143   if (!err)
144     return NULL;
145   if (err->msg)
146     msg = err->msg;
147   else
148     msg = strdup (err->buf);
149
150   if (dofree_flag)
151     rs_err_free (err);
152   return msg;
153 }
154
155 int
156 rs_err_code (struct rs_error *err, int dofree_flag)
157 {
158   int code;
159
160   if (!err)
161     return -1;
162   code = err->code;
163
164   if (dofree_flag)
165     rs_err_free(err);
166   return code;
167 }