1
2 /* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
3 Message handling facility of libisofs.
4 Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
5 provided under GPL version 2 or later
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "../config.h"
10 #endif
11
12 #include <stdio.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <errno.h>
18 #include <sys/time.h>
19
20 /* Only this single source module is entitled to do this */
21 #define LIBISO_MSGS_H_INTERNAL 1
22
23 /* All participants in the messaging system must do this */
24 #include "libiso_msgs.h"
25
26
27 /* ----------------------------- libiso_msgs_item ------------------------- */
28
29
libiso_msgs_item_new(struct libiso_msgs_item ** item,struct libiso_msgs_item * link,int flag)30 static int libiso_msgs_item_new(struct libiso_msgs_item **item,
31 struct libiso_msgs_item *link, int flag)
32 {
33 int ret;
34 struct libiso_msgs_item *o;
35 struct timeval tv;
36
37 (*item)= o=
38 (struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
39 if(o==NULL)
40 return(-1);
41 o->timestamp= 0.0;
42 ret= gettimeofday(&tv, NULL);
43 if(ret==0)
44 o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
45 o->process_id= getpid();
46 o->origin= -1;
47 o->severity= LIBISO_MSGS_SEV_ALL;
48 o->priority= LIBISO_MSGS_PRIO_ZERO;
49 o->error_code= 0;
50 o->msg_text= NULL;
51 o->os_errno= 0;
52 o->prev= link;
53 o->next= NULL;
54 if(link!=NULL) {
55 if(link->next!=NULL) {
56 link->next->prev= o;
57 o->next= link->next;
58 }
59 link->next= o;
60 }
61 return(1);
62 }
63
64
65 /** Detaches item from its queue and eventually readjusts start, end pointers
66 of the queue */
libiso_msgs_item_unlink(struct libiso_msgs_item * o,struct libiso_msgs_item ** chain_start,struct libiso_msgs_item ** chain_end,int flag)67 int libiso_msgs_item_unlink(struct libiso_msgs_item *o,
68 struct libiso_msgs_item **chain_start,
69 struct libiso_msgs_item **chain_end, int flag)
70 {
71 if(o->prev!=NULL)
72 o->prev->next= o->next;
73 if(o->next!=NULL)
74 o->next->prev= o->prev;
75 if(chain_start!=NULL)
76 if(*chain_start == o)
77 *chain_start= o->next;
78 if(chain_end!=NULL)
79 if(*chain_end == o)
80 *chain_end= o->prev;
81 o->next= o->prev= NULL;
82 return(1);
83 }
84
85
libiso_msgs_item_destroy(struct libiso_msgs_item ** item,int flag)86 int libiso_msgs_item_destroy(struct libiso_msgs_item **item,
87 int flag)
88 {
89 struct libiso_msgs_item *o;
90
91 o= *item;
92 if(o==NULL)
93 return(0);
94 libiso_msgs_item_unlink(o,NULL,NULL,0);
95 if(o->msg_text!=NULL)
96 free((char *) o->msg_text);
97 free((char *) o);
98 *item= NULL;
99 return(1);
100 }
101
102
libiso_msgs_item_get_msg(struct libiso_msgs_item * item,int * error_code,char ** msg_text,int * os_errno,int flag)103 int libiso_msgs_item_get_msg(struct libiso_msgs_item *item,
104 int *error_code, char **msg_text, int *os_errno,
105 int flag)
106 {
107 *error_code= item->error_code;
108 *msg_text= item->msg_text;
109 *os_errno= item->os_errno;
110 return(1);
111 }
112
113
libiso_msgs_item_get_origin(struct libiso_msgs_item * item,double * timestamp,pid_t * process_id,int * origin,int flag)114 int libiso_msgs_item_get_origin(struct libiso_msgs_item *item,
115 double *timestamp, pid_t *process_id, int *origin,
116 int flag)
117 {
118 *timestamp= item->timestamp;
119 *process_id= item->process_id;
120 *origin= item->origin;
121 return(1);
122 }
123
124
libiso_msgs_item_get_rank(struct libiso_msgs_item * item,int * severity,int * priority,int flag)125 int libiso_msgs_item_get_rank(struct libiso_msgs_item *item,
126 int *severity, int *priority, int flag)
127 {
128 *severity= item->severity;
129 *priority= item->priority;
130 return(1);
131 }
132
133
134 /* ------------------------------- libiso_msgs ---------------------------- */
135
136
libiso_msgs_new(struct libiso_msgs ** m,int flag)137 int libiso_msgs_new(struct libiso_msgs **m, int flag)
138 {
139 struct libiso_msgs *o;
140
141 (*m)= o= (struct libiso_msgs *) malloc(sizeof(struct libiso_msgs));
142 if(o==NULL)
143 return(-1);
144 o->refcount= 1;
145 o->oldest= NULL;
146 o->youngest= NULL;
147 o->count= 0;
148 o->queue_severity= LIBISO_MSGS_SEV_ALL;
149 o->print_severity= LIBISO_MSGS_SEV_NEVER;
150 strcpy(o->print_id,"libiso: ");
151
152 #ifndef LIBISO_MSGS_SINGLE_THREADED
153 pthread_mutex_init(&(o->lock_mutex),NULL);
154 #endif
155
156 return(1);
157 }
158
159
libiso_msgs_lock(struct libiso_msgs * m,int flag)160 static int libiso_msgs_lock(struct libiso_msgs *m, int flag)
161 {
162
163 #ifndef LIBISO_MSGS_SINGLE_THREADED
164 int ret;
165
166 ret= pthread_mutex_lock(&(m->lock_mutex));
167 if(ret!=0)
168 return(0);
169 #endif
170
171 return(1);
172 }
173
174
libiso_msgs_unlock(struct libiso_msgs * m,int flag)175 static int libiso_msgs_unlock(struct libiso_msgs *m, int flag)
176 {
177
178 #ifndef LIBISO_MSGS_SINGLE_THREADED
179 int ret;
180
181 ret= pthread_mutex_unlock(&(m->lock_mutex));
182 if(ret!=0)
183 return(0);
184 #endif
185
186 return(1);
187 }
188
189
libiso_msgs_destroy(struct libiso_msgs ** m,int flag)190 int libiso_msgs_destroy(struct libiso_msgs **m, int flag)
191 {
192 struct libiso_msgs *o;
193 struct libiso_msgs_item *item, *next_item;
194
195 o= *m;
196 if(o==NULL)
197 return(0);
198 if(o->refcount > 1) {
199 if(libiso_msgs_lock(*m,0)<=0)
200 return(-1);
201 o->refcount--;
202 libiso_msgs_unlock(*m,0);
203 *m= NULL;
204 return(1);
205 }
206
207 #ifndef LIBISO_MSGS_SINGLE_THREADED
208 if(pthread_mutex_destroy(&(o->lock_mutex))!=0) {
209 pthread_mutex_unlock(&(o->lock_mutex));
210 pthread_mutex_destroy(&(o->lock_mutex));
211 }
212 #endif
213
214 for(item= o->oldest; item!=NULL; item= next_item) {
215 next_item= item->next;
216 libiso_msgs_item_destroy(&item,0);
217 }
218 free((char *) o);
219 *m= NULL;
220 return(1);
221 }
222
223
libiso_msgs_refer(struct libiso_msgs ** pt,struct libiso_msgs * m,int flag)224 int libiso_msgs_refer(struct libiso_msgs **pt, struct libiso_msgs *m, int flag)
225 {
226 if(libiso_msgs_lock(m,0)<=0)
227 return(0);
228 m->refcount++;
229 *pt= m;
230 libiso_msgs_unlock(m,0);
231 return(1);
232 }
233
234
libiso_msgs_set_severities(struct libiso_msgs * m,int queue_severity,int print_severity,char * print_id,int flag)235 int libiso_msgs_set_severities(struct libiso_msgs *m, int queue_severity,
236 int print_severity, char *print_id, int flag)
237 {
238 if(libiso_msgs_lock(m,0)<=0)
239 return(0);
240 m->queue_severity= queue_severity;
241 m->print_severity= print_severity;
242 strncpy(m->print_id,print_id,80);
243 m->print_id[80]= 0;
244 libiso_msgs_unlock(m,0);
245 return(1);
246 }
247
248
libiso_msgs__text_to_sev(char * severity_name,int * severity,int flag)249 int libiso_msgs__text_to_sev(char *severity_name, int *severity,
250 int flag)
251 {
252 if(strncmp(severity_name,"NEVER",5)==0)
253 *severity= LIBISO_MSGS_SEV_NEVER;
254 else if(strncmp(severity_name,"ABORT",5)==0)
255 *severity= LIBISO_MSGS_SEV_ABORT;
256 else if(strncmp(severity_name,"FATAL",5)==0)
257 *severity= LIBISO_MSGS_SEV_FATAL;
258 else if(strncmp(severity_name,"FAILURE",7)==0)
259 *severity= LIBISO_MSGS_SEV_FAILURE;
260 else if(strncmp(severity_name,"MISHAP",6)==0)
261 *severity= LIBISO_MSGS_SEV_MISHAP;
262 else if(strncmp(severity_name,"SORRY",5)==0)
263 *severity= LIBISO_MSGS_SEV_SORRY;
264 else if(strncmp(severity_name,"WARNING",7)==0)
265 *severity= LIBISO_MSGS_SEV_WARNING;
266 else if(strncmp(severity_name,"HINT",4)==0)
267 *severity= LIBISO_MSGS_SEV_HINT;
268 else if(strncmp(severity_name,"NOTE",4)==0)
269 *severity= LIBISO_MSGS_SEV_NOTE;
270 else if(strncmp(severity_name,"UPDATE",6)==0)
271 *severity= LIBISO_MSGS_SEV_UPDATE;
272 else if(strncmp(severity_name,"DEBUG",5)==0)
273 *severity= LIBISO_MSGS_SEV_DEBUG;
274 else if(strncmp(severity_name,"ERRFILE",7)==0)
275 *severity= LIBISO_MSGS_SEV_ERRFILE;
276 else if(strncmp(severity_name,"ALL",3)==0)
277 *severity= LIBISO_MSGS_SEV_ALL;
278 else {
279 *severity= LIBISO_MSGS_SEV_ALL;
280 return(0);
281 }
282 return(1);
283 }
284
285
libiso_msgs__sev_to_text(int severity,char ** severity_name,int flag)286 int libiso_msgs__sev_to_text(int severity, char **severity_name,
287 int flag)
288 {
289 if(flag&1) {
290 *severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
291 return(1);
292 }
293 *severity_name= "";
294 if(severity>=LIBISO_MSGS_SEV_NEVER)
295 *severity_name= "NEVER";
296 else if(severity>=LIBISO_MSGS_SEV_ABORT)
297 *severity_name= "ABORT";
298 else if(severity>=LIBISO_MSGS_SEV_FATAL)
299 *severity_name= "FATAL";
300 else if(severity>=LIBISO_MSGS_SEV_FAILURE)
301 *severity_name= "FAILURE";
302 else if(severity>=LIBISO_MSGS_SEV_MISHAP)
303 *severity_name= "MISHAP";
304 else if(severity>=LIBISO_MSGS_SEV_SORRY)
305 *severity_name= "SORRY";
306 else if(severity>=LIBISO_MSGS_SEV_WARNING)
307 *severity_name= "WARNING";
308 else if(severity>=LIBISO_MSGS_SEV_HINT)
309 *severity_name= "HINT";
310 else if(severity>=LIBISO_MSGS_SEV_NOTE)
311 *severity_name= "NOTE";
312 else if(severity>=LIBISO_MSGS_SEV_UPDATE)
313 *severity_name= "UPDATE";
314 else if(severity>=LIBISO_MSGS_SEV_DEBUG)
315 *severity_name= "DEBUG";
316 else if(severity>=LIBISO_MSGS_SEV_ERRFILE)
317 *severity_name= "ERRFILE";
318 else if(severity>=LIBISO_MSGS_SEV_ALL)
319 *severity_name= "ALL";
320 else {
321 *severity_name= "";
322 return(0);
323 }
324 return(1);
325 }
326
327
libiso_msgs_submit(struct libiso_msgs * m,int origin,int error_code,int severity,int priority,char * msg_text,int os_errno,int flag)328 int libiso_msgs_submit(struct libiso_msgs *m, int origin, int error_code,
329 int severity, int priority, char *msg_text,
330 int os_errno, int flag)
331 {
332 int ret;
333 char *textpt,*sev_name,sev_text[81];
334 struct libiso_msgs_item *item= NULL;
335
336 if(severity >= m->print_severity) {
337 if(msg_text==NULL)
338 textpt= "";
339 else
340 textpt= msg_text;
341 sev_text[0]= 0;
342 ret= libiso_msgs__sev_to_text(severity,&sev_name,0);
343 if(ret>0)
344 sprintf(sev_text,"%s : ",sev_name);
345
346 fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt);
347 if(os_errno!=0) {
348 ret= libiso_msgs_lock(m,0);
349 if(ret<=0)
350 return(-1);
351 fprintf(stderr,"%s( Most recent system error: %d '%s' )\n",
352 m->print_id,os_errno,strerror(os_errno));
353 libiso_msgs_unlock(m,0);
354 }
355
356 }
357 if(severity < m->queue_severity)
358 return(0);
359
360 ret= libiso_msgs_lock(m,0);
361 if(ret<=0)
362 return(-1);
363 ret= libiso_msgs_item_new(&item,m->youngest,0);
364 if(ret<=0)
365 goto failed;
366 item->origin= origin;
367 item->error_code= error_code;
368 item->severity= severity;
369 item->priority= priority;
370 if(msg_text!=NULL) {
371 item->msg_text= malloc(strlen(msg_text)+1);
372 if(item->msg_text==NULL)
373 goto failed;
374 strcpy(item->msg_text,msg_text);
375 }
376 item->os_errno= os_errno;
377 if(m->oldest==NULL)
378 m->oldest= item;
379 m->youngest= item;
380 m->count++;
381 libiso_msgs_unlock(m,0);
382
383 /*
384 fprintf(stderr,"libiso_experimental: message submitted to queue (now %d)\n",
385 m->count);
386 */
387
388 return(1);
389 failed:;
390 libiso_msgs_item_destroy(&item,0);
391 libiso_msgs_unlock(m,0);
392 return(-1);
393 }
394
395
libiso_msgs_obtain(struct libiso_msgs * m,struct libiso_msgs_item ** item,int severity,int priority,int flag)396 int libiso_msgs_obtain(struct libiso_msgs *m, struct libiso_msgs_item **item,
397 int severity, int priority, int flag)
398 {
399 int ret;
400 struct libiso_msgs_item *im, *next_im= NULL;
401
402 *item= NULL;
403 ret= libiso_msgs_lock(m,0);
404 if(ret<=0)
405 return(-1);
406 for(im= m->oldest; im!=NULL; im= next_im) {
407 for(; im!=NULL; im= next_im) {
408 next_im= im->next;
409 if(im->severity>=severity)
410 break;
411 libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
412 libiso_msgs_item_destroy(&im,0); /* severity too low: delete */
413 }
414 if(im==NULL)
415 break;
416 if(im->priority>=priority)
417 break;
418 }
419 if(im==NULL)
420 {ret= 0; goto ex;}
421 libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
422 *item= im;
423 ret= 1;
424 ex:;
425 libiso_msgs_unlock(m,0);
426 return(ret);
427 }
428
429
libiso_msgs_destroy_item(struct libiso_msgs * m,struct libiso_msgs_item ** item,int flag)430 int libiso_msgs_destroy_item(struct libiso_msgs *m,
431 struct libiso_msgs_item **item, int flag)
432 {
433 int ret;
434
435 ret= libiso_msgs_lock(m,0);
436 if(ret<=0)
437 return(-1);
438 ret= libiso_msgs_item_destroy(item,0);
439 libiso_msgs_unlock(m,0);
440 return(ret);
441 }
442
443