From alewis@email.unc.edu Thu Oct 19 11:49:00 MET 1995
Article: 73781 of comp.os.linux.misc
Path: jurix.jura.uni-sb.de!pf2.phil.uni-sb.de!news.coli.uni-sb.de!news.dfn.de!Germany.EU.net!howland.reston.ans.net!gatech!concert!bigblue.oit.unc.edu!not-for-mail
From: alewis@email.unc.edu (Amelia A Lewis)
Newsgroups: comp.os.linux.misc
Subject: Re: Fortune under Linux?
Date: 1 Oct 1995 00:09:02 -0400
Organization: The mystical world of Talsever
Lines: 163
Message-ID: <44l48u$2nm@talsever.fantasy.nonet>
References: <44anfb$v0f@CUBoulder.Colorado.EDU> <44atdu$1s5i@yuma.ACNS.ColoState.EDU> <44htl0$1u3@auriga.galacta.demon.co.uk>
NNTP-Posting-Host: login1.isis.unc.edu

In article <44htl0$1u3@auriga.galacta.demon.co.uk>,
Dr. Rich Artym <rich@galacta.demon.co.uk> wrote:
>
>What I'd like to know is why the fortunes in Slackware are so lousy!!!!
[deleted]
>in any way related.  Or is there a randomization fault as someone
>suggested, and only a bad subset is being selected?  Nah, unlikely ...

Okay.

I'm fairly certain that BSD fortune, and the strfile and unstr utilities
included with it, are broken as distributed.

If you'd like to test whether yours is, here's how.

prompt# cd /path/where/you/keep/your/fortune/files
prompt# mv fortunes fortunes-bak
promtp# mv fortunes.dat fortunes-bak.dat
prompt# cat ->fortunes
This is fortune #1
%
This is fortune #2
%
This is fortune #3
%
^D
prompt# strfile fortunes
prompt# fortune -f

Now, you have a list of the files that fortune claims it's looking at.
It probably isn't correct.  Test it by running:
prompt# fortune

ten times.  If all you see is "This is fortune #n" over and over, then
your copy of fortune is broken.

The fix is to fix the code that creates this silliness.  The workaround
is simpler.  Assuming that you've done all the above, the following
works.  If you *haven't* done the test above, then before doing what
follows, *rename* fortunes and fortunes.dat, or you'll wish you had!

prompt# rm fortunes
prompt# rm fortunes.dat
prompt# ln -s . fortunes

fortune will now display the same list with -f that it actually accesses.
You may find a sudden increase in the variety of fortunes that are
displayed.

strfile and unstr are also broken.  strfile *does* perform its basic
function, creating a .dat file, correctly, so as long as you don't wish
to sort or randomize the database, and don't have a null fortune (i.e.:
%
%
) in the text file, you won't have a problem (if you have a null fortune,
the next fortune after it is skipped).  To test it (since you won't
believe me), try the following:

prompt# cd /path/where/you/keep/your/fortune/files
prompt# cat ->test
z
%
a
%
x
%
s
%
^D
prompt# strfile -io test
prompt# unstr test >test.sorted
prompt# cat test.sorted

At this point, you *should* see:
a
%
s
%
x
%
z
%

But you won't.  It will be in the same order that you entered it, above.
Try:

prompt# diff test test.sorted

And you'll see that there are no differences (well, actually, unstr may
strip that trailing "%\n").

Showing that the next fortune after a null is skipped is a bit more
complex.  Trust me on that one, or look at the code, and note that if the
last fortune was null, the current pointer isn't written.

There are no workarounds, except to use different utilities to try to
sort the database.

The REAL solution:

I have fixed source code.  I'm delaying uploading it, because I'm still
working on reorganizing the data files.  But the source for the binaries
*is* fixed, and even enhanced (you can now specify length to break
between long and short fortunes, -f shows percentages, and strfile now
sorts, randomizes, and ignores null fortunes, while unstr takes an output
file parameter and allows you to globally change the delimiter
character).  As I say, I'm now planning on uploading this (probably as
fortune-mod.tar.gz, since someone might decide to fix the BSD code
without introducing quite as many changes as I have), but I want to
include the datafiles as well (I've changed the way to distinguish
between offensive and inoffensive from the '-o' infix to separate
subdirectories, and I'm trying hard to take out the multiple redundancy,
the presence of which was obscured by the fact that strfile wouldn't
really sort).

So.  If your fortune is broken, and you don't want to use the workarounds
suggested above, and *just* *can't* *wait*, I can send you the code for
the binaries.  Or you can wait a bit, and I'll upload the whole mess,
fixed.

I've also added a minor fortune-like program that you could use to
generate things like random signatures, lotteries, and like that.

Minor note: if any FreeBSD/NetBSD people are reading this, you might want
to look at the source for fortune and strfile.  Where fortune calls
add_file, in form_file_list, it incorrectly makes a different list if
Find_files is set and if it isn't.  Fixing strfile is a bit more complex,
but sorting and randomizing can be enabled just by not using a loop
control variable (in str_cmp and I forget the name of the randomize
function) that's set to zero at the top of the loop (put fprintf(stderr,
"Loop control variable i set to %ld\n", i); just before the loop, and
see!).  That doesn't fix the null-string problem (you need to add a
fix_last_pointer to do that, backing up over the just-written pointer to
a null string).  I'd offer diffs, but I've also changed the order of
function definitions (main last, and others in the order that they need
to be to avoid implicit declarations), so diffs would probably be as
large as the source itself, apart from the things that I think are
enhancements.  Point is, your fortune/strfile/unstr is broken, too, since
the Linux one is a straightforward port of yours.

Disclaimer: I'm not particularly well-trained as a programmer
(self-taught, for the most part; my formal training was in Pascal fifteen
years ago), and I've introduced one bug (documented in the man pages and
readme) into fortune.  I've been beating on my binaries to try to make
them crash, and I'm pretty sure that there's just the one bug (it's
rather obscure--happens when you specify -a and a percentage for a
filename that exists in the offensive and inoffensive directories).  I'm
reasonably certain that my mods won't break anything, but you may prefer
not to trust me (and if there's a hotshot programmer who feels like
taking my hacks to the code and rationalizing the whole program, feel
free), and back up your old files first.  Oh, and the sorting performed
by strfile only looks at the first line, so if the first line is empty,
or contains only non-alphanumeric characters, strfile 'sorts' it into the
space between alphanumerics (between a and b, or b and c, or c and d,
etc.).  I don't know why that is, but it isn't *my* bug.  It's now
documented, so consider it a feature.  :-)

Amy!
-- 
alewis@email.unc.edu              "But pain ... seems to me an insufficient
reason not to embrace life.  Being dead is quite painless.  Pain, like time,
is going to come on regardless. Question is: what glorious moments can you
win from life in addition to the pain?"  --Cordelia Vorkosigan [L.M. Bujold]



