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