diff --git a/Makefile.am b/Makefile.am index db730d2..827c35f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,6 +19,10 @@ src_libisofs_la_SOURCES = \ src/fsource.h \ src/fsource.c \ src/fs_local.c \ + src/messages.h \ + src/messages.c \ + src/libiso_msgs.h \ + src/libiso_msgs.c \ src/stream.h libinclude_HEADERS = \ src/libisofs.h diff --git a/src/image.c b/src/image.c index 83d5462..7420492 100644 --- a/src/image.c +++ b/src/image.c @@ -10,6 +10,7 @@ #include "image.h" #include "error.h" #include "node.h" +#include "messages.h" #include #include @@ -40,9 +41,19 @@ int iso_image_new(const char *name, IsoImage **image) return ISO_MEM_ERROR; } + /* create message messenger */ + res = libiso_msgs_new(&img->messenger, 0); + if (res <= 0) { + free(img); + return ISO_MEM_ERROR; + } + libiso_msgs_set_severities(img->messenger, LIBISO_MSGS_SEV_NEVER, + LIBISO_MSGS_SEV_FATAL, name, 0); + /* fill image fields */ res = iso_node_new_root(&img->root); if (res < 0) { + libiso_msgs_destroy(&img->messenger, 0); free(img); return res; } @@ -73,6 +84,7 @@ void iso_image_unref(IsoImage *image) if (--image->refcount == 0) { /* we need to free the image */ iso_node_unref((IsoNode*)image->root); + libiso_msgs_destroy(&image->messenger, 0); free(image->volset_id); free(image->volume_id); free(image->publisher_id); diff --git a/src/image.h b/src/image.h index e313ebe..0c3ad55 100644 --- a/src/image.h +++ b/src/image.h @@ -36,6 +36,9 @@ struct Iso_Image { char *copyright_file_id; char *abstract_file_id; char *biblio_file_id; + + /* message messenger for the image */ + struct libiso_msgs *messenger; }; diff --git a/src/libiso_msgs.c b/src/libiso_msgs.c new file mode 100644 index 0000000..fbf0832 --- /dev/null +++ b/src/libiso_msgs.c @@ -0,0 +1,404 @@ + +/* libiso_msgs + Message handling facility of libiso. + 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 LIBISO_MSGS_H_INTERNAL 1 + +/* All participants in the messaging system must do this */ +#include "libiso_msgs.h" + + +/* ----------------------------- libiso_msgs_item ------------------------- */ + + +static int libiso_msgs_item_new(struct libiso_msgs_item **item, + struct libiso_msgs_item *link, int flag) +{ + int ret; + struct libiso_msgs_item *o; + struct timeval tv; + struct timezone tz; + + (*item)= o= + (struct libiso_msgs_item *) malloc(sizeof(struct libiso_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= LIBISO_MSGS_SEV_ALL; + o->priority= LIBISO_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); +} + + +/** Detaches item from its queue and eventually readjusts start, end pointers + of the queue */ +int libiso_msgs_item_unlink(struct libiso_msgs_item *o, + struct libiso_msgs_item **chain_start, + struct libiso_msgs_item **chain_end, int flag) +{ + if(o->prev!=NULL) + o->prev->next= o->next; + if(o->next!=NULL) + o->next->prev= o->prev; + if(chain_start!=NULL) + if(*chain_start == o) + *chain_start= o->next; + if(chain_end!=NULL) + if(*chain_end == o) + *chain_end= o->prev; + o->next= o->prev= NULL; + return(1); +} + + +int libiso_msgs_item_destroy(struct libiso_msgs_item **item, + int flag) +{ + struct libiso_msgs_item *o; + + o= *item; + if(o==NULL) + return(0); + libiso_msgs_item_unlink(o,NULL,NULL,0); + if(o->msg_text!=NULL) + free((char *) o->msg_text); + free((char *) o); + *item= NULL; + return(1); +} + + +int libiso_msgs_item_get_msg(struct libiso_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 libiso_msgs_item_get_origin(struct libiso_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 libiso_msgs_item_get_rank(struct libiso_msgs_item *item, + int *severity, int *priority, int flag) +{ + *severity= item->severity; + *priority= item->priority; + return(1); +} + + +/* ------------------------------- libiso_msgs ---------------------------- */ + + +int libiso_msgs_new(struct libiso_msgs **m, int flag) +{ + struct libiso_msgs *o; + + (*m)= o= (struct libiso_msgs *) malloc(sizeof(struct libiso_msgs)); + if(o==NULL) + return(-1); + o->oldest= NULL; + o->youngest= NULL; + o->count= 0; + o->queue_severity= LIBISO_MSGS_SEV_ALL; + o->print_severity= LIBISO_MSGS_SEV_NEVER; + strcpy(o->print_id,"libiso: "); + +#ifndef LIBISO_MSGS_SINGLE_THREADED + pthread_mutex_init(&(o->lock_mutex),NULL); +#endif + + return(1); +} + + +int libiso_msgs_destroy(struct libiso_msgs **m, int flag) +{ + struct libiso_msgs *o; + struct libiso_msgs_item *item, *next_item; + + o= *m; + if(o==NULL) + return(0); + +#ifndef LIBISO_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; + libiso_msgs_item_destroy(&item,0); + } + free((char *) o); + *m= NULL; + return(1); +} + + +int libiso_msgs_set_severities(struct libiso_msgs *m, int queue_severity, + int print_severity, const 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 libiso_msgs_lock(struct libiso_msgs *m, int flag) +{ + +#ifndef LIBISO_MSGS_SINGLE_THREADED + int ret; + + ret= pthread_mutex_lock(&(m->lock_mutex)); + if(ret!=0) + return(0); +#endif + + return(1); +} + + +static int libiso_msgs_unlock(struct libiso_msgs *m, int flag) +{ + +#ifndef LIBISO_MSGS_SINGLE_THREADED + int ret; + + ret= pthread_mutex_unlock(&(m->lock_mutex)); + if(ret!=0) + return(0); +#endif + + return(1); +} + + +int libiso_msgs__text_to_sev(char *severity_name, int *severity, + int flag) +{ + if(strncmp(severity_name,"NEVER",5)==0) + *severity= LIBISO_MSGS_SEV_NEVER; + else if(strncmp(severity_name,"ABORT",5)==0) + *severity= LIBISO_MSGS_SEV_ABORT; + else if(strncmp(severity_name,"FATAL",5)==0) + *severity= LIBISO_MSGS_SEV_FATAL; + else if(strncmp(severity_name,"SORRY",5)==0) + *severity= LIBISO_MSGS_SEV_SORRY; + else if(strncmp(severity_name,"WARNING",7)==0) + *severity= LIBISO_MSGS_SEV_WARNING; + else if(strncmp(severity_name,"HINT",4)==0) + *severity= LIBISO_MSGS_SEV_HINT; + else if(strncmp(severity_name,"NOTE",4)==0) + *severity= LIBISO_MSGS_SEV_NOTE; + else if(strncmp(severity_name,"UPDATE",6)==0) + *severity= LIBISO_MSGS_SEV_UPDATE; + else if(strncmp(severity_name,"DEBUG",5)==0) + *severity= LIBISO_MSGS_SEV_DEBUG; + else if(strncmp(severity_name,"ALL",3)==0) + *severity= LIBISO_MSGS_SEV_ALL; + else { + *severity= LIBISO_MSGS_SEV_NEVER; + return(0); + } + return(1); +} + + +int libiso_msgs__sev_to_text(int severity, char **severity_name, + int flag) +{ + if(flag&1) { + *severity_name= + "NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL"; + return(1); + } + *severity_name= ""; + if(severity>=LIBISO_MSGS_SEV_NEVER) + *severity_name= "NEVER"; + else if(severity>=LIBISO_MSGS_SEV_ABORT) + *severity_name= "ABORT"; + else if(severity>=LIBISO_MSGS_SEV_FATAL) + *severity_name= "FATAL"; + else if(severity>=LIBISO_MSGS_SEV_SORRY) + *severity_name= "SORRY"; + else if(severity>=LIBISO_MSGS_SEV_WARNING) + *severity_name= "WARNING"; + else if(severity>=LIBISO_MSGS_SEV_HINT) + *severity_name= "HINT"; + else if(severity>=LIBISO_MSGS_SEV_NOTE) + *severity_name= "NOTE"; + else if(severity>=LIBISO_MSGS_SEV_UPDATE) + *severity_name= "UPDATE"; + else if(severity>=LIBISO_MSGS_SEV_DEBUG) + *severity_name= "DEBUG"; + else if(severity>=LIBISO_MSGS_SEV_ALL) + *severity_name= "ALL"; + else { + *severity_name= ""; + return(0); + } + return(1); +} + + +int libiso_msgs_submit(struct libiso_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 libiso_msgs_item *item= NULL; + + if(severity >= m->print_severity) { + if(msg_text==NULL) + textpt= ""; + else + textpt= msg_text; + sev_text[0]= 0; + ret= libiso_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) { + ret= libiso_msgs_lock(m,0); + if(ret<=0) + return(-1); + fprintf(stderr,"%s( Most recent system error: %d '%s' )\n", + m->print_id,os_errno,strerror(os_errno)); + libiso_msgs_unlock(m,0); + } + + } + if(severity < m->queue_severity) + return(0); + + ret= libiso_msgs_lock(m,0); + if(ret<=0) + return(-1); + ret= libiso_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; + if(m->oldest==NULL) + m->oldest= item; + m->youngest= item; + m->count++; + libiso_msgs_unlock(m,0); + +/* +fprintf(stderr,"libiso_experimental: message submitted to queue (now %d)\n", + m->count); +*/ + + return(1); +failed:; + libiso_msgs_item_destroy(&item,0); + libiso_msgs_unlock(m,0); + return(-1); +} + + +int libiso_msgs_obtain(struct libiso_msgs *m, struct libiso_msgs_item **item, + int severity, int priority, int flag) +{ + int ret; + struct libiso_msgs_item *im, *next_im= NULL; + + *item= NULL; + ret= libiso_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; + libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); + libiso_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;} + libiso_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); + *item= im; + ret= 1; +ex:; + libiso_msgs_unlock(m,0); + return(ret); +} + + +int libiso_msgs_destroy_item(struct libiso_msgs *m, + struct libiso_msgs_item **item, int flag) +{ + int ret; + + ret= libiso_msgs_lock(m,0); + if(ret<=0) + return(-1); + ret= libiso_msgs_item_destroy(item,0); + libiso_msgs_unlock(m,0); + return(ret); +} + diff --git a/src/libiso_msgs.h b/src/libiso_msgs.h new file mode 100644 index 0000000..d681410 --- /dev/null +++ b/src/libiso_msgs.h @@ -0,0 +1,454 @@ + +/* libiso_msgs + Message handling facility of libisofs. + Copyright (C) 2006-2007 Thomas Schmitt , + provided under GPL +*/ + + +/* + *Never* set this macro outside libiso_msgs.c ! + The entrails of the message handling facility are not to be seen by + the other library components or the applications. +*/ +#ifdef LIBISO_MSGS_H_INTERNAL + + +#ifndef LIBISO_MSGS_SINGLE_THREADED +#include +#endif + + +struct libiso_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 libiso_msgs_item *prev,*next; + +}; + + +struct libiso_msgs { + + struct libiso_msgs_item *oldest; + struct libiso_msgs_item *youngest; + int count; + + int queue_severity; + int print_severity; + char print_id[81]; + +#ifndef LIBISO_MSGS_SINGLE_THREADED + pthread_mutex_t lock_mutex; +#endif + + +}; + +#endif /* LIBISO_MSGS_H_INTERNAL */ + + +#ifndef LIBISO_MSGS_H_INCLUDED +#define LIBISO_MSGS_H_INCLUDED 1 + + +#ifndef LIBISO_MSGS_H_INTERNAL + + + /* Public Opaque Handles */ + +/** A pointer to this is a opaque handle to a message handling facility */ +struct libiso_msgs; + +/** A pointer to this is a opaque handle to a single message item */ +struct libiso_msgs_item; + +#endif /* ! LIBISO_MSGS_H_INTERNAL */ + + + /* Public Macros */ + + +/* Registered Severities */ + +/* It is well advisable to let applications select severities via strings and + forwarded functions libiso_msgs__text_to_sev(), libiso_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 LIBISO_MSGS_SEV_ALL 0x00000000 + +/** Debugging messages not to be visible to normal users by default +*/ +#define LIBISO_MSGS_SEV_DEBUG 0x10000000 + +/** Update of a progress report about long running actions +*/ +#define LIBISO_MSGS_SEV_UPDATE 0x20000000 + +/** Not so usual events which were gracefully handled +*/ +#define LIBISO_MSGS_SEV_NOTE 0x30000000 + +/** Possibilities to achieve a better result +*/ +#define LIBISO_MSGS_SEV_HINT 0x40000000 + +/** Warnings about problems which could not be handled optimally +*/ +#define LIBISO_MSGS_SEV_WARNING 0x50000000 + +/** Non-fatal error messages indicating that parts of the action failed + but processing will/should go on +*/ +#define LIBISO_MSGS_SEV_SORRY 0x60000000 + +/** An error message which puts the whole operation of libdax in question +*/ +#define LIBISO_MSGS_SEV_FATAL 0x70000000 + +/** A message from an abort handler which will finally finish libburn +*/ +#define LIBISO_MSGS_SEV_ABORT 0x71000000 + +/** A severity to exclude resp. discard any possible message. + Do not use this severity for submitting. +*/ +#define LIBISO_MSGS_SEV_NEVER 0x7fffffff + + +/* Registered Priorities */ + +/* Priorities are to be used by libburn/libdax only. */ + +#define LIBISO_MSGS_PRIO_ZERO 0x00000000 +#define LIBISO_MSGS_PRIO_LOW 0x10000000 +#define LIBISO_MSGS_PRIO_MEDIUM 0x20000000 +#define LIBISO_MSGS_PRIO_HIGH 0x30000000 +#define LIBISO_MSGS_PRIO_TOP 0x7ffffffe + +/* Do not use this priority for submitting */ +#define LIBISO_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 libiso_msgs_new(struct libiso_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 libiso_msgs_destroy(struct libiso_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 LIBISO_MSGS_SEV_* of the event. + @param priority The LIBISO_MSGS_PRIO_* 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 libiso_msgs_submit(struct libiso_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 libiso_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 libiso_msgs__text_to_sev(char *severity_name, int *severity, + int flag); + + +/** Set minimum severity for messages to be queued (default + LIBISO_MSGS_SEV_ALL) and for messages to be printed directly to stderr + (default LIBISO_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 libiso_msgs_set_severities(struct libiso_msgs *m, int queue_severity, + int print_severity, const 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 libiso_msgs_obtain(struct libiso_msgs *m, struct libiso_msgs_item **item, + int severity, int priority, int flag); + + +/** Destroy a message item obtained by libiso_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 libiso_msgs_destroy_item(struct libiso_msgs *m, + struct libiso_msgs_item **item, int flag); + + +/** Obtain from a message item the three application oriented components as + submitted with the originating call of libiso_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 libiso_msgs_item_get_msg(struct libiso_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 libiso_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 libiso_msgs_item_get_origin(struct libiso_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 libiso_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 libiso_msgs_item_get_rank(struct libiso_msgs_item *item, + int *severity, int *priority, int flag); + + +#ifdef LIDBAX_MSGS_________________ + + + /* Registered Error Codes */ + + +Format: error_code (LIBISO_MSGS_SEV_*,LIBISO_MSGS_PRIO_*) = explanation +If no severity or priority are fixely associates, use "(,)". + +------------------------------------------------------------------------------ +Range "libiso_msgs" : 0x00000000 to 0x0000ffff + + 0x00000000 (ALL,ZERO) = Initial setting in new libiso_msgs_item + 0x00000001 (DEBUG,ZERO) = Test error message + 0x00000002 (DEBUG,ZERO) = Debugging message + + +------------------------------------------------------------------------------ +Range "elmom" : 0x00010000 to 0x0001ffff + + + +------------------------------------------------------------------------------ +Range "scdbackup" : 0x00020000 to 0x0002ffff + + Acessing and defending drives: + + 0x00020001 (SORRY,LOW) = Cannot open busy device + 0x00020002 (SORRY,HIGH) = Encountered error when closing drive + 0x00020003 (SORRY,HIGH) = Could not grab drive + 0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling + 0x00020005 (SORRY,HIGH) = Failed to open device + 0x00020006 (FATAL,HIGH) = Too many scsi siblings + 0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings + 0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock + + General library operations: + + 0x00020101 (WARNING,HIGH) = Cannot find given worker item + 0x00020102 (SORRY,HIGH) = A drive operation is still going on + 0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on + 0x00020104 (SORRY,HIGH) = NULL pointer caught + 0x00020105 (SORRY,HIGH) = Drive is already released + 0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close + 0x00020107 (SORRY,HIGH) = Drive is busy on attempt to shut down library + 0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry + 0x00020108 (FATAL,HIGH) = Could not allocate new drive object + 0x00020109 (FATAL,HIGH) = Library not running + 0x0002010a (FATAL,HIGH) = Unsuitable track mode + 0x0002010b (FATAL,HIGH) = Burn run failed + 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive + 0x0002010d (DEBUG,HIGH) = Could not inquire TOC + 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive + 0x0002010f (DEBUG,HIGH) = SCSI error condition on command + 0x00020110 (FATAL,HIGH) = Persistent drive address too long + 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object + 0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type + 0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet + 0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data + 0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value + 0x00020116 (FATAL,HIGH) = Track mode has unusable value + 0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use + 0x00020118 (DEBUG,HIGH) = Closing track + 0x00020119 (DEBUG,HIGH) = Closing session + 0x0002011a (NOTE,HIGH) = Padding up track to minimum size + 0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive + 0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive + 0x0002011d (FATAL,HIGH) = SCSI error on write + 0x0002011e (SORRY,HIGH) = Unsuitable media detected + 0x0002011f (SORRY,HIGH) = Burning is restricted to a single track + 0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored + 0x00020121 (FATAL,HIGH) = Write preparation setup failed + 0x00020122 (FATAL,HIGH) = SCSI error on format_unit + 0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type + 0x00020124 (SORRY,HIGH) = SCSI error on set_streaming + 0x00020125 (SORRY,HIGH) = Write start address not supported + 0x00020126 (SORRY,HIGH) = Write start address not properly aligned + 0x00020127 (NOTE,HIGH) = Write start address is ... + 0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance + 0x00020129 (SORRY,HIGH) = Will not format media type + 0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities + 0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job + 0x0002012c (SORRY,HIGH) = Too many logical tracks recorded + 0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses + 0x0002012e (NOTE,HIGH) = Activated track default size + 0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session + 0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking + 0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive + 0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn + 0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode + 0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO + 0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO + 0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track + 0x00020137 (HINT,HIGH) = TAO would be possible + 0x00020138 (FATAL,HIGH) = Cannot reserve track + 0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable + 0x0002013a (FATAL,HIGH) = No suitable media detected + 0x0002013b (DEBUG,HIGH) = SCSI command indicates host or driver error + 0x0002013c (SORRY,HIGH) = Malformed capabilities page 2Ah received + 0x0002013d (DEBUG,LOW) = Waiting for free buffer space takes long time + 0x0002013e (SORRY,HIGH) = Timeout with waiting for free buffer. Now disabled + 0x0002013f (DEBUG,LOW) = Reporting total time spent with waiting for buffer + + + libiso_audioxtr: + 0x00020200 (SORRY,HIGH) = Cannot open audio source file + 0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format + 0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data + + +------------------------------------------------------------------------------ +Range "vreixo" : 0x00030000 to 0x0003ffff + + General: + 0x00031001 (SORRY,HIGH) = Cannot read file (ignored) + 0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled) + 0x00031003 (FATAL,HIGH) = File doesnt exist + 0x00031004 (FATAL,HIGH) = Read access denied + + Image reading: + 0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image + 0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored + 0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image + 0x00031003 (SORRY,HIGH) = Cannot read previous image file + + Rock-Ridge: + 0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored + 0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry + 0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found + 0x00030111 (SORRY,HIGH) = Unsupported RR feature + 0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry + + El-Torito: + 0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored + 0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog + 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature + 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image + 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image + 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without + enought info about it + + Joliet: + 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree + + +------------------------------------------------------------------------------ + +#endif /* LIDBAX_MSGS_________________ */ + + + +#ifdef LIBISO_MSGS_H_INTERNAL + + /* Internal Functions */ + + +/** Lock before doing side effect operations on m */ +static int libiso_msgs_lock(struct libiso_msgs *m, int flag); + +/** Unlock after effect operations on m are done */ +static int libiso_msgs_unlock(struct libiso_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 libiso_msgs_item_new(struct libiso_msgs_item **item, + struct libiso_msgs_item *link, int flag); + +/** Destroy a message item obtained by libiso_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 libiso_msgs_item_destroy(struct libiso_msgs_item **item, int flag); + + +#endif /* LIBISO_MSGS_H_INTERNAL */ + + +#endif /* ! LIBISO_MSGS_H_INCLUDED */ diff --git a/src/libisofs.h b/src/libisofs.h index 67408c4..9eb8f8f 100644 --- a/src/libisofs.h +++ b/src/libisofs.h @@ -409,4 +409,53 @@ int iso_dir_iter_take(IsoDirIter *iter); */ int iso_dir_iter_remove(IsoDirIter *iter); +#define ISO_MSGS_MESSAGE_LEN 4096 + +/** + * Control queueing and stderr printing of messages from a given IsoImage. + * Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", + * "NOTE", "UPDATE", "DEBUG", "ALL". + * + * @param image The image + * @param queue_severity Gives the minimum limit for messages to be queued. + * Default: "NEVER". If you queue messages then you + * must consume them by iso_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 iso_image_set_msgs_severities(IsoImage *img, char *queue_severity, + char *print_severity, char *print_id); +/** + * Obtain the oldest pending message from a IsoImage message 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 image The image whose messages we want to obtain + * @param error_code Will become a unique error code as listed in messages.h + * @param msg_text Must provide at least ISO_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 iso_image_obtain_msgs(IsoImage *image, char *minimum_severity, + int *error_code, char msg_text[], int *os_errno, + char severity[]); + +/** + * Return the messenger object handle used by the given image. This handle + * may be used by related libraries to replace their own compatible + * messenger objects and thus to direct their messages to the libisofs + * message queue. See also: libburn, API function burn_set_messenger(). + * + * @return the handle. Do only use with compatible + */ +void *iso_image_get_messenger(IsoImage *image); + #endif /*LIBISO_LIBISOFS_H_*/ diff --git a/src/messages.c b/src/messages.c new file mode 100644 index 0000000..da5eef5 --- /dev/null +++ b/src/messages.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ +#include +#include + +#include "libisofs.h" +#include "messages.h" + +#include "image.h" + +void iso_msg_debug(IsoImage *img, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, 0x00000002, + LIBISO_MSGS_SEV_DEBUG, LIBISO_MSGS_PRIO_ZERO, + msg_text, 0, 0); +} + +void iso_msg_note(IsoImage *img, int error_code, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, error_code, + LIBISO_MSGS_SEV_NOTE, LIBISO_MSGS_PRIO_MEDIUM, + msg_text, 0, 0); +} + +void iso_msg_hint(IsoImage *img, int error_code, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, error_code, + LIBISO_MSGS_SEV_HINT, LIBISO_MSGS_PRIO_MEDIUM, + msg_text, 0, 0); +} + +void iso_msg_warn(IsoImage *img, int error_code, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, error_code, + LIBISO_MSGS_SEV_WARNING, LIBISO_MSGS_PRIO_MEDIUM, + msg_text, 0, 0); +} + +void iso_msg_sorry(IsoImage *img, int error_code, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, error_code, + LIBISO_MSGS_SEV_SORRY, LIBISO_MSGS_PRIO_HIGH, + msg_text, 0, 0); +} + +void iso_msg_fatal(IsoImage *img, int error_code, char *msg_text) +{ + libiso_msgs_submit(img->messenger, -1, error_code, + LIBISO_MSGS_SEV_FATAL, LIBISO_MSGS_PRIO_HIGH, + msg_text, 0, 0); +} + +/** + * Control queueing and stderr printing of messages from libisofs. + * 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 iso_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 iso_image_set_msgs_severities(IsoImage *img, char *queue_severity, + char *print_severity, char *print_id) +{ + int ret, queue_sevno, print_sevno; + + ret = libiso_msgs__text_to_sev(queue_severity, &queue_sevno, 0); + if (ret <= 0) + return 0; + ret = libiso_msgs__text_to_sev(print_severity, &print_sevno, 0); + if (ret <= 0) + return 0; + ret = libiso_msgs_set_severities(img->messenger, queue_sevno, + print_sevno, print_id, 0); + if (ret <= 0) + return 0; + return 1; +} + +#define ISO_MSGS_MESSAGE_LEN 4096 + +/** + * Obtain the oldest pending libisofs 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 listed in messages.h + * @param msg_text Must provide at least ISO_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 iso_image_obtain_msgs(IsoImage *img, 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 libiso_msgs_item *item = NULL; + + if (img == NULL) + return 0; + + ret = libiso_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0); + if (ret <= 0) + return 0; + ret = libiso_msgs_obtain(img->messenger, &item, minimum_sevno, + LIBISO_MSGS_PRIO_ZERO, 0); + if (ret <= 0) + goto ex; + ret = libiso_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0); + if (ret <= 0) + goto ex; + strncpy(msg_text, textpt, ISO_MSGS_MESSAGE_LEN-1); + if(strlen(textpt) >= ISO_MSGS_MESSAGE_LEN) + msg_text[ISO_MSGS_MESSAGE_LEN-1] = 0; + + severity[0]= 0; + ret = libiso_msgs_item_get_rank(item, &sevno, &priority, 0); + if(ret <= 0) + goto ex; + ret = libiso_msgs__sev_to_text(sevno, &sev_name, 0); + if(ret <= 0) + goto ex; + strcpy(severity,sev_name); + + ret = 1; +ex: + libiso_msgs_destroy_item(img->messenger, &item, 0); + return ret; +} + +void *iso_image_get_messenger(IsoImage *img) +{ + return img->messenger; +} + diff --git a/src/messages.h b/src/messages.h new file mode 100644 index 0000000..e93e6f3 --- /dev/null +++ b/src/messages.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2007 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +/* + * Message handling for libisofs + */ + +#ifndef MESSAGES_H_ +#define MESSAGES_H_ + +#include "libiso_msgs.h" + +/** Can't read file (ignored) */ +#define LIBISO_CANT_READ_FILE 0x00031001 +/** Can't read file (operation canceled) */ +#define LIBISO_FILE_READ_ERROR 0x00031002 +/** File doesn't exist */ +#define LIBISO_FILE_DOESNT_EXIST 0x00031003 +/** Read access denied */ +#define LIBISO_FILE_NO_READ_ACCESS 0x00031004 + +/** Unsupported image feature */ +#define LIBISO_IMG_UNSUPPORTED 0x00031000 +/** Unsupported Vol Desc that will be ignored */ +#define LIBISO_UNSUPPORTED_VD 0x00031001 +/** damaged image */ +#define LIBISO_WRONG_IMG 0x00031002 +/** Can't read previous image file */ +#define LIBISO_CANT_READ_IMG 0x00031003 + +/* Unsupported SUSP entry */ +#define LIBISO_SUSP_UNHANLED 0x00030101 +/* Wrong SUSP entry, that cause RR to be ignored */ +#define LIBISO_SUSP_WRONG 0x00030102 +/* Unsupported multiple SUSP ER entries where found */ +#define LIBISO_SUSP_MULTIPLE_ER 0x00030103 +/** Unsupported RR feature. */ +#define LIBISO_RR_UNSUPPORTED 0x00030111 +/** Error in a Rock Ridge entry. */ +#define LIBISO_RR_ERROR 0x00030112 + +/** Unsupported boot vol desc. */ +#define LIBISO_BOOT_VD_UNHANLED 0x00030201 +/** Wrong or damaged el-torito catalog */ +#define LIBISO_EL_TORITO_WRONG 0x00030202 +/** Unsupproted el-torito feature */ +#define LIBISO_EL_TORITO_UNHANLED 0x00030203 +/** Trying to add an invalid file as a El-Torito image */ +#define LIBISO_EL_TORITO_WRONG_IMG 0x00030204 +/** Can't properly patch isolinux image */ +#define LIBISO_ISOLINUX_CANT_PATCH 0x00030205 +/** Copying El-Torito from a previous image without enought info about it */ +#define LIBISO_EL_TORITO_BLIND_COPY 0x00030206 + +/** Unsupported file type for Joliet tree */ +#define LIBISO_JOLIET_WRONG_FILE_TYPE 0x00030301 + +void iso_msg_debug(IsoImage *img, char *msg_text); + +void iso_msg_note(IsoImage *img, int error_code, char *msg_text); + +void iso_msg_hint(IsoImage *img, int error_code, char *msg_text); + +void iso_msg_warn(IsoImage *img, int error_code, char *msg_text); + +void iso_msg_sorry(IsoImage *img, int error_code, char *msg_text); + +void iso_msg_fatal(IsoImage *img, int error_code, char *msg_text); + +#endif /*MESSAGES_H_*/