From 1cd20619e5f5e11a9547f0a9a92853ea73c617fb Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Sat, 27 Dec 2014 16:25:35 +0100 Subject: [PATCH] Gracefully handle missing indirect info nodes Fixed Debian bug https://bugs.debian.org/298865 --- src/filehandling_functions.c | 37 +++++++++++++++++++++++++++--------- src/filehandling_functions.h | 2 +- src/pinfo.c | 11 +++++++++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/filehandling_functions.c b/src/filehandling_functions.c index 100c4d0..b146ef0 100644 --- a/src/filehandling_functions.c +++ b/src/filehandling_functions.c @@ -1099,12 +1099,27 @@ create_indirect_tag_table() { id = openinfo(indirect[i].filename, 1); initial = TagTableEntries + 1; - if (id) + if (!id) { - create_tag_table(id); - FirstNodeOffset = tag_table[1].offset; - strcpy(FirstNodeName, tag_table[1].nodename); + /* display error message to make the user aware of + * the broken info page + */ + char msg[81]; + snprintf(msg, 81, "%s '%s' (%s)", + _("Can't open file"), indirect[i].filename, + _("press a key to continue") ); + attrset(bottomline); + mvhline(maxy - 1, 0, ' ', maxx); + mvaddstr(maxy - 1, 0, msg); + move(0, 0); + attrset(normal); + getch(); + + continue; } + create_tag_table(id); + FirstNodeOffset = tag_table[1].offset; + strcpy(FirstNodeName, tag_table[1].nodename); fclose(id); for (j = initial; j <= TagTableEntries; j++) { @@ -1187,10 +1202,11 @@ create_tag_table(FILE * id) } } -void +int seeknode(int tag_table_pos, FILE ** Id) { int i; + FILE * newid; #define id (*Id) /* * Indirect nodes are seeked using a formula: @@ -1204,15 +1220,17 @@ seeknode(int tag_table_pos, FILE ** Id) if (indirect[i].offset <= tag_table[tag_table_pos].offset) { long off = tag_table[tag_table_pos].offset - indirect[i].offset + FirstNodeOffset - 4; - fclose(id); - id = openinfo(indirect[i].filename, 0); - if (id == NULL) + newid = openinfo(indirect[i].filename, 0); + if (newid == NULL) { + return -1; closeprogram(); - printf(_("Error: could not open info file")); + printf(_("Error: could not open info file part")); printf("\n"); exit(1); } + fclose(id); + id = newid; if (off > 0) fseek(id, off, SEEK_SET); else @@ -1230,6 +1248,7 @@ seeknode(int tag_table_pos, FILE ** Id) fseek(id, off, SEEK_SET); } #undef id + return 0; } /* removes trailing .gz, .bz2, etc. */ diff --git a/src/filehandling_functions.h b/src/filehandling_functions.h index 3d16f41..8501482 100644 --- a/src/filehandling_functions.h +++ b/src/filehandling_functions.h @@ -36,7 +36,7 @@ void initpaths (); void addrawpath (char *filename); /* seek to a node in certain info file */ -void seeknode (int tag_table_pos, FILE ** Id); +int seeknode (int tag_table_pos, FILE ** Id); /* * free allocated memory, hold by buf (node** content, stored line by line), diff --git a/src/pinfo.c b/src/pinfo.c index eb23624..efe01b0 100644 --- a/src/pinfo.c +++ b/src/pinfo.c @@ -378,7 +378,14 @@ main(int argc, char *argv[]) do { /* set seek offset for given node */ - seeknode(tag_table_pos, &id); + if (seeknode(tag_table_pos, &id)!=0) + { + tag_table_pos = gettagtablepos(FirstNodeName); + if (seeknode(tag_table_pos, &id)!=0) + { + exit(-1); + } + } /* read the node */ read_item(id, &type, &message, &lines); @@ -415,7 +422,7 @@ main(int argc, char *argv[]) * the broken info page */ char msg[81]; - snprintf(msg, 81, "%s (%s)", + snprintf(msg, 81, "%s (%s)", _("Tag table is corrupt, trying to fix..."), _("press a key to continue") ); attrset(bottomline); -- 2.33.0