New API calls Xorriso_sieve_add_filter, Xorriso_sieve_get_result, Xorriso_sieve_clear_results, Xorriso_sieve_dispose, Xorriso_sieve_big

This commit is contained in:
2012-12-06 13:22:13 +00:00
parent 5f3dcc3904
commit 0bd83b3a73
9 changed files with 933 additions and 9 deletions

View File

@ -633,6 +633,7 @@ bit15= with bit1 to bit3: close depicted log file
FILE *logfile_fp, *pktlog_fp;
static int num_channels= 4;
static char channel_prefixes[4][4]= {".","R","I","M"};
int Xorriso_sieve_filter_msg(struct XorrisO *xorriso, char *msg, int flag);
#ifdef Xorriso_fetch_with_msg_queueS
static int complaints= 0, complaint_limit= 5;
@ -705,7 +706,7 @@ bit15= with bit1 to bit3: close depicted log file
if(xorriso->stderr_fp == NULL)
{ret= 0; goto ex;}
}
if(flag & (2| 4 | 8))
if(flag & (2 | 4 | 8))
{ret= 1; goto ex;}
/* Eventually perform backslash encoding of non-printable characters */
@ -716,7 +717,11 @@ bit15= with bit1 to bit3: close depicted log file
{ret= -1; goto ex;}
}
/* Eventually perform messag redirection */
/* Pick interesting words for the Xorriso_sieve API */
Xorriso_sieve_filter_msg(xorriso, text,
(channel_no > 0 ? channel_no - 1 : 0));
/* Eventually perform message redirection */
if(xorriso->msglist_stackfill > 0) {
if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1)
result_redirected= 1;
@ -1374,6 +1379,572 @@ ex:;
}
/* -------------------------- Xorriso_msg_sievE -------------------------- */
struct Xorriso_msg_filteR {
char *name;
char *prefix;
char *separators;
int channels; /* What to watch: bit0=result , bit1=info , bit2=mark */
int num_words;
int *word_idx;
int last_word_line_end;
/* Oldest result gets discarded when new surpassed threshold */
int max_results;
struct Xorriso_lsT *results; /* Serialized tuples of num_words */
int num_results;
int num_delivered;
struct Xorriso_lsT *next_to_deliver;
struct Xorriso_msg_filteR *prev;
struct Xorriso_msg_filteR *next;
};
int Xorriso_msg_filter_destroy(struct Xorriso_msg_filteR **o, int flag);
int Xorriso_msg_filter_new(struct Xorriso_msg_filteR **o, char *name,
struct Xorriso_msg_filteR *prev,
struct Xorriso_msg_filteR *next,
int flag)
{
struct Xorriso_msg_filteR *m;
m= (*o)= TSOB_FELD(struct Xorriso_msg_filteR, 1);
if((*o) == NULL)
return(-1);
m->name= NULL;
m->prefix= NULL;
m->separators= NULL;
m->channels= 7;
m->num_words= 0;
m->word_idx= NULL;
m->last_word_line_end= flag & 1;
m->max_results= 1;
m->results= NULL;
m->num_results= 0;
m->num_delivered= 0;
m->next_to_deliver= NULL;
m->name= strdup(name);
if(m->name == NULL)
goto failure;
m->prev= prev;
if(prev != NULL)
prev->next= m;
m->next= next;
if(next != NULL)
next->prev= m;
return(1);
failure:
Xorriso_msg_filter_destroy(o, 0);
return(-1);
}
int Xorriso_msg_filter_destroy(struct Xorriso_msg_filteR **o, int flag)
{
struct Xorriso_msg_filteR *m;
if((*o)==NULL)
return(0);
m= *o;
if(m->name != NULL)
free(m->name);
if(m->prefix != NULL)
free(m->prefix);
if(m->separators != NULL)
free(m->separators);
if(m->word_idx != NULL)
free((char *) m->word_idx);
if(m->results != NULL)
Xorriso_lst_destroy_all(&(m->results), 0);
if(m->prev != NULL)
m->prev->next= m->next;
if(m->next != NULL)
m->next->prev= m->prev;
free(*o);
*o= NULL;
return(1);
}
int Xorriso_msg_filter_set_words(struct Xorriso_msg_filteR *m,
int num_words, int *word_idx, int flag)
{
int i;
if(m->word_idx != NULL)
free(m->word_idx);
m->num_words= 0;
if(num_words <= 0)
return(1);
m->word_idx= TSOB_FELD(int, num_words);
if(m->word_idx == NULL)
return(-1);
for(i= 0; i < num_words; i++)
m->word_idx[i]= word_idx[i];
m->num_words= num_words;
return(1);
}
struct Xorriso_msg_sievE {
int num_filters;
struct Xorriso_msg_filteR *first_filter;
};
int Xorriso_msg_sieve_new(struct Xorriso_msg_sievE **o, int flag)
{
struct Xorriso_msg_sievE *m;
m= (*o)= TSOB_FELD(struct Xorriso_msg_sievE, 1);
if((*o) == NULL)
return(-1);
m->num_filters= 0;
m->first_filter= NULL;
return(1);
}
int Xorriso_msg_sieve_destroy(struct Xorriso_msg_sievE **o, int flag)
{
struct Xorriso_msg_sievE *m;
struct Xorriso_msg_filteR *f, *next_f= NULL;
if((*o) == NULL)
return(0);
m= *o;
for(f= m->first_filter; f != NULL; f= next_f) {
next_f= f->next;
Xorriso_msg_filter_destroy(&f, 0);
}
free(*o);
*o= NULL;
return(1);
}
/* API */
int Xorriso_sieve_add_filter(struct XorrisO *xorriso, char *name,
int channels, char *prefix, char *separators,
int num_words, int *word_idx, int max_results,
int flag)
{
int ret;
struct Xorriso_msg_sievE *sieve= NULL;
struct Xorriso_msg_filteR *filter;
if(xorriso->msg_sieve == NULL) {
ret= Xorriso_msg_sieve_new(&sieve, 0);
if(ret <= 0)
goto no_mem;
xorriso->msg_sieve= sieve;
} else
sieve= xorriso->msg_sieve;
ret= Xorriso_msg_filter_new(&filter, name, NULL, sieve->first_filter,
flag & 1);
if(ret <= 0)
goto no_mem;
sieve->first_filter= filter;
ret= Xorriso_msg_filter_set_words(filter, num_words, word_idx, 0);
if(ret <= 0)
goto no_mem;
if(prefix != NULL)
filter->prefix= strdup(prefix);
if(separators != NULL)
filter->separators= strdup(separators);
filter->channels= channels;
filter->max_results= max_results;
(sieve->num_filters)++;
return(1);
no_mem:;
Xorriso_msg_sieve_destroy(&sieve, 0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
/* API */
int Xorriso_sieve_dispose(struct XorrisO *xorriso, int flag)
{
Xorriso_msg_sieve_destroy(&(xorriso->msg_sieve), 0);
return(1);
}
/* API */
int Xorriso_sieve_clear_results(struct XorrisO *xorriso, int flag)
{
struct Xorriso_msg_filteR *f;
for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
f->num_results= 0;
f->num_delivered= 0;
if(f->results != NULL)
Xorriso_lst_destroy_all(&(f->results), 0);
f->next_to_deliver= NULL;
}
return(1);
}
/* API */
/* @param flag bit0= Reset reading to first matching result
bit1= Only inquire number of available results.
Do not allocate memory.
bit2= If *argv is not NULL, then free it before attaching
new memory.
*/
int Xorriso_sieve_get_result(struct XorrisO *xorriso, char *name,
int *argc, char ***argv, int *available, int flag)
{
struct Xorriso_msg_filteR *f;
struct Xorriso_lsT *lst;
int i;
if(flag & 4)
Xorriso__dispose_words(argc, argv);
*argc= 0;
*argv= NULL;
if(xorriso->msg_sieve == NULL)
return(0);
for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
if(strcmp(f->name, name) != 0)
continue;
*available= f->num_results - f->num_delivered;
if(*available <= 0)
break;
if(flag & 2)
return(1);
if(flag & 1) {
f->num_delivered= 0;
f->next_to_deliver= NULL;
}
if(f->next_to_deliver == NULL) {
f->next_to_deliver= f->results;
for(i= 0; i < f->num_words * f->num_delivered; i++)
if(f->next_to_deliver != NULL)
f->next_to_deliver= Xorriso_lst_get_next(f->next_to_deliver, 0);
}
if(f->next_to_deliver == NULL) {
/* Should not happen */
*available= 0;
break;
}
if(f->num_words <= 0)
return(1);
*argv= calloc(f->num_words, sizeof(char *));
if(*argv == NULL)
goto no_mem;
*argc= f->num_words;
for(i= 0; i < *argc; i++)
(*argv)[i]= NULL;
lst= f->next_to_deliver;
for(i= 0; i < *argc; i++) {
if(lst != NULL) {
(*argv)[i]= strdup(Xorriso_lst_get_text(lst, 0));
if((*argv)[i] == NULL)
goto no_mem;
} else {
/* >>> ??? should not happen */;
}
lst= Xorriso_lst_get_next(lst, 0);
}
f->next_to_deliver= lst;
(f->num_delivered)++;
(*available)--;
return(1);
}
return(0);
no_mem:
if(*argv != NULL)
Xorriso__dispose_words(argc, argv);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
int Xorriso_sieve_big(struct XorrisO *xorriso, int flag)
{
struct Xorriso_sieve_big_filteR {
char *name;
int channels;
char *prefix;
char *separators;
int num_words;
int word_idx[6];
int max_results;
int flag;
};
static struct Xorriso_sieve_big_filteR filters[] = {
{"Drive current:", 3, "Drive current:", "", 2, { 0, 1, -1, -1, -1, -1},
2, 0},
{"Drive type :", 3, "Drive type :", "", 3, { 1, 3, 5, -1, -1, -1},
2, 0},
{"Media current:", 3, "Media current: ", "", 1, { 0, -1, -1, -1, -1, -1},
2, 1},
{"Media status :", 3, "Media status : ", "", 1, { 0, -1, -1, -1, -1, -1},
2, 1},
{"Media blocks :", 3, "Media blocks :", "", 3, { 0, 3, 6, -1, -1, -1},
2, 0},
{"Media summary:", 3, "Media summary:", "", 4, { 0, 2, 5, 7, -1, -1},
2, 0},
{"Media nwa :", 3, "Media nwa :", "", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Volume id :", 3, "Volume id :", "", 1, { 0, -1, -1, -1, -1, -1},
2, 0},
{"ISO session :", 3, "ISO session :", "", 4, { 0, 2, 4, 6, -1, -1},
10000, 1},
{"Image size :", 3, "Image size :", "", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Media space :", 3, "Image size :", "", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"After commit :", 3, "Image size :", "", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"PVD address :", 3, "PVD address :", "", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Volume Id :", 3, "Volume Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Volume Set Id:", 3, "Volume Set Id: ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Publisher Id :", 3, "Publisher Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Preparer Id :", 3, "Preparer Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"App Id :", 3, "App Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"System Id :", 3, "System Id : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"CopyrightFile:", 3, "CopyrightFile: ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Abstract File:", 3, "Abstract File: ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Biblio File :", 3, "Biblio File : ", "", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"Write speed :", 3, "Write speed :", "", 2, { 0, 2, -1, -1, -1, -1},
100, 0},
{"Write speed H:", 3, "Write speed H:", "", 2, { 0, 2, -1, -1, -1, -1},
1, 0},
{"Write speed L:", 3, "Write speed L:", "", 2, { 0, 2, -1, -1, -1, -1},
1, 0},
{"Write speed h:", 3, "Write speed h:", "", 2, { 0, 2, -1, -1, -1, -1},
1, 0},
{"Write speed l:", 3, "Write speed l:", "", 2, { 0, 2, -1, -1, -1, -1},
1, 0},
{"Format status:", 3, "Format status:", ", ", 2, { 0, 1, -1, -1, -1, -1},
1, 1},
{"Format idx :", 3, "Format idx ", ",: ", 4, { 0, 1, 2, 3, -1, -1},
100, 1},
{"Profile :", 3, "Profile :", "", 2, { 0, 1, -1, -1, -1, -1},
256, 1},
{"-changes_pending", 3, "-changes_pending ", "", 1,
{ 0, -1, -1, -1, -1, -1}, 1, 0},
{"Media region :", 3, "Media region :", "", 3, { 0, 2, 4, -1, -1, -1},
10000, 1},
{"MD5 tag range:", 3, "MD5 tag range:", "", 3, { 0, 2, 4, -1, -1, -1},
10000, 1},
{"Local ACL :", 3, "Local ACL :", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Local xattr :", 3, "Local xattr :", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Jigdo files :", 3, "Jigdo files :", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"zisofs :", 3, "zisofs :", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Ext. filters :", 3, "Ext. filters : ", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 1},
{"DVD obs 64 kB:", 3, "DVD obs 64 kB:", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"Readline :", 3, "Readline :", ", ", 1, { 0, -1, -1, -1, -1, -1},
1, 0},
{"xorriso version :", 3, "xorriso version :", ", ", 1,
{ 0, -1, -1, -1, -1, -1}, 1, 0},
{"Version timestamp :", 3, "Version timestamp :", ", ", 1,
{ 0, -1, -1, -1, -1, -1}, 1, 0},
{"Build timestamp :", 3, "Build timestamp : ", ", ", 1,
{ 0, -1, -1, -1, -1, -1}, 1, 1},
{"libisofs in use :", 3, "libisofs in use :", ", ", 2,
{ 0, 1, -1, -1, -1, -1}, 1, 1},
{"libjte in use :", 3, "libjte in use :", ", ", 2,
{ 0, 1, -1, -1, -1, -1}, 1, 1},
{"libburn in use :", 3, "libburn in use :", ", ", 2,
{ 0, 1, -1, -1, -1, -1}, 1, 1},
{"libburn OS adapter:", 3, "libburn OS adapter: ", ", ", 1,
{ 0, -1, -1, -1, -1, -1}, 1, 1},
{"libisoburn in use :", 3, "libisoburn in use :", ", ", 2,
{ 0, 1, -1, -1, -1, -1}, 1, 1},
{"@", 0, "@", "", 0, {-1, -1, -1, -1, -1, -1}, 0, 0}
};
/* Problem cases:
<<<
-devices -device_links
have no well recognizable prefix
-pwd -pwdx
have a headline and a value line
-ls* , -getfacl* , -getfattr* , -du* , -compare* , -show_stream*
have no well recognizable prefix
Todo:
-find -exec
report_damage report_lba getfacl getfattr get_any_xattr list_extattr
get_md5 check_md5 get_hfs_crtp get_hfs_bless show_stream estimate_size
*/
struct Xorriso_sieve_big_filteR *f;
int ret, i, num_filters= 1000;
for(i= 0; i < num_filters; i++) {
f= &(filters[i]);
if(strcmp(f->name, "@") == 0)
break;
ret= Xorriso_sieve_add_filter(xorriso, f->name, f->channels, f->prefix,
f->separators, f->num_words, f->word_idx,
f->max_results, f->flag);
if(ret <= 0)
goto failure;
}
return(1);
failure:
Xorriso_sieve_dispose(xorriso, 0);
return(-1);
}
/* Check for matching filter and eventually extract words.
To be called by Xorriso_result, Xorriso_info, Xorriso_mark,
and alike.
Thus no own message output is allowed here !
@param flag bit0-1= channel:
0= result channel
1= info channel
2= mark channel
*/
int Xorriso_sieve_filter_msg(struct XorrisO *xorriso, char *msg, int flag)
{
int channel, ret, argc= 0, i, max_words, l, widx;
char **argv= NULL;
struct Xorriso_msg_filteR *f;
struct Xorriso_lsT *lst, *prev_lst, *next_lst;
if(xorriso->msg_sieve == NULL)
return(1);
channel= flag & 3;
for(f= xorriso->msg_sieve->first_filter; f != NULL; f= f->next) {
if(!(f->channels & (1 << channel)))
continue;
if(f->prefix[0])
if(strncmp(f->prefix, msg, strlen(f->prefix)) != 0)
continue;
max_words= 0;
if(f->last_word_line_end)
if(f->num_words > 0) /* Let last word take rest of line */
max_words= f->word_idx[f->num_words - 1];
if(max_words <= 0 && f->last_word_line_end) {
/* Copy rest of line as single word because Xorriso_parse_line understands
max_words == 0 as unlimited number of words. But here it is desired
to get the rest of line already in argv[0].
*/
max_words= 0;
argv= calloc(1, sizeof(char *));
if(argv == NULL)
goto no_mem;
argc= 1;
argv[0]= strdup(msg + strlen(f->prefix));
if(argv[0] == NULL)
goto no_mem;
ret= 1;
} else {
ret= Xorriso_parse_line(xorriso, msg, f->prefix, f->separators, max_words,
&argc, &argv, 0);
}
if(ret < 0)
goto ex;
if(ret == 0)
continue;
if(f->last_word_line_end) {
l= strlen(argv[max_words]);
if(l > 0)
if(argv[max_words][l - 1] == '\n')
argv[max_words][l - 1]= 0;
}
if(f->max_results > 0 && f->num_results >= f->max_results) {
/* Dispose surplus results */
for(i= 0; i < f->num_words; i++) {
if(f->results != NULL) {
next_lst= f->results->next;
Xorriso_lst_destroy(&(f->results), 0);
f->results= next_lst;
}
}
if(f->num_delivered > 0)
(f->num_delivered)--;
if(f->num_delivered == 0)
f->next_to_deliver= NULL;
f->num_results--;
}
if(f->results == NULL) {
prev_lst= NULL;
} else {
for(prev_lst= f->results; prev_lst->next != NULL;
prev_lst= prev_lst->next);
}
for(i= 0; i < f->num_words; i++) {
widx= f->word_idx[i];
if(widx >= argc || widx < 0)
ret= Xorriso_lst_new(&lst, "", prev_lst, 0);
else if(argv[widx] == NULL)
ret= Xorriso_lst_new(&lst, "", prev_lst, 0);
else
ret= Xorriso_lst_new(&lst, argv[widx], prev_lst, 0);
if(ret <= 0)
goto no_mem;
if(prev_lst == NULL)
f->results= lst;
prev_lst= lst;
}
(f->num_results)++;
Xorriso__dispose_words(&argc, &argv);
}
ret= 1;
ex:
Xorriso__dispose_words(&argc, &argv);
return(ret);
no_mem:;
Xorriso_no_malloc_memory(xorriso, NULL, 1); /* reports to stderr */
ret= -1;
goto ex;
}
/* ^^^^^^^^^^^^^^^^^^^^^^^^^^ Xorriso_msg_sievE ^^^^^^^^^^^^^^^^^^^^^^^^^^ */
int Xorriso_result(struct XorrisO *xorriso, int flag)
/*
bit0= no considerations or computations or dialog. Just put out.
@ -2839,6 +3410,8 @@ int Xorriso_reset_counters(struct XorrisO *xorriso, int flag)
}
/* @param flag bit0= to stderr rather than Xorriso_msgs_submit
*/
int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag)
{
if(to_free!=NULL)
@ -2848,7 +3421,12 @@ int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag)
*to_free= NULL;
}
sprintf(xorriso->info_text, "Out of virtual memory");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 0);
if(flag & 1) {
fprintf(stderr, "%s", xorriso->info_text);
/* (No need to first check for problem status worse than ABORT) */
Xorriso_set_problem_status(xorriso, "ABORT", 0);
} else
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 0);
return(1);
}