1 |
#include "plugin_manager.h" |
2 |
#include "aos.h" |
3 |
#include "_aos.h" |
4 |
|
5 |
/* internal methods */ |
6 |
|
7 |
int aos_is_initialized(){ |
8 |
return _is_initialized; |
9 |
} |
10 |
|
11 |
int aos_is_threaded(){ |
12 |
return _is_threaded; |
13 |
} |
14 |
|
15 |
size_t aos_buffer_size(eef_arg_type argtype){ |
16 |
switch (argtype){ |
17 |
case TYPE_NONE : |
18 |
return 0; |
19 |
case TYPE_SCHAR : |
20 |
return sizeof(int); |
21 |
case TYPE_UCHAR : |
22 |
return sizeof(unsigned int); |
23 |
case TYPE_SHORT : |
24 |
return sizeof(int); |
25 |
case TYPE_USHORT : |
26 |
return sizeof(unsigned int); |
27 |
case TYPE_INT : |
28 |
return sizeof(int); |
29 |
case TYPE_UINT : |
30 |
return sizeof(unsigned int); |
31 |
case TYPE_LONGINT : |
32 |
return sizeof(long int); |
33 |
case TYPE_ULONGINT : |
34 |
return sizeof(unsigned long int); |
35 |
#ifdef HAVE_LONG_LONG_INT |
36 |
case TYPE_LONGLONGINT : |
37 |
return sizeof(long long int); |
38 |
case TYPE_ULONGLONGINT : |
39 |
return sizeof(unsigned long long int); |
40 |
#endif |
41 |
case TYPE_FLOAT : |
42 |
return sizeof(double); |
43 |
case TYPE_DOUBLE : |
44 |
return sizeof(double); |
45 |
#ifdef HAVE_LONG_DOUBLE |
46 |
case TYPE_LONGDOUBLE : |
47 |
return sizeof(long double); |
48 |
#endif |
49 |
case TYPE_CHAR : |
50 |
return sizeof(int); |
51 |
#ifdef HAVE_WINT_T |
52 |
case TYPE_WIDE_CHAR : |
53 |
return sizeof(wint_t); |
54 |
#endif |
55 |
case TYPE_STRING : |
56 |
return sizeof(const char*); |
57 |
#ifdef HAVE_WCHAR_T |
58 |
case TYPE_WIDE_STRING : |
59 |
return sizeof(const wchar_t*); |
60 |
#endif |
61 |
case TYPE_POINTER : |
62 |
return sizeof(void*); |
63 |
case TYPE_COUNT_SCHAR_POINTER : |
64 |
return sizeof(signed char*); |
65 |
case TYPE_COUNT_SHORT_POINTER : |
66 |
return sizeof(short *); |
67 |
case TYPE_COUNT_INT_POINTER : |
68 |
return sizeof(int*); |
69 |
case TYPE_COUNT_LONGINT_POINTER : |
70 |
return sizeof(long int*); |
71 |
#ifdef HAVE_LONG_LONG_INT |
72 |
case TYPE_COUNT_LONGLONGINT_POINTER : |
73 |
return sizeof(long long int*); |
74 |
#endif |
75 |
default: |
76 |
return 0; |
77 |
} |
78 |
} |
79 |
|
80 |
/* base functions */ |
81 |
|
82 |
EES_RC aos_set(const char *label, void *value, eef_arg_type type, size_t arg_bufsize, aos_argument_t * parent, aos_argument_t * child, aos_argument_t **head_node, unsigned int *args_size){ |
83 |
|
84 |
int rc = 0; |
85 |
aos_argument_t * args_new = NULL; |
86 |
aos_argument_t * last_node = NULL; |
87 |
size_t buf_size = arg_bufsize; |
88 |
pthread_t * self; |
89 |
pid_t tid; |
90 |
|
91 |
self = pthread_self(); |
92 |
tid = syscall(SYS_gettid); |
93 |
|
94 |
printf("Accessed a setter in thread %i\n", tid); |
95 |
|
96 |
|
97 |
if(!aos_is_initialized()){ |
98 |
eef_log(LOG_ERR, "AOS is not yet initialized. Aborting."); |
99 |
return EES_FAILURE; |
100 |
} |
101 |
|
102 |
if(!(aos_get_value_by_label(label, head_node, args_size) == NULL)){ |
103 |
eef_log(LOG_ERR, "Block with label %s already exists.", label); |
104 |
return EES_FAILURE; |
105 |
} |
106 |
|
107 |
/*if(pthread_rwlock_trywrlock(&rwlock)){*/ |
108 |
/*return EES_FAILURE;*/ |
109 |
/*}*/ |
110 |
|
111 |
/* allocate an extra argument in the list */ |
112 |
if((args_new = calloc(1, (sizeof(aos_argument_t)))) == NULL){ |
113 |
eef_log(LOG_ERR, "Failed to realloc a new argument on the list. %s", strerror(errno)); |
114 |
return EES_FAILURE; |
115 |
} else { |
116 |
/*eef_log(LOG_DEBUG, "Malloc succeeded. Argument lists is now %lu elements.\n", (unsigned long) (*args_size));*/ |
117 |
} |
118 |
|
119 |
if(buf_size == 0) { |
120 |
args_new->data = value; |
121 |
args_new->needs_free = 0; |
122 |
/*eef_log(LOG_DEBUG, "1 pointer allocated at %p. No need to free!\n", args_new->data);*/ |
123 |
} else { |
124 |
args_new->data = calloc(1, buf_size); |
125 |
/*eef_log(LOG_DEBUG, "Storing bytes: %i\n", buf_size);*/ |
126 |
memcpy(args_new->data, value, buf_size); |
127 |
args_new->needs_free = 1; |
128 |
/*eef_log(LOG_DEBUG, "%i bytes allocated at %p. (index %lu) Remember to free it!\n", buf_size, args_new->data, (unsigned long) (*args_size));*/ |
129 |
} |
130 |
|
131 |
args_new->type = type; |
132 |
args_new->label = label; |
133 |
args_new->parent = parent; |
134 |
args_new->child = child; |
135 |
args_new->next = NULL; |
136 |
args_new->setting_plugin = get_running_plugin(); |
137 |
|
138 |
last_node = aos_get_last_node(head_node, args_size); |
139 |
if(last_node != NULL){ |
140 |
(last_node)->next = args_new; |
141 |
} else { |
142 |
*head_node = args_new; |
143 |
} |
144 |
|
145 |
(*args_size)++; |
146 |
/*pthread_rwlock_unlock(&rwlock);*/ |
147 |
return EES_SUCCESS; |
148 |
} |
149 |
|
150 |
aos_argument_t * aos_get_last_node(aos_argument_t **head_node, unsigned int *args_size){ |
151 |
aos_argument_t * current_arg; |
152 |
unsigned int i; |
153 |
current_arg = *head_node; |
154 |
for(i = 0; i < (*args_size); i++){ |
155 |
if(current_arg->next != NULL){ |
156 |
current_arg = current_arg->next; |
157 |
} |
158 |
} |
159 |
return current_arg; |
160 |
} |
161 |
|
162 |
void* aos_get_value_by_label(const char *label, aos_argument_t **head_node, unsigned int *args_size){ |
163 |
aos_argument_t* arg; |
164 |
arg = aos_get_argument_by_label(label, head_node, args_size); |
165 |
if(arg == NULL){ |
166 |
return NULL; |
167 |
} else { |
168 |
return arg->data; |
169 |
} |
170 |
} |
171 |
|
172 |
aos_argument_t * aos_get_argument_by_label(const char *label, aos_argument_t **head_node, unsigned int *args_size){ |
173 |
unsigned int i; |
174 |
aos_argument_t *current_arg = *head_node; |
175 |
|
176 |
/*if(pthread_rwlock_tryrdlock(&rwlock)){*/ |
177 |
/*return NULL;*/ |
178 |
/*}*/ |
179 |
|
180 |
for(i = 0; i < (*args_size); i++){ |
181 |
if(strncmp(current_arg->label, label, strlen(label))==0){ |
182 |
return current_arg; |
183 |
} |
184 |
if(current_arg->next != NULL){ |
185 |
current_arg = current_arg->next; |
186 |
} |
187 |
} |
188 |
/*pthread_rwlock_unlock(&rwlock);*/ |
189 |
return NULL; |
190 |
} |
191 |
|
192 |
/* frees every copied byte */ |
193 |
void aos_free_argslist(aos_argument_t **head_node, unsigned int *args_size) { |
194 |
unsigned int i; |
195 |
aos_argument_t * current_arg; |
196 |
aos_argument_t * next_arg; |
197 |
current_arg = *head_node; |
198 |
for(i = 0; i < (*args_size); i++){ |
199 |
/*eef_log(LOG_DEBUG, "Element %i points to %p\n", i, current_arg->data);*/ |
200 |
next_arg = current_arg->next; |
201 |
if(current_arg->needs_free){ |
202 |
/*eef_log(LOG_DEBUG, "Freeing arg %i\n",i);*/ |
203 |
free(current_arg->data); |
204 |
free(current_arg); |
205 |
} |
206 |
current_arg = next_arg; |
207 |
} |
208 |
(*args_size) = 0; |
209 |
} |
210 |
|
211 |
EES_RC aos_delete_argument_by_label(const char* label, aos_argument_t **head_node, unsigned int *args_size){ |
212 |
aos_argument_t * current_arg = NULL; |
213 |
aos_argument_t * previous_arg = NULL; |
214 |
|
215 |
if(label == NULL){ |
216 |
return EES_FAILURE; |
217 |
} |
218 |
|
219 |
/*if(pthread_rwlock_trywrlock(&rwlock)){*/ |
220 |
/*return EES_FAILURE;*/ |
221 |
/*}*/ |
222 |
|
223 |
for(current_arg = *head_node; current_arg != NULL; previous_arg = current_arg, current_arg = current_arg->next){ |
224 |
if(strncmp(current_arg->label, label, strlen(label)) == 0){ |
225 |
if(current_arg->setting_plugin != get_running_plugin()){ |
226 |
eef_log(LOG_ERR, "Argument %s is not owned by running plugin %s", current_arg->label, get_running_plugin()->name); |
227 |
return EES_FAILURE; |
228 |
} |
229 |
if(previous_arg == NULL){ |
230 |
/* head node deleted. linking start of list to next node */ |
231 |
*head_node = current_arg->next; |
232 |
} else { |
233 |
/* link previous to deletee's next */ |
234 |
previous_arg->next = current_arg->next; |
235 |
} |
236 |
break; |
237 |
} |
238 |
} |
239 |
|
240 |
if(current_arg){ |
241 |
eef_log(LOG_ERR, "Deleting arg: %s", label); |
242 |
free(current_arg->data); |
243 |
free(current_arg); |
244 |
(*args_size)--; |
245 |
/*pthread_rwlock_unlock(&rwlock);*/ |
246 |
return EES_SUCCESS; |
247 |
} else { |
248 |
/*pthread_rwlock_unlock(&rwlock);*/ |
249 |
return EES_FAILURE; |
250 |
} |
251 |
|
252 |
} |
253 |
|
254 |
/* initializer & terminator */ |
255 |
|
256 |
EES_RC AOS_Init (void){ |
257 |
size_assertions = calloc(1, sizeof(int)); |
258 |
*size_assertions = 0; |
259 |
list_assertions = NULL; |
260 |
|
261 |
size_obligations = calloc(1, sizeof(int)); |
262 |
*size_obligations = 0; |
263 |
list_obligations = NULL; |
264 |
|
265 |
/*if(!pthread_rwlock_init(&rwlock, NULL)){*/ |
266 |
_is_initialized = 1; |
267 |
return EES_SUCCESS; |
268 |
/*}*/ |
269 |
|
270 |
/*return EES_FAILURE;*/ |
271 |
} |
272 |
|
273 |
EES_RC aos_start_threading(){ |
274 |
_is_threaded = 1; |
275 |
return EES_SUCCESS; |
276 |
} |
277 |
|
278 |
|
279 |
EES_RC AOS_Term (void){ |
280 |
aos_free_argslist(&list_assertions, size_assertions); |
281 |
aos_free_argslist(&list_obligations, size_obligations); |
282 |
free(size_assertions); |
283 |
free(size_obligations); |
284 |
|
285 |
/*if(!pthread_rwlock_destroy(&rwlock)){*/ |
286 |
/*_is_initialized = 0;*/ |
287 |
return EES_SUCCESS; |
288 |
/*}*/ |
289 |
|
290 |
/*return EES_FAILURE;*/ |
291 |
} |
292 |
|
293 |
/* general high-level wrapper functions */ |
294 |
|
295 |
EES_RC aos_set_int(const char* label, int value){ |
296 |
int* stack_value = &value; |
297 |
return aos_set(label, stack_value, TYPE_INT, 0, NULL, NULL, &list_assertions, size_assertions); |
298 |
} |
299 |
|
300 |
EES_RC aos_set_string(const char* label, char* value){ |
301 |
return aos_set(label, value, TYPE_STRING, strlen(value)+1, NULL, NULL, &list_assertions, size_assertions); |
302 |
} |
303 |
|
304 |
EES_RC aos_set_pem(const char* label, char* value){ |
305 |
return aos_set(label, value, TYPE_PEM, strlen(value)+1, NULL, NULL, &list_assertions, size_assertions); |
306 |
} |
307 |
|
308 |
/* AOS high-level wrapper functions */ |
309 |
|
310 |
EES_RC setAssertion(const char* label, char* value){ |
311 |
return aos_set(label, value, TYPE_STRING, strlen(value)+1, NULL, NULL, &list_assertions, size_assertions); |
312 |
} |
313 |
|
314 |
char* getAssertion(const char* label){ |
315 |
return aos_get_value_by_label(label, &list_assertions, size_assertions); |
316 |
} |
317 |
|
318 |
EES_RC setObligation(const char* label, char* value){ |
319 |
if(aos_set(label, value, TYPE_STRING, strlen(value)+1, NULL, NULL, &list_obligations, size_obligations)){ |
320 |
return EES_SUCCESS; |
321 |
} else { |
322 |
return EES_FAILURE; |
323 |
} |
324 |
} |
325 |
|
326 |
char* getObligation(const char* label){ |
327 |
return aos_get_value_by_label(label, &list_obligations, size_obligations); |
328 |
} |
329 |
|
330 |
EES_RC destroyObligation(const char* label){ |
331 |
return aos_delete_argument_by_label(label, &list_obligations, size_obligations); |
332 |
} |
333 |
|
334 |
|
335 |
EES_RC aos_dump_argslists (void){ |
336 |
eef_log(LOG_ERR, "Dumping Assertions AOS\n"); |
337 |
aos_dump_argslist(&list_assertions, size_assertions); |
338 |
eef_log(LOG_ERR, "Dumping Obligations AOS\n"); |
339 |
aos_dump_argslist(&list_obligations, size_obligations); |
340 |
return EES_SUCCESS; |
341 |
} |
342 |
|
343 |
EES_RC aos_dump_argslist (aos_argument_t **head_node, unsigned int *args_size) { |
344 |
unsigned int i; |
345 |
aos_argument_t * current_arg = *head_node; |
346 |
for(i = 0; i < (*args_size); i++){ |
347 |
eef_log(LOG_ERR, "Element %03i - at point %p - label \"%s\" - needs_free %s\n", i, current_arg, current_arg->label, current_arg -> needs_free ? "yes" : "no"); |
348 |
eef_log(LOG_ERR, " - type %d - \"%s\"", current_arg -> type, current_arg -> type == TYPE_STRING ? (char *) current_arg -> data : "non-string data"); |
349 |
current_arg = current_arg->next; |
350 |
} |
351 |
return EES_SUCCESS; |
352 |
} |
353 |
|