From f59071dde9d60102d7c8b194c34b89f2a29cc27f Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 24 Sep 2006 17:16:01 +0000 Subject: [PATCH] Added an error message handling facility (ticket 74) --- trunk/Makefile.am | 2 + trunk/cdrskin/cdrskin.c | 9 +- trunk/cdrskin/cdrskin_timestamp.h | 2 +- trunk/cdrskin/compile_cdrskin.sh | 5 + trunk/libburn/init.c | 108 +++++++++ trunk/libburn/libburn.h | 39 ++++ trunk/libburn/libdax_msgs.c | 364 ++++++++++++++++++++++++++++++ trunk/libburn/libdax_msgs.h | 330 +++++++++++++++++++++++++++ 8 files changed, 857 insertions(+), 2 deletions(-) create mode 100644 trunk/libburn/libdax_msgs.c create mode 100644 trunk/libburn/libdax_msgs.h diff --git a/trunk/Makefile.am b/trunk/Makefile.am index e75320cb..1447e8ee 100644 --- a/trunk/Makefile.am +++ b/trunk/Makefile.am @@ -26,6 +26,8 @@ libburn_libburn_la_SOURCES = \ libburn/lec.c \ libburn/lec.h \ libburn/libburn.h \ + libburn/libdax_msgs.h \ + libburn/libdax_msgs.c \ libburn/message.c \ libburn/message.h \ libburn/mmc.c \ diff --git a/trunk/cdrskin/cdrskin.c b/trunk/cdrskin/cdrskin.c index c376c191..4dcfa0e0 100644 --- a/trunk/cdrskin/cdrskin.c +++ b/trunk/cdrskin/cdrskin.c @@ -166,6 +166,7 @@ or #define Cdrskin_libburn_has_is_enumerablE 1 #define Cdrskin_libburn_has_convert_fs_adR 1 #define Cdrskin_libburn_has_convert_scsi_adR 1 +#define Cdrskin_libburn_has_burn_msgS 1 #endif #ifndef Cdrskin_libburn_versioN @@ -1280,7 +1281,7 @@ int Cdrpreskin_destroy(struct CdrpreskiN **preskin, int flag) int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN], int *driveno, int flag) { - int comma_seen= 0,digit_seen= 0,busno= 0,k,lun_no= -1,ret= 0; + int comma_seen= 0,digit_seen= 0,busno= 0,k,lun_no= -1; *driveno= -1; device_adr[0]= 0; @@ -1344,6 +1345,8 @@ int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN], #ifdef Cdrskin_libburn_has_convert_scsi_adR } else { + int ret; + ret= burn_drive_convert_scsi_adr(busno,-1,*driveno,lun_no,device_adr); return(ret); #endif @@ -4464,6 +4467,10 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin, } *lib_initialized= 1; +#ifdef Cdrskin_libburn_has_burn_msgS + burn_msgs_set_severities("NEVER","SORRY","cdrskin: "); +#endif + #ifndef Cdrskin_libburn_no_burn_preset_device_opeN burn_preset_device_open((*preskin)->drive_exclusive, (*preskin)->drive_blocking, diff --git a/trunk/cdrskin/cdrskin_timestamp.h b/trunk/cdrskin/cdrskin_timestamp.h index 0bb709e6..4446da9b 100644 --- a/trunk/cdrskin/cdrskin_timestamp.h +++ b/trunk/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2006.09.23.183608" +#define Cdrskin_timestamP "2006.09.24.171706" diff --git a/trunk/cdrskin/compile_cdrskin.sh b/trunk/cdrskin/compile_cdrskin.sh index ce0d1dfd..203a3324 100755 --- a/trunk/cdrskin/compile_cdrskin.sh +++ b/trunk/cdrskin/compile_cdrskin.sh @@ -7,6 +7,7 @@ debug_opts= def_opts= libvers="-DCdrskin_libburn_0_2_3" +libdax_msgs_o="libburn/libdax_msgs.o" do_strip=0 static_opts= warn_opts="-Wall" @@ -22,12 +23,15 @@ do elif test "$i" = "-cvs_A60220" then libvers="-DCdrskin_libburn_cvs_A60220_tS" + libdax_msgs_o= elif test "$i" = "-libburn_0_2_2" then libvers="-DCdrskin_libburn_0_2_2" + libdax_msgs_o= elif test "$i" = "-libburn_0_2_3" then libvers="-DCdrskin_libburn_0_2_3" + libdax_msgs_o="libburn/libdax_msgs.o" elif test "$i" = "-newapi" -o "$i" = "-experimental" then def_opts="$def_opts -DCdrskin_new_api_tesT" @@ -103,6 +107,7 @@ then libburn/message.o \ libburn/sg.o \ libburn/write.o \ + $libdax_msgs_o \ \ libburn/mmc.o \ libburn/sbc.o \ diff --git a/trunk/libburn/init.c b/trunk/libburn/init.c index 552229dc..b546681c 100644 --- a/trunk/libburn/init.c +++ b/trunk/libburn/init.c @@ -4,6 +4,8 @@ #include #include #include +#include + #include "init.h" #include "sg.h" #include "error.h" @@ -14,6 +16,11 @@ #define BURN_BACK_HACKS_INIT 1 #include "back_hacks.h" +/* ts A60924 : a new message handling facility */ +#include "libdax_msgs.h" +static struct libdax_msgs *libdax_messenger= NULL; + + int burn_running = 0; /* ts A60813 : wether to use O_EXCL and/or O_NONBLOCK in libburn/sg.c */ @@ -31,11 +38,21 @@ int burn_sg_open_o_nonblock = 1; int burn_sg_open_abort_busy = 0; +/* ts A60924 : ticket 74 : Added use of global libdax_messenger */ int burn_initialize(void) { + int ret; + if (burn_running) return 1; + ret = libdax_msgs_new(&libdax_messenger,0); + if (ret <= 0) + return 0; + /* A60924: Apps enable queueing via burn_msgs_set_severities() */ + libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER, + LIBDAX_MSGS_SEV_FATAL, "libburn: ", 0); + burn_running = 1; return 1; } @@ -49,6 +66,9 @@ void burn_finish(void) /* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */ burn_drive_free_all(); + /* ts A60924 : ticket 74 */ + libdax_msgs_destroy(&libdax_messenger,0); + burn_running = 0; } @@ -78,3 +98,91 @@ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy) burn_sg_open_abort_busy= !!abort_on_busy; } + +/* ts A60924 : ticket 74 */ +/** Control queueing and stderr printing of messages from libburn. + Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", + "NOTE", "UPDATE", "DEBUG", "ALL". + @param queue_severity Gives the minimum limit for messages to be queued. + Default: "NEVER". If you queue messages then you + must consume them by burn_msgs_obtain(). + @param print_severity Does the same for messages to be printed directly + to stderr. + @param print_id A text prefix to be printed before the message. + @return >0 for success, <=0 for error + +*/ +int burn_msgs_set_severities(char *queue_severity, + char *print_severity, char *print_id) +{ + int ret, queue_sevno, print_sevno; + + ret = libdax_msgs__text_to_sev(queue_severity, &queue_sevno, 0); + if (ret <= 0) + return 0; + ret = libdax_msgs__text_to_sev(print_severity, &print_sevno, 0); + if (ret <= 0) + return 0; + ret = libdax_msgs_set_severities(libdax_messenger, queue_sevno, + print_sevno, print_id, 0); + if (ret <= 0) + return 0; + return 1; +} + + +/* ts A60924 : ticket 74 */ +#define BURM_MSGS_MESSAGE_LEN 4096 + +/** Obtain the oldest pending libburn message from the queue which has at + least the given minimum_severity. This message and any older message of + lower severity will get discarded from the queue and is then lost forever. + Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", + "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" + will discard the whole queue. + @param error_code Will become a unique error code as liste in + libburn/libdax_msgs.h + @param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes. + @param os_errno Will become the eventual errno related to the message + @param severity Will become the severity related to the message and + should provide at least 80 bytes. + @return 1 if a matching item was found, 0 if not, <0 for severe errors +*/ +int burn_msgs_obtain(char *minimum_severity, + int *error_code, char msg_text[], int *os_errno, + char severity[]) +{ + int ret, minimum_sevno, sevno, priority; + char *textpt, *sev_name; + struct libdax_msgs_item *item = NULL; + + ret = libdax_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0); + if (ret <= 0) + return 0; + ret = libdax_msgs_obtain(libdax_messenger, &item, minimum_sevno, + LIBDAX_MSGS_PRIO_ZERO, 0); + if (ret <= 0) + goto ex; + + ret = libdax_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0); + if (ret <= 0) + goto ex; + strncpy(msg_text, textpt, BURM_MSGS_MESSAGE_LEN-1); + if(strlen(textpt) >= BURM_MSGS_MESSAGE_LEN) + msg_text[BURM_MSGS_MESSAGE_LEN-1] = 0; + + severity[0]= 0; + ret = libdax_msgs_item_get_rank(item, &sevno, &priority, 0); + if(ret <= 0) + goto ex; + ret = libdax_msgs__sev_to_text(sevno, &sev_name, 0); + if(ret <= 0) + goto ex; + strcpy(severity,sev_name); + + ret = 1; +ex: + libdax_msgs_destroy_item(libdax_messenger, &item, 0); + return ret; +} + diff --git a/trunk/libburn/libburn.h b/trunk/libburn/libburn.h index d80511d5..d18c9fd4 100644 --- a/trunk/libburn/libburn.h +++ b/trunk/libburn/libburn.h @@ -1072,6 +1072,45 @@ int burn_session_get_hidefirst(struct burn_session *session); */ void burn_version(int *major, int *minor, int *micro); + +/* ts A60924 : ticket 74 */ +/** Control queueing and stderr printing of messages from libburn. + Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", + "NOTE", "UPDATE", "DEBUG", "ALL". + @param queue_severity Gives the minimum limit for messages to be queued. + Default: "NEVER". If you queue messages then you + must consume them by burn_msgs_obtain(). + @param print_severity Does the same for messages to be printed directly + to stderr. + @param print_id A text prefix to be printed before the message. + @return >0 for success, <=0 for error + +*/ +int burn_msgs_set_severities(char *queue_severity, + char *print_severity, char *print_id); + +/* ts A60924 : ticket 74 */ +#define BURM_MSGS_MESSAGE_LEN 4096 + +/** Obtain the oldest pending libburn message from the queue which has at + least the given minimum_severity. This message and any older message of + lower severity will get discarded from the queue and is then lost forever. + Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", + "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" + will discard the whole queue. + @param error_code Will become a unique error code as liste in + libburn/libdax_msgs.h + @param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes. + @param os_errno Will become the eventual errno related to the message + @param severity Will become the severity related to the message and + should provide at least 80 bytes. + @return 1 if a matching item was found, 0 if not, <0 for severe errors +*/ +int burn_msgs_obtain(char *minimum_severity, + int *error_code, char msg_text[], int *os_errno, + char severity[]); + + #ifndef DOXYGEN BURN_END_DECLS diff --git a/trunk/libburn/libdax_msgs.c b/trunk/libburn/libdax_msgs.c new file mode 100644 index 00000000..04dc9438 --- /dev/null +++ b/trunk/libburn/libdax_msgs.c @@ -0,0 +1,364 @@ + +/* libdax_msgs + Message handling facility of libdax. + Copyright (C) 2006 Thomas Schmitt , provided under GPL +*/ + +#include +#include +#include +#include +#include +#include +#include + +/* Only this single source module is entitled to do this */ +#define LIBDAX_MSGS_H_INTERNAL 1 + +/* All participants in the messaging system must do this */ +#include "libdax_msgs.h" + + +/* ----------------------------- libdax_msgs_item ------------------------- */ + + +static int libdax_msgs_item_new(struct libdax_msgs_item **item, + struct libdax_msgs_item *link, int flag) +{ + int ret; + struct libdax_msgs_item *o; + struct timeval tv; + struct timezone tz; + + (*item)= o= + (struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item)); + if(o==NULL) + return(-1); + o->timestamp= 0.0; + ret= gettimeofday(&tv,&tz); + if(ret==0) + o->timestamp= tv.tv_sec+0.000001*tv.tv_usec; + o->process_id= getpid(); + o->driveno= -1; + o->severity= LIBDAX_MSGS_SEV_ALL; + o->priority= LIBDAX_MSGS_PRIO_ZERO; + o->error_code= 0; + o->msg_text= NULL; + o->os_errno= 0; + o->prev= link; + o->next= NULL; + if(link!=NULL) { + if(link->next!=NULL) { + link->next->prev= o; + o->next= link->next; + } + link->next= o; + } + return(1); +} + + +int libdax_msgs_item_destroy(struct libdax_msgs_item **item, + int flag) +{ + struct libdax_msgs_item *o; + + o= *item; + if(o==NULL) + return(0); + if(o->msg_text!=NULL) + free((char *) o->msg_text); + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + free((char *) o); + *item= NULL; + return(1); +} + + +int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, + int *error_code, char **msg_text, int *os_errno, + int flag) +{ + *error_code= item->error_code; + *msg_text= item->msg_text; + *os_errno= item->os_errno; + return(1); +} + + +int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, + double *timestamp, pid_t *process_id, int *driveno, + int flag) +{ + *timestamp= item->timestamp; + *process_id= item->process_id; + *driveno= item->driveno; + return(1); +} + + +int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, + int *severity, int *priority, int flag) +{ + *severity= item->severity; + *priority= item->priority; + return(1); +} + + +/* ------------------------------- libdax_msgs ---------------------------- */ + + +int libdax_msgs_new(struct libdax_msgs **m, int flag) +{ + struct libdax_msgs *o; + + (*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs)); + if(o==NULL) + return(-1); + o->oldest= NULL; + o->youngest= NULL; + o->count= 0; + o->queue_severity= LIBDAX_MSGS_SEV_ALL; + o->print_severity= LIBDAX_MSGS_SEV_NEVER; + strcpy(o->print_id,"libdax: "); + +#ifndef LIBDAX_MSGS_SINGLE_THREADED + pthread_mutex_init(&(o->lock_mutex),NULL); +#endif + + return(1); +} + + +int libdax_msgs_destroy(struct libdax_msgs **m, int flag) +{ + struct libdax_msgs *o; + struct libdax_msgs_item *item, *next_item; + + o= *m; + if(o==NULL) + return(0); + +#ifndef LIBDAX_MSGS_SINGLE_THREADED + if(pthread_mutex_destroy(&(o->lock_mutex))!=0) { + pthread_mutex_unlock(&(o->lock_mutex)); + pthread_mutex_destroy(&(o->lock_mutex)); + } +#endif + + for(item= o->oldest; item!=NULL; item= next_item) { + next_item= item->next; + libdax_msgs_item_destroy(&item,0); + } + free((char *) o); + *m= NULL; + return(1); +} + + +int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, + int print_severity, char *print_id, int flag) +{ + m->queue_severity= queue_severity; + m->print_severity= print_severity; + strncpy(m->print_id,print_id,80); + m->print_id[80]= 0; + return(1); +} + + +static int libdax_msgs_lock(struct libdax_msgs *m, int flag) +{ + +#ifndef LIBDAX_MSGS_SINGLE_THREADED + int ret; + + ret= pthread_mutex_lock(&(m->lock_mutex)); + if(ret!=0) + return(0); +#endif + + return(1); +} + + +static int libdax_msgs_unlock(struct libdax_msgs *m, int flag) +{ + +#ifndef LIBDAX_MSGS_SINGLE_THREADED + int ret; + + ret= pthread_mutex_unlock(&(m->lock_mutex)); + if(ret!=0) + return(0); +#endif + + return(1); +} + + +int libdax_msgs__text_to_sev(char *severity_name, int *severity, + int flag) +{ + if(strncmp(severity_name,"NEVER",5)==0) + *severity= LIBDAX_MSGS_SEV_NEVER; + else if(strncmp(severity_name,"FATAL",5)==0) + *severity= LIBDAX_MSGS_SEV_FATAL; + else if(strncmp(severity_name,"SORRY",5)==0) + *severity= LIBDAX_MSGS_SEV_SORRY; + else if(strncmp(severity_name,"WARNING",7)==0) + *severity= LIBDAX_MSGS_SEV_WARNING; + else if(strncmp(severity_name,"HINT",4)==0) + *severity= LIBDAX_MSGS_SEV_HINT; + else if(strncmp(severity_name,"NOTE",4)==0) + *severity= LIBDAX_MSGS_SEV_NOTE; + else if(strncmp(severity_name,"UPDATE",6)==0) + *severity= LIBDAX_MSGS_SEV_UPDATE; + else if(strncmp(severity_name,"DEBUG",5)==0) + *severity= LIBDAX_MSGS_SEV_DEBUG; + else if(strncmp(severity_name,"ALL",3)==0) + *severity= LIBDAX_MSGS_SEV_ALL; + else { + *severity= LIBDAX_MSGS_SEV_NEVER; + return(0); + } + return(1); +} + + +int libdax_msgs__sev_to_text(int severity, char **severity_name, + int flag) +{ + if(flag&1) { + *severity_name= + "NEVER\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL"; + return(1); + } + *severity_name= ""; + if(severity>=LIBDAX_MSGS_SEV_NEVER) + *severity_name= "NEVER"; + else if(severity>=LIBDAX_MSGS_SEV_FATAL) + *severity_name= "FATAL"; + else if(severity>=LIBDAX_MSGS_SEV_SORRY) + *severity_name= "SORRY"; + else if(severity>=LIBDAX_MSGS_SEV_WARNING) + *severity_name= "WARNING"; + else if(severity>=LIBDAX_MSGS_SEV_HINT) + *severity_name= "HINT"; + else if(severity>=LIBDAX_MSGS_SEV_NOTE) + *severity_name= "NOTE"; + else if(severity>=LIBDAX_MSGS_SEV_UPDATE) + *severity_name= "UPDATE"; + else if(severity>=LIBDAX_MSGS_SEV_DEBUG) + *severity_name= "DEBUG"; + else if(severity>=LIBDAX_MSGS_SEV_ALL) + *severity_name= "ALL"; + else { + *severity_name= ""; + return(0); + } + return(1); +} + + +int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code, + int severity, int priority, char *msg_text, + int os_errno, int flag) +{ + int ret; + char *textpt,*sev_name,sev_text[81]; + struct libdax_msgs_item *item= NULL; + + if(severity >= m->print_severity) { + if(msg_text==NULL) + textpt= ""; + else + textpt= msg_text; + sev_text[0]= 0; + ret= libdax_msgs__sev_to_text(severity,&sev_name,0); + if(ret>0) + sprintf(sev_text,"%s : ",sev_name); + + fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt); + if(os_errno!=0) + perror(m->print_id); + } + if(severity < m->queue_severity) + return(0); + + ret= libdax_msgs_lock(m,0); + if(ret<=0) + return(-1); + ret= libdax_msgs_item_new(&item,m->youngest,0); + if(ret<=0) + goto failed; + item->driveno= driveno; + item->error_code= error_code; + item->severity= severity; + item->priority= priority; + if(msg_text!=NULL) { + item->msg_text= malloc(strlen(msg_text)+1); + if(item->msg_text==NULL) + goto failed; + strcpy(item->msg_text,msg_text); + } + item->os_errno= os_errno; + m->youngest= item; + m->count++; + libdax_msgs_unlock(m,0); + return(1); +failed:; + libdax_msgs_item_destroy(&item,0); + libdax_msgs_unlock(m,0); + return(-1); +} + + +int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, + int severity, int priority, int flag) +{ + int ret; + struct libdax_msgs_item *im, *next_im= NULL; + + ret= libdax_msgs_lock(m,0); + if(ret<=0) + return(-1); + for(im= m->oldest; im!=NULL; im= next_im) { + for(; im!=NULL; im= next_im) { + next_im= im->next; + if(im->severity>=severity) + break; + libdax_msgs_item_destroy(&im,0); /* severity too low: delete */ + } + if(im==NULL) + break; + if(im->priority>=priority) + break; + } + if(im==NULL) + {ret= 0; goto ex;} + *item= im; + ret= 1; +ex:; + libdax_msgs_unlock(m,0); + return(ret); +} + + +int libdax_msgs_destroy_item(struct libdax_msgs *m, + struct libdax_msgs_item **item, int flag) +{ + int ret; + + ret= libdax_msgs_lock(m,0); + if(ret<=0) + return(-1); + ret= libdax_msgs_item_destroy(item,0); + libdax_msgs_unlock(m,0); + return(ret); +} + diff --git a/trunk/libburn/libdax_msgs.h b/trunk/libburn/libdax_msgs.h new file mode 100644 index 00000000..2414194a --- /dev/null +++ b/trunk/libburn/libdax_msgs.h @@ -0,0 +1,330 @@ + +/* libdax_msgs + Message handling facility of libdax. + Copyright (C) 2006 Thomas Schmitt , provided under GPL +*/ + + +/* + *Never* set this macro outside libdax_msgs.c ! + The entrails of the message handling facility are not to be seen by + the other library components or the applications. +*/ +#ifdef LIBDAX_MSGS_H_INTERNAL + + +#ifndef LIBDAX_MSGS_SINGLE_THREADED +#include +#endif + + +struct libdax_msgs_item { + + double timestamp; + pid_t process_id; + int driveno; + + int severity; + int priority; + + /* Apply for your developer's error code range at + libburn-hackers@pykix.org + Report introduced codes in the list below. */ + int error_code; + + char *msg_text; + int os_errno; + + struct libdax_msgs_item *prev,*next; + +}; + + +struct libdax_msgs { + + struct libdax_msgs_item *oldest; + struct libdax_msgs_item *youngest; + int count; + + int queue_severity; + int print_severity; + char print_id[81]; + +#ifndef LIBDAX_MSGS_SINGLE_THREADED + pthread_mutex_t lock_mutex; +#endif + + +}; + +#endif /* LIBDAX_MSGS_H_INTERNAL */ + + +#ifndef LIBDAX_MSGS_H_INCLUDED +#define LIBDAX_MSGS_H_INCLUDED 1 + + +#ifndef LIBDAX_MSGS_H_INTERNAL + + + /* Public Opaque Handles */ + +/** A pointer to this is a opaque handle to a message handling facility */ +struct libdax_msgs; + +/** A pointer to this is a opaque handle to a single message item */ +struct libdax_msgs_item; + +#endif /* ! LIBDAX_MSGS_H_INTERNAL */ + + + /* Public Macros */ + + +/* Registered Severities */ + +/* It is well advisable to let applications select severities via strings and + forwarded functions libdax_msgs__text_to_sev(), libdax_msgs__sev_to_text(). + These macros are for use by libdax/libburn only. +*/ + +/** Use this to get messages of any severity. Do not use for submitting. +*/ +#define LIBDAX_MSGS_SEV_ALL 0x00000000 + +/** Debugging messages not to be visible to normal users by default +*/ +#define LIBDAX_MSGS_SEV_DEBUG 0x10000000 + +/** Update of a progress report about long running actions +*/ +#define LIBDAX_MSGS_SEV_UPDATE 0x20000000 + +/** Not so usual events which were gracefully handled +*/ +#define LIBDAX_MSGS_SEV_NOTE 0x30000000 + +/** Possibilities to achieve a better result +*/ +#define LIBDAX_MSGS_SEV_HINT 0x40000000 + +/** Warnings about problems which could not be handled optimally +*/ +#define LIBDAX_MSGS_SEV_WARNING 0x50000000 + +/** Non-fatal error messages indicating that parts of the action failed + but processing will/should go on +*/ +#define LIBDAX_MSGS_SEV_SORRY 0x60000000 + +/** An error message which puts the whole operation of libdax in question +*/ +#define LIBDAX_MSGS_SEV_FATAL 0x70000000 + +/** A severity to exclude resp. discard any possible message. + Do not use this severity for submitting. +*/ +#define LIBDAX_MSGS_SEV_NEVER 0x7fffffff + + +/* Registered Priorities */ + +/* Priorities are to be used by libburn/libdax only. */ + +#define LIBDAX_MSGS_PRIO_ZERO 0x00000000 +#define LIBDAX_MSGS_PRIO_LOW 0x10000000 +#define LIBDAX_MSGS_PRIO_MEDIUM 0x20000000 +#define LIBDAX_MSGS_PRIO_HIGH 0x30000000 +#define LIBDAX_MSGS_PRIO_TOP 0x7ffffffe + +/* Do not use this priority for submitting */ +#define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff + + + /* Public Functions */ + + /* Calls initiated from inside libdax/libburn */ + + +/** Create new empty message handling facility with queue. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return >0 success, <=0 failure +*/ +int libdax_msgs_new(struct libdax_msgs **m, int flag); + + +/** Destroy a message handling facility and all its eventual messages. + The submitted pointer gets set to NULL. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 for success, 0 for pointer to NULL +*/ +int libdax_msgs_destroy(struct libdax_msgs **m, int flag); + + +/** Submit a message to a message handling facility. + @param driveno libdax drive number. Use -1 if no number is known. + @param error_code Unique error code. Use only registered codes. See below. + The same unique error_code may be issued at different + occasions but those should be equivalent out of the view + of a libdax application. (E.g. "cannot open ATA drive" + versus "cannot open SCSI drive" would be equivalent.) + @param severity The LIBDAX_MSGS_SEVERITY_* of the event. + @param priority The LIBDAX_MSGS_PRIORITY_* number of the event. + @param msg_text Printable and human readable message text. + @param os_errno Eventual error code from operating system (0 if none) + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 on success, 0 on rejection, <0 for severe errors +*/ +int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code, + int severity, int priority, char *msg_text, + int os_errno, int flag); + + + /* Calls from applications (to be forwarded by libdax/libburn) */ + + +/** Convert a registered severity number into a severity name + @param flag Bitfield for control purposes: + bit0= list all severity names in a newline separated string + @return >0 success, <=0 failure +*/ +int libdax_msgs__sev_to_text(int severity, char **severity_name, + int flag); + + +/** Convert a severity name into a severity number, + @param flag Bitfield for control purposes (unused yet, submit 0) + @return >0 success, <=0 failure +*/ +int libdax_msgs__text_to_sev(char *severity_name, int *severity, + int flag); + + +/** Set minimum severity for messages to be queued (default + LIBDAX_MSGS_SEV_ALL) and for messages to be printed directly to stderr + (default LIBDAX_MSGS_SEV_NEVER). + @param print_id A text of at most 80 characters to be printed before + any eventually printed message (default is "libdax: "). + @param flag Bitfield for control purposes (unused yet, submit 0) + @return always 1 for now +*/ +int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, + int print_severity, char *print_id, int flag); + + +/** Obtain a message item that has at least the given severity and priority. + Usually all older messages of lower severity are discarded then. If no + item of sufficient severity was found, all others are discarded from the + queue. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 if a matching item was found, 0 if not, <0 for severe errors +*/ +int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, + int severity, int priority, int flag); + + +/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted + pointer gets set to NULL. + Caution: Copy eventually obtained msg_text before destroying the item, + if you want to use it further. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 for success, 0 for pointer to NULL, <0 for severe errors +*/ +int libdax_msgs_destroy_item(struct libdax_msgs *m, + struct libdax_msgs_item **item, int flag); + + +/** Obtain from a message item the three application oriented components as + submitted with the originating call of libdax_msgs_submit(). + Caution: msg_text becomes a pointer into item, not a copy. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 on success, 0 on invalid item, <0 for servere errors +*/ +int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, + int *error_code, char **msg_text, int *os_errno, + int flag); + + +/** Obtain from a message item the submitter identification submitted + with the originating call of libdax_msgs_submit(). + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 on success, 0 on invalid item, <0 for servere errors +*/ +int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, + double *timestamp, pid_t *process_id, int *driveno, + int flag); + + +/** Obtain from a message item severity and priority as submitted + with the originating call of libdax_msgs_submit(). + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 on success, 0 on invalid item, <0 for servere errors +*/ +int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, + int *severity, int *priority, int flag); + + +#ifdef LIDBAX_MSGS_________________ + + + /* Registered Error Codes */ + + +Format: error_code (LIBDAX_MSGS_SEV_*,LIBDAX_MSGS_PRIO_*) = explanation +If no severity or priority are fixely associates, use "(,)". + +------------------------------------------------------------------------------ +Range "libdax_msgs" : 0x00000000 to 0x0000ffff + + 0x0000 (ALL,ZERO) = Initial setting in new libdax_msgs_item + 0x0001 (DEBUG,ZERO) = Test error message + + +------------------------------------------------------------------------------ +Range "elmom" : 0x00010000 to 0x0001ffff + + + +------------------------------------------------------------------------------ +Range "scdbackup" : 0x00020000 to 0x0002ffff + + + +------------------------------------------------------------------------------ + +#endif /* LIDBAX_MSGS_________________ */ + + + +#ifdef LIBDAX_MSGS_H_INTERNAL + + /* Internal Functions */ + + +/** Lock before doing side effect operations on m */ +static int libdax_msgs_lock(struct libdax_msgs *m, int flag); + +/** Unlock after effect operations on m are done */ +static int libdax_msgs_unlock(struct libdax_msgs *m, int flag); + + +/** Create new empty message item. + @param link Previous item in queue + @param flag Bitfield for control purposes (unused yet, submit 0) + @return >0 success, <=0 failure +*/ +static int libdax_msgs_item_new(struct libdax_msgs_item **item, + struct libdax_msgs_item *link, int flag); + +/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted + pointer gets set to NULL. + @param flag Bitfield for control purposes (unused yet, submit 0) + @return 1 for success, 0 for pointer to NULL +*/ +static int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag); + + +#endif /* LIBDAX_MSGS_H_INTERNAL */ + + +#endif /* ! LIBDAX_MSGS_H_INCLUDED */