Use rad_malloc() instead of malloc() + NULL test.
[freeradius.git] / src / modules / rlm_eap / mem.c
1 /*
2  * mem.c  Memory allocation, deallocation stuff.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2000,2001  The FreeRADIUS server project
21  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
22  */
23
24 #include <stdio.h>
25 #include "eap.h"
26
27 /*
28  *      Allocate a new EAP_PACKET.  Guaranteed to succeed.
29  */
30 EAP_PACKET *eap_packet_alloc(void)
31 {
32         EAP_PACKET   *rp;
33
34         rp = rad_malloc(sizeof(EAP_PACKET));
35         memset(rp, 0, sizeof(EAP_PACKET));
36         return rp;
37 }
38
39 /*
40  *      Free a EAP_PACKET
41  */
42 void eap_packet_free(EAP_PACKET **eap_packet_ptr)
43 {
44         EAP_PACKET *eap_packet;
45
46         if (!eap_packet_ptr) return;
47         eap_packet = *eap_packet_ptr;
48         if (!eap_packet) return;
49
50         if (eap_packet->typedata) free(eap_packet->typedata);
51         if (eap_packet->rad_vps) pairfree(&(eap_packet->rad_vps));
52
53         free(eap_packet);
54
55         *eap_packet_ptr = NULL;
56 }
57
58 /*
59  *      Allocate a new EAP_PACKET
60  */
61 EAP_DS *eap_ds_alloc(void)
62 {
63         EAP_DS  *eap_ds;
64
65         eap_ds = rad_malloc(sizeof(EAP_DS));
66         memset(eap_ds, 0, sizeof(EAP_DS));
67         eap_ds->response = eap_packet_alloc();
68         eap_ds->request = eap_packet_alloc();
69
70         return eap_ds;
71 }
72
73 void eap_ds_free(EAP_DS **eap_ds_p)
74 {
75         EAP_DS *eap_ds;
76
77         if (!eap_ds_p) return;
78         eap_ds = *eap_ds_p;
79         if (!eap_ds) return;
80
81         if (eap_ds->response) eap_packet_free(&(eap_ds->response));
82         if (eap_ds->request) eap_packet_free(&(eap_ds->request));
83
84         if (eap_ds->username) pairfree(&(eap_ds->username));
85         if (eap_ds->password) pairfree(&(eap_ds->password));
86
87         free(eap_ds);
88         *eap_ds_p = NULL;
89 }
90
91 void free_type_list(EAP_TYPES **i)
92 {
93         EAP_TYPES       *c, *next;
94
95         c = *i;
96         while (c) {
97                 next = c->next;
98                 if(c->type->detach) (c->type->detach)(&(c->type_stuff));
99                 if (c->handle) lt_dlclose(c->handle);
100                 free(c);
101                 c = next;
102         }
103         *i = NULL;
104 }
105
106 void node_free(EAP_LIST **node)
107 {
108         if (node == NULL) return;
109         if (*node == NULL) return;
110         if ((*node)->eap_ds) eap_ds_free(&((*node)->eap_ds));
111
112         (*node)->next = NULL;
113         free(*node);
114         *node = NULL;
115 }
116
117 void list_free(EAP_LIST **list)
118 {
119         EAP_LIST *node, *next;
120
121         if (!list) return;
122         node = *list;
123
124         while (node) {
125                 next = node->next;
126                 node_free(&node);
127                 node = next;
128         }
129
130         *list = NULL;
131 }
132
133 int list_add(EAP_LIST **list, EAP_DS *eap_ds)
134 {
135         EAP_LIST        *node, **last;
136
137         if (!eap_ds) return 0;
138         
139         last = list;
140         while (*last) *last = (*last)->next;
141         
142         eap_ds->timestamp = time(NULL);
143         eap_ds->finished = 1;
144
145         node = malloc(sizeof(EAP_LIST));
146         if (!node) {
147                 radlog(L_ERR, "rlm_eap: out of memory");
148                 return 0;
149         }
150
151         node->next = NULL;
152         node->eap_ds = eap_ds;
153
154         *last = node;
155         return 1;
156 }
157
158 /*
159  * List should contain only recent packets with life < X seconds.
160  */
161 void list_clean(EAP_LIST **first, time_t limit)
162 {
163         time_t  now;
164         EAP_LIST *node, *next;
165         EAP_LIST **last = first;
166
167         now = time(NULL);
168
169         for (node = *first; node; node = next) {
170                 next = node->next;
171                 if ((now - node->eap_ds->timestamp) > limit) {
172                         radlog(L_INFO, "rlm_eap:  list_clean deleted one item");
173                         *last = next;
174                         node_free(&node);
175                 } else  {
176                         last = &(node->next);
177                 }
178         }
179 }
180
181 void remove_item(EAP_LIST **first, EAP_LIST *item)
182 {
183         time_t  now;
184         EAP_LIST *node, *next;
185         EAP_LIST **last = first;
186
187         now = time(NULL);
188
189         for (node = *first; node; node = next) {
190                 next = node->next;
191                 if (node == item) {
192                         radlog(L_INFO, "rlm_eap:  remove_item deleted one item");
193                         *last = next;
194                         node_free(&node);
195                 } else  {
196                         last = &(node->next);
197                 }
198         }
199 }