Hi! I've noticed that the unstr utility from games/fortune does not work properly. When reading the header of .dat files, all the other utilities do some endianness correction, but unstr does not. Therefore, it gets wrong information, and produces garbage.
The diff below fixes this symptom. Using the unpatched unstr on any datfile previously generated by strfile aborts quickly since the flags are not interpreted correctly. By commenting out the flag processing code, unstr works to some degree, but doesn't get the right number of entries and runs in a pseudo-endless loop. The patched version doesn't exhibit those symptoms. Still, I don't understand the reason why strfile does htonl (strfile.c at line 220 onwards) for all the header fields in the first place, only for fortune then to undo it (and for unstr to forget doing it, therefore not working). Also, fortune.c at line 1107 does ntohl to undo the htonl of strfile.c for every header field but for tbl.str_version, which is explicitely commented out. This seems rather odd -- looking at fortune's behaviour in the debugger shows that without ntohl the str_version comes in in reverse byte order, as expected. According to CVS, this oddity comes all the way from the initial import. The second diff fixes that. Last, I'd like to suggest that strfile and unstr be included in the base distribution. It seems strange that their source is there and the fortune(6) manpage loops through hoops to mention that they can be compiled if one wishes so -- but before I try to patch that, I'd like to hear whether there are some non-obvious reasons why they are kept out. Cheers, s//un Index: unstr/unstr.c =================================================================== RCS file: /cvs/src/games/fortune/unstr/unstr.c,v retrieving revision 1.10 diff -u -r1.10 unstr.c --- unstr/unstr.c 27 Oct 2009 23:59:24 -0000 1.10 +++ unstr/unstr.c 21 Oct 2011 17:26:11 -0000 @@ -79,6 +79,12 @@ (void) fread(&tbl.str_shortlen, sizeof(tbl.str_shortlen), 1, Dataf); (void) fread(&tbl.str_flags, sizeof(tbl.str_flags), 1, Dataf); (void) fread( tbl.stuff, sizeof(tbl.stuff), 1, Dataf); + tbl.str_version = ntohl(tbl.str_version); + tbl.str_numstr = ntohl(tbl.str_numstr); + tbl.str_longlen = ntohl(tbl.str_longlen); + tbl.str_shortlen = ntohl(tbl.str_shortlen); + tbl.str_flags = ntohl(tbl.str_flags); + if (!(tbl.str_flags & (STR_ORDERED | STR_RANDOM))) errx(1, "nothing to do -- table in file order"); Delimch = tbl.str_delim; Index: fortune/fortune.c =================================================================== RCS file: /cvs/src/games/fortune/fortune/fortune.c,v retrieving revision 1.30 diff -u -r1.30 fortune.c --- fortune/fortune.c 3 Jan 2011 17:38:24 -0000 1.30 +++ fortune/fortune.c 21 Oct 2011 17:26:11 -0000 @@ -1104,7 +1104,7 @@ exit(1); } - /* fp->tbl.str_version = ntohl(fp->tbl.str_version); */ + fp->tbl.str_version = ntohl(fp->tbl.str_version); fp->tbl.str_numstr = ntohl(fp->tbl.str_numstr); fp->tbl.str_longlen = ntohl(fp->tbl.str_longlen); fp->tbl.str_shortlen = ntohl(fp->tbl.str_shortlen); -- squeak!