[comp.sources.amiga] v90i187: UUCP 1.06D - UNIX compatible uucp/news/mail system, Part09/12

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (06/28/90)

Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon>
Posting-number: Volume 90, Issue 187
Archive-name: unix/uucp-1.06d/part09

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 9 (of 12)."
# Contents:  uucp2/src/dmail/dmail.help uucp2/src/news/rnews.c
# Wrapped by tadguy@xanth on Thu Jun 28 08:21:33 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'uucp2/src/dmail/dmail.help' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uucp2/src/dmail/dmail.help'\"
else
echo shar: Extracting \"'uucp2/src/dmail/dmail.help'\" \(23728 characters\)
sed "s/^X//" >'uucp2/src/dmail/dmail.help' <<'END_OF_FILE'
X
X$Header: Beta:src/uucp/src/dmail/RCS/dmail.help,v 1.1 90/02/02 12:03:57 dillon Exp Locker: dillon $
X
X'help TOPIC' for more information on a command.  Many commands take
Xmessage numbers or message lists:
X	[msg]	is an optionaly specified message number (usually the
X		operation is on the current message if no number is
X		specified)
X	<list>	is an optionaly specified message list.  Message lists
X		consists of number ranges of the form N -N N- or N-N, and
X		keywords (help keywords)
X
X
XOTHER HELP AVAILABLE (in addition to the commands):
X	pager sendmail tilde header newmail keywords enviroment
X
XDMAIL written by Matthew Dillon, U.C. Berkeley -UCF
X
X(C)Copyright 1985-1989 by Matthew Dillon
X
X.pager
Xset page [rows/command]
X
X	'page' is a SET variable which determines the type of paging list and
Xdisplay commands will use.  If not defined, no filter is used.	If a numerical
Xvalue (i.e. 24) is specified, the page length will be set to that value and
Xa rather stupid, simple internal paging routine will be used.  If the
Xvariable is set to an alpha-numeric string, output will be piped through
Xthat filter.  For instance:
X
X	unset page		-no paging
X	set page more		-use more filter
X	set page page		-use 'page' filter
X	set page > x		-redirect to a file (be careful)
X	set page 24		-use internal paging, page length 24 rows.
X
X	For internal paging, use <return> to continue, or your INTR
Xcharacter to break out.  Note that if you have paging set to a program,
Xresponse time may be slower because dmail must execute that program.
X
X.sendmail
Xset sendmail sendmail-path
X
X	Inform DMAIL as to where the sendmail program is.  The default
X(variable unset) is /usr/lib/sendmail.  This variable is useful only for
Xthose of us who like to hack-up our own sendmail.
X
X.tilde
X~ ~user directory expansion
X
X	In all expressions except those within double quotes, the tilde
X`~` will be expanded to either your home directory, or the directory of
Xa specified user, depending.  Note that '*' and '?' are not expanded by
XDMAIL, though they will be by any shell commands you execute.
X
X	It is probably a good idea to use ~ in any aliases, etc... in case
Xyou change directories using the 'cd' command.
X
X	alias resource source ~/.dmailrc		-example using ~
X
X.header
Xset header filepath
X
X	Set the location of your header file, which will appended to the
Xscratch mail file before you are placed in the editor (usually vi).
X
X	set header ~/.header			-set header file to ~/.header
X	unset header				-no header file
X
X.newmail
XWhen new mail comes in:
X
X	Whenever newmail arrives, it will be automatically incorporated into
Xa running DMAIL.  However, to see it, you must 'select all' (or select on
Xanything that would include it).
X
X.keywords
X.range
X.message
XKEYWORDS, MESSAGE LISTS
X
X	Many commands in DMAIL require a range of messages be given.  A Range
Xconsists of message numbers (3 4 5), message ranges (1-45 -9 9-), and
Xkeywords.  Keywords select certain messages from the entire SELECTED list:
X
X	all		-All messages
X	tag		-All TAGGED messages
X	mark		-All MARKED (read) messages
X	deleted 	-All DELETED messages
X	written 	-All WRITTEN messages
X	untag		-All messages NOT TAGGED
X	unmark		-All messages NOT MARKED (i.e. read)
X	undeleted	-All messages NOT DELETED
X	unwritten	-All messages NOT WRITTEN
X
X	Only the first three letters need be specified.  For instance, the
X'all' keyword selects all the messages currently selected.  You could select
Xon some subject, say, and then 'delete all'.
X
X	The message number 0 refers to the last message. the 'undeleted'
Xkeyword exists only for completeness; you will probably never use it.
X
X.ver
X.version
XVER
X
X	returns the version number.
X
X.if
X.else
X.endif
XIF [!]variable
XELSE
XENDIF
X
X	Conditionals.  Example:
X
X	if verbose
X		.... do stuff if the variable exists
X	else
X		... do stuff if the variable does not exist
X	endif
X	if !page; echo no page variable; endif
X
X.nobreak
X.breakok
XNOBREAK
XBREAKOK
X
X	Disable or Enable your INTR key.  This command is stackable, thus
Xthere is no problem with recursive aliases which use it.  Be careful that
Xyou match any NOBREAK to a BREAKOK, or you may accidently put yourself into
XNOBREAK mode (and a single BREAKOK may not fix it because it's stackable).
X
X	A good example would be a command which needs the page variable set
Xfor the duration... say an alias to TYPE to a file:
X
Xalias file "%_a nobreak; set _b $page; set page cat > $_a; type; set page $_b; unset _b; breakok"
X
X	You can see that if the user were to hit his INTR character at the
Xwrong time, the page variable would be incorrectly set.  The nobreak/breakok
Xcommands fix this problem.  For simplicity, most people don't bother with
Xbreak/nobreak, as it clutter's aliases up.
X
X.delete
XDELETE <message list>
X
X	Mark the specified messages for deletion.  They will no longer show up
Xon LISTings, (gaps will appear in message numbering).  However, you can
Xstill TYPE them, if you remember the message number, and you can always
XUNDELETE them.	Remember that the particular message # you've deleted
Xmay be different if you change the SELECT parameters.  For example,
Xmessage #3 selecting 'To' & 'foo' may actually be message #45 when you
Xare selecting ALL (see SELECT).  Upon a QUIT, messages marked for
Xdeletion are actually deleted from the mail file.
X
X.undelete
XUNDELETE   <message list>
X
X	UNDELETES messages.  Without arguments, UNDELETE will
Xrestore the last message you deleted.  Specifying 'all' (undelete all), will
Xundelete any deleted messages in the currently selected message list.
X
X.header
XHEADER [message]
X
X	Display the entire header of a message.  This does not cause the
Xmessage to be marked 'read'.  TYPE, on the other hand, only displays
Xheader information specified by SETLIST.
X
X.type
XTYPE [message]
X
X	Type the text of a message.  Only header fields defined by SETLIST
Xare displayed.	Otherwise, only the text is displayed.	This marks
Xthe particular message as 'read', and also makes that message the
Xcurrent message.
X
X.echo
XECHO [string]
X
X	Echo the given string onto the screen.
X
X.go
XGO #
X	go to a message, don't type it out or anything.  Remember that you
Xcan go to the last message by using the message # 0.  By placing a keyword
X(help range), you can go to the first TAGGED message, etc...
X
X.reply
X.Reply
XREPLY
X
X	Reply to the current letter.  There are two forms of 'reply'.  The
Xfirst does not include the senders original letter, the second does.
XIn both cases, Dmail will place you in VI, with the To:, Cc:, and
Xsubject lines filled out.  The second form is 'Reply', with an
Xupper case 'R'.  This form includes the sender's message shifted to
Xthe right with '>'s on the left hand side.  See FORWARD for another
Xmethod of replying to mail.
X
X	In any case, you may get the sender's letter by reading the file '#'
Xfrom VI.  That sequence would be ':r\\#'
X
X	See MAIL for more information on VI
X
X.forward
XFORWARD [user user user....]
X
X	Forward the current message to a list of users.  The sender's
Xentire message is placed in the text portion.  The To: field will
Xcontain the user's named above, and the Subject: field will contain
Xa 'Fo:' (you append your own subject)
X
X	See MAIL for more information on VI
X
X.mail
XMAIL [user user user user...]
X
X	Mail to [users].  You are given a VI to work from, and may modify
Xany of the header fields.  the From: field is inserted automatically
Xby SENDMAIL, but you can overide it if you wish.
X
X	Quitting out of VI without writing the output file will cause an
Xabort, and no mail will be sent.   Additionaly, you may use the 'vibreak'
Xvariable to enable your INTR character (usually CTL-C) to break you out of
XVI.
X
X	When modifying the users list in To and Cc fields, remember that
Xthey should be all comma delimited, or none comma delimited.
X
X.select
XSELECT ALL
XSELECT Field  match match match match...
XSELECT Field  !match
XSELECT Field  match match match , Field match , .....
X
X	Select what you want to look at.  Select will take the field header
Xyou supply and attempt to match arguments with that field in the mail
Xfile.  You can then work on the selected material as if the rest of
Xyour mail didn't exist.  For instance, 'select To dillon', will select
Xall messages addressed to you.	Note that case is checked for the
XFIELD-HEADER, but not for arguments, so the latter will also find
Xanything addressed to Dillon or DILLON.  You only have to give a
Xpartial match, so 'select To di' would work just as well.
X
X	Select then, allows you to quickly find what you want even though
Xyou may have 12000 messages (though it may take a while with that many)
XYou may also specify what you DON'T want to select on:
X
X select To !foo
X
Xwill select all letters not addressed to 'foo'.  You may select on any
Xfield you wish.  At any time, you may say 'select ALL' to select the
Xentire message list.  Use RESELECT to select on the current message
Xlist.  SELECT always selects from the entire message-list
X
X select Cc hack , To hack
X
Xwill select any mail with Cc or To fields containing hack.  You may
Xhave as many comma operators as you wish.  The comma must be a field
Xof its own (spaces on either side... will be fixed in a later version)
X
X.reselect
XRESELECT ALL
XRESELECT Field	match match match match...
XRESELECT Field	!match
X
X	SEE SELECT.  Reselect allows you to CONTINUE to narrow down a topic
Xor whatever.  It will select on the current message list (which you have
Xalready narrowed down with SELECT or RESELECT).
X
X.defer
XDEFER
X
X	Deselects any marked messages .. messages marked as 'read'.  This is
Xas if you did a RESELECT on all unread messages in the current select field.
XThus, the messages will be renumbered.	To see these messages again, you must
Xuse SELECT.
X
X.rlist <num>
XRLIST <num>		-<num> > 0 (next N), < 0 (prev N).
XRLIST			-Lists next 20 (or previous 20 if near the end)
X
X	Relative list.	See LIST for details of the list command.  This
Xcommand will display the next <num> messages beginning at the current
Xmessage.  If <num> is negative, it displays the previous 20 ending at
Xthe current message.  If there are not enough messages remaining in the
Xforward or reverse direction, it lists in the opposite direction to try
Xto bring the total messages listed to <num>
X
X.list
XLIST <message list>
XLIST			-Lists all selected messages
X
X	Display header information on a message as specified by SETLIST,
Xin a one line per message format.  The default lists ALL messages.
X
XLeftword flags:    r	-indicates message has been read.  Message will be
X			 moved to the destination file on QUIT
X		   >	-indicates message is the current message
X		   w	-indicates message has been written to a file.
X			 Message will be deleted from source file on QUIT
X		   T	-indicates message has been taged by the user
X
X.next
XNEXT
X
X	Execute TYPE or HEADER for the next message, depending on which of
XTYPE or HEADER was last executed by you
X
X._next
X_NEXT
X
X	Go to next message, do not print it out.
X
X.back
XBACK
X
X	Execute TYPE or HEADER for the previous message, depending on which
Xof TYPE or HEADER was last executed by you
X
X._back
X_BACK
X
X	Go to previous message, do not print it out.
X
X.db
XDB
X	Delete the current message, type (or header) the previous message.
XThis command could not be implemented with "del;prev" due to a special case
Xwhen one is on the last message.
X
X.dt
XDT
X	Delete current message, type (or header) next message.  This command
Xwill warn you when you reach the end of the message list.
X
X	References: DELETE and NEXT
X
X.enviroment
XENVIROMENT VARIABLE ACCESS
X
X	Access may be gained to enviroment variables by using $$ instead of
X	a single $.  For example:  echo $$USER
X
X	'help dmail' for command line options,
X	'help set'   for description of special variables
X
X.set
XSET [variable [string]]
X
X	see 'enviroment' for enviroment variables
X
X	With no arguments, SET prints out all currently active variables.
XNote that this variable list is a different list than the ALIAS list.  With
Xone argument, the specified variable is displayed if it exists, or created
Xif it doesn't.  With more than one argument, the specified variable is set
Xto the specified string.  Variables may be references on the command line by
X$variable .  The variable's contents will replace the reference.  Unlike
Xaliases, however, variable substitutions may take place anywhere on the
Xcommand line rather than substitute just the command name.  Note also that
Xif you use a $ substitution for an argument of a command, the entire
Xvariable's contents is ONE argument (i.e. if a = "b c d", and you say
Xsomething like: 'unset $a', it would attempt to unset a single variable
Xwhos name is "b c d".
X
X	There are several reserved SET variables, which define options in
XDMAIL.	Changing these will modify the option:
X
X	page		set paging on or to a specific command (i.e. more)
X	sendmail	set the path to the sendmail program
X	vibreak 	enable your INTR character even when in VI.
X	verbose 	reflects verbose option to sendmail
X	comlinemail	set when dmail executed w/ command line mailing list
X	header		header file to append to any messages you send.
X	ask		ask what to do after vi'ing mail
X	archive 	file to archive any mail you send out in.
X	_headchar	string used to precede included text, default ">"
X	replyfields	fields to search to find the reply path
X
X	page
X
X	 This variable determines what kind of paging is used for LIST,
X	 TYPE, and HEADER commands.  If the variable does not exist, paging
X	 is turned off.  If set to null (no string), an internal paging
X	 routine is used.  If set to a value, an internal paging routine is
X	 used using the value as the page length.  the 'page' variable can
X	 also be set to a command, such as 'more' or 'page', in which case,
X	 the output is piped through those commands:
X
X	 set page		Turn paging on (internal page routine)
X	 set page 25		Internal page routine... 25 rows/screen
X	 set page more		Use 'more' command to pipe output through
X	 set page page		Use 'page' command to pipe output through
X
X	 you could also conceviably say:  'set page cat > x', or
X	 'set page cat | lpr', but be very careful.
X
X	sendmail
X
X	 This variable will redirect DMAIL as to where the mailer program
X	 is.  The mailer program must be compatible with /usr/lib/sendmail
X	 which is the default used if the 'sendmail' variable isn't set
X	 to anything:
X
X	 set sendmail bin/mysendmail
X
X	vibreak
X
X	 This variable, when set, allows the INTR character to abort a
X	 reply, mail, or forward command.  Otherwise, if this variable is
X	 not present, INTR will not abort the above commands.
X
X	verbose
X
X	 This variable, when set, causes the -v flag to be sent to
X	 sendmail.  In addition, DMAIL will wait for sendmail to complete
X	 before returning your prompt.
X
X	comlinemail
X
X	 This variable is set when dmail is invoked with a command line
X	 user list (e.g.  dmail charlie mary mark). Usually, one uses
X	 this variable in an IF construct.  A good example would be that
X	 you may usually CD to a mail directory, but you don't want to
X	 CD when dmail is run with a command line user-list:
X
X		if !comlinemail
X			cd  ...
X
X	 alternate definition: The comlinemail variable will NOT be set
X	 if dmail is in interactive mode.
X
X	header
X
X	 The file specified by this variable will be appended onto the temp
X	 vi files in reply and mail.  The file is appended before you go into
X	 vi, so when you do, what you see is still what you get.
X
X	ask
X
X	 If set, dmail will ask you what to to (quit, send, re-edit) after you
X	 leave the editor when sending mail.  If not set, the mail is sent as
X	 soon as you leave the editor (unless you didn't write anything).
X
X	archive
X
X	 If set (to a file name), any mail you send out (mail/reply/etc...)
X	 will be archived to this file.  Usually, you provide a fully
X	 specified path so cd's won't effect the file location.
X
X	_headchar
X
X	 This string is prepend to any included text when you do an upper-case
X	 reply (R) command.
X
X	replyfields
X
X	 This string holds a list of fields which are searched for to
X	 determine which one to use in the To: field of your reply.  If
X	 this variable does not exist or none of the specified fields could
X	 be found, the 'From ' (not From:) mail header will be used.  The
X	 search ends at the first field found.	Example:
X
X	 set replyfields "Reply-To: From:"
X
X.replyfields
XSET replyfields "field1 field2 ..."
X
X	 This string holds a list of fields which are searched for to
X	 determine which one to use in the To: field of your reply.  If
X	 this variable does not exist or none of the specified fields could
X	 be found, the 'From ' (not From:) mail header will be used.  The
X	 search ends at the first field found.	Example:
X
X	 set replyfields "Reply-To: From:"
X
X.>
XSET _HEADCHAR "string"
X
X	see SET.  The _headchar variable determines the string prepending all
X	included text when you do an upper-case reply (R) command.
X
X.archive
XSET ARCHIVE file
X
X	if the archive variable is set to a file path, any mail you send out
X	will automatically be appended to that file.  Dmail pre-pends a
X	"From ", so it is compatible with /bin/mail and so that you can
X	dmail -f your archive file.  Additionaly, a "Date: " field is
X	pre-pended so you know when you sent the message.  example:
X
X	set archive ~/Dmail/arch
X
X	since your .dmailrc is sourced even when you "dmail user .." from
X	your csh, putting the above line in your .dmailrc will turn on
X	archiving whenever you use dmail to send mail, command line or
X	dmail prompt.
X
X	if unset or set to nothing, no archive is made.
X
X.ask
XSET ASK
X
X	if the 'ask' variable is set (set ask), dmail will ask you what to do
X	when you are finished editing mail rather than send it immediately.
X	(see 'help set')
X
X.alias
XALIAS [variable [string]]
X
X	Create an alias for a command.	With no arguments, ALIAS will display
Xall active aliases.  With one argument, a particular alias is displayed (if
Xit exists), or defined (if it did not previously exist).  With more than one
Xargument, the particular alias is set to the string list specified.
X
Xalias
Xalias hack "select From hacker , To hacker , Cc hacker"
Xalias bye quit
Xalias stuff "setlist 60 To ; list"
X
X	Usually, any arguments following the alias are appended to the
Xexpansion.  However, you can place such arguments inside the alias somewhere
Xby using the following construction:
X
Xalias myecho "%var echo $var ; list"
X
Xmyecho hello there  ---> echo hello there ; list
X
X	to unalias an alias, use the UNALIAS command.
X
X.unset
X.unalias
XUNSET var var var...
XUNALIAS var var var...
X
X	Eradicate variables or aliases from memory.
X
X.setlist
XSETLIST [-s] [columns] Field [columns] Field ...
X
X	-s prevents display of the list.
XSet the list format used for LIST and TYPE.  The optional [columns]
Xindicates how many columns to allocate for the Field specified.  The
XField can be a partial match. However, case is observed:
X
Xsetlist 18 Fro	38 Sub	10 To  0 Dat
X
X18 columns for the From: field, etc... when TYPEing messages, the
X[columns] is ignored, and each field is printed in its entirety.
XNote that 0 columns have been allocated for the Date: field.
XTherefore, the Date: field will not show up on the LIST command,
Xbut will show up in the TYPE command.
X
X.cd
XCD PATH
X
X	cd, as in csh.	Changes your base directory.  You can use
X the shell escape '! pwd' to get your current working directory.
X
X.source
XSOURCE file
X
X	Source a file.	The file is read in an executed in sequence.
X
X.preserve
XPRE	<message list>
X
X	PRESERVE messages.  A message is MARKED if it has been read (has an 'r'
Xflag from the LIST command).  Marked messages are moved from your readfile
Xinto your outfile upon a QUIT.	If you are reading and writing to the same
Xfile (i.e. from your mbox to your mbox), the 'r' flag has no effect.
X
X	However, if you are reading from your spool file, and want to keep
Xread messages in your spool (that is, not move them to your mbox), you want
Xto PRESERVE them.  This command simply unmarks them, so they appear not to
Xhave been read.
X
X.mark
XMARK <message list>
X
X	Mark messages specified as being already 'read'.  Remember that if
Xyou executed DMAIL without a -f option, any message 'read' at the time
Xyou quit will be moved to MBOX (or file specified by -o)
X
X.tag
X.untag
XTAG <list>
XUNTAG <list>
X
X	The TAG command allow you to flag any message.	You can tag a set of
Xmessages, then reference them all at once.  For instance, if you tag
Xinteresting messages as you glance at them, you may then write them all
Xto a file by 'write filename tag',  or list them with 'list tag'.
XAlternately, you could delete all your taged messages with a single delete
Xcommand 'delete tag'.  The 'tag' operand works in the same way as the 'all'
Xoperand, except it works only on taged messages.
X
X	UNTAG will untag a particular message in your message list.  For
Xinstance, to untag any taged messages in the entire message list, you would:
X
X select all
X untag all	OR	 untag tag
X
X	Note that 'untag all' and 'untag tag' have the same effect.
X
X.write
XWRITE file <message list>
X
X	Write the given messages or the current message to a file.  The file
Xfile is appended to.  Remember that you may specify 'all' to write
Xall messages in the current select field to the file.  Messages will be
Xmarked as having been writen, and will be deleted from the mail file
Xwhen you 'quit'.  However, you may cause them to be kept in the mail
Xfile by UNdeleting the messages (i.e.  undelete all)
X
X	You can also TAG the messages you want to write, and say
X'write file tag' to write to the file all taged messages.
X
X.!
X! [shell command]
X
X	Give yourself a shell or execute a shell command.  The shell forked
Xis that specified by your SHELL enviroment variable, or /bin/sh if there is
Xno SHELL enviroment variable.
X
X.x
X.exit
XX (EXIT)
X
X	EXIT out of DMAIL without changing any files.  Usually, one exits
Xwith QUIT, which would cause deleted messages to disappear, and TYPEd
Xmessages to go to MBOX (if you did not use the -f option with DMAIL).
X
X	If your outfile is the same as your infile, reading a message does
Xnot effect anything.
X
X.quit
XQUIT
X
X	Quit out of DMAIL. Delete any messages that were marked for deletion
Xand if you executed DMAIL on /usr/spool/mail/ (default), any mail
Xmarked 'read' will be placed in MBOX in your home directory
X
X.xswitch
X.qswitch
XXSWITCH fromfile [tofile]
XQSWITCH fromfile [tofile]
X
X	Switch to a different set of files.  XSWITCH doesn't modify your
Xold from and to files before switching, QSWITCH works as if you had QUIT
Xstuff before switching to another set of files.
X
X	If no [tofile] is specified, the new tofile will be the same as the
Xfromfile you specify.
X
X.help
X.?
XHELP [topic]
X
X	Give me help on a topic
X
X.dmail
XCOMMAND LINE OPTIONS FOR DMAIL
X
X	dmail -O [-l rcfile] -f [file] -o [file] -F field -F field -F field ...
X
X	Default conditions:
X		Home directory gotten from password entry
X		User gotten from password entry
X		Visual editor set to /usr/ucb/vi
X
X		VI BREAKOUT enabled
X		READ file is /usr/spool/mail/$USER
X		WRITE file is $HOME/mbox
X		From:,	To:, and Subject: fields will be loaded into memory.
X
X	HOME	enviroment variable becomes home directory
X	USER	enviroment variable becomes user name
X	VISUAL	enviroment variable becomes editor used
X
X	-O			Go into interactive mode, even if there is no
X				mail to read.
X
X	-f [from file]		Specify spool file to get mail from. If no file
X				Argument is given, $HOME/MBOX is used.
X
X	-o [to file]		Specify file to write to, If no Argument
X				is given, $HOME/.MBOX is used.	Note that
X				the default without -o is $HOME/MBOX
X
X	-f -o			With no file arguments causes both READ and
X				WRITE files to be $HOME/.MBOX
X
X	-F field		Append this field to those which will be
X				used on initial load.  If, During usage of the
X				program you specify a field which is not in
X				memory, DMAIL will be forced to re-load the
X				entire spool file, which can take a long time
X				if you have more than 64K in the file
X
X	-l rcfile		Use this as the rc file rather than .dmailrc
X
X	-L			Do not source the rc file on boot
X
X
END_OF_FILE
if test 23728 -ne `wc -c <'uucp2/src/dmail/dmail.help'`; then
    echo shar: \"'uucp2/src/dmail/dmail.help'\" unpacked with wrong size!
fi
# end of 'uucp2/src/dmail/dmail.help'
fi
if test -f 'uucp2/src/news/rnews.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uucp2/src/news/rnews.c'\"
else
echo shar: Extracting \"'uucp2/src/news/rnews.c'\" \(21274 characters\)
sed "s/^X//" >'uucp2/src/news/rnews.c' <<'END_OF_FILE'
X
X/*
X *  RNEWS.C
X *
X *  Copyright 1988 by William Loftus.  All rights reserved.
X *  Extensive Changes Copyright 1990 by Matthew Dillon, All Rights Reserved
X *
X *  This is rnews for compressed news.	News 2.11 will uux
X *  a file to this system that will be in compressed format.
X *  This program will strip off the "#! cunbatch", uncompress
X *  the news, and call unbatch.  If the news is not in compressed
X *  format it will just pass it to unbatch.
X *
X *  Each newsgroup directory has a .next file which indicates the next
X *  article number to write.  This number rolls over at 32767.
X */
X
X#include "news.h"
X#include <errno.h>
X#include <ctype.h>
X#include <sys/stat.h>	    /* outrageous place for the mkdir() proto! */
X#include <log.h>
X
Xextern char *TmpFileName();
X
XIDENT(".04");
X
Xstatic int dofile(void);
Xstatic void unbatch(char *);
Xstatic long store_art(long size, char *);
Xstatic void uncompress_news(void);
Xstatic void news_exit(int stat);
X
X#define exit news_exit
X
Xstatic char TmpBuf[2048];
Xchar homedir[256];
X
Xchar *NewsDir;
Xchar *WKName;
X
Xvoid copy_uualtspool();
X
X#define PROG_NAME "RNews"
X
Xint
Xmain(ac, av)
Xint ac;
Xchar *av[];
X{
X    int ret = 0;
X    short i;
X
X    LogProgram = PROG_NAME;
X    fclose(stderr);         /* Assume we are running in the background */
X
X    getcwd(homedir, sizeof(homedir));
X    NewsDir = GetConfigDir(UUNEWS);
X
X    if (chdir(NewsDir) != 0) {
X	ulog(0, "NewsDir %s doesn't exist; quitting", NewsDir);
X	exit(1);
X    }
X    WKName = strdup(TmpFileName("news-work"));
X
X    for (i = 1; i < ac; ++i) {
X	char *ptr = av[i];
X	if (*ptr != '=')
X	    break;
X	switch(ptr[1]) {
X	case 'x':
X	    LogLevel = atoi(ptr + 2);
X	    break;
X	default:
X	    printf("unknown flag '%s' ignored\n", ptr + 1);
X	    break;
X	}
X    }
X    if (i < ac && strcmp(av[i], "UseNet") == 0) {
X	ulog(1, "Starting standard input");
X	if (atoi(GetConfig(RNEWSDEBUG, "0"))) {
X	    ulog(-1, "RNewsDebug, copying to UUAltSpool:");
X	    copy_uualtspool();
X	}
X
X	if (dofile() < 0)
X	    ret = 1;
X    } else {
X	for (; i < ac; ++i) {
X	    char *ptr = av[i];
X
X	    chdir(homedir);         /* so relative file names will work */
X	    ulog(1, "Starting file %s", ptr);
X	    if (freopen(ptr, "r", stdin) == NULL) {
X		ulog(0, "Cannot open news file %s", ptr);
X		continue;
X	    }
X	    chdir(NewsDir);
X	    if (dofile() < 0)
X		ret = 1;
X	}
X    }
X    if (ret == 0)
X	remove(WKName);
X    exit(ret);
X}
X
Xstatic int
Xdofile(void)
X{
X    char buf[64];
X
X    if (fgets(buf, sizeof(buf), stdin)) {
X	if (strncmp(buf, "#! cunbatch", 11) == 0) {
X	    uncompress_news();
X	} else {
X	    unbatch(buf);
X	}
X    }
X    fclose(stdin);
X    return(0);
X}
X
X/*
X * Unbatch, an Amiga unbatcher.
X *
X *	Written by Fred Cassirer, 10/8/88.
X *	Some unbatch code originally taken from News2.11 sources.
X *
X *	Ported to Lattice 5.0
X *	Added config.h file
X *	Added use of ERRORFILE
X *	11/23/1988  Dan 'Sneakers' Schein
X *
X * This code (as well as the unbatch stuff) is free for anyone who thinks
X * they can get some use out of it.
X *
X *	Articles will only be placed in newsgroups as defined in the
X *	"LIB/NewsGroups" control file.  Articles which are not listed
X *	in the control file are placed in the "junk" directory.  Articles
X *	are sequenced by the sequencer in "LIB/seqnews". This could
X *	possibly be updated to use a sequencer within each of the news
X *	subdirectories, to more closely resemble the News system under Unix.
X *
X *	(sequence numbers are not kept in the NewsGroups file itself but in
X *	each news directory.  This protects against accidents)
X *
X *	The NewsGroups file contains one newsgroup per line, plus an optional
X *	# days expiration.  For example:
X *
X *	    comp.sys.amiga  30
X *
X *	Unbatch will also take command line args of files to be unbatched.
X *	Files on the command line are not removed, they should be removed
X *	after running unbatch.
X */
X
Xstatic struct group {
X    struct group *next;
X    char name[1];
X} groups;
X
Xstatic void
Xinitgroups(void)
X{
X    struct group *gp;
X    long len;
X    FILE *fp;
X    char buf[50];
X
X    if (groups.next != NULL)
X	return;
X
X    if ((fp = openlib("newsgroups")) == NULL) {
X	ulog(0, "Couldn't open LIB/newsgroups file");
X	exit(2);
X    }
X
X    gp = &groups;
X    while (fgets(buf, sizeof(buf), fp)) {
X	short c;
X	for (len = 0; (c = buf[len]) != ' ' && c != 9 && c != '\n'; ++len);
X	buf[len] = 0;
X	if ((gp->next = (struct group *)malloc(4+len+1)) == NULL) {
X	    ulog(0, "Malloc failed!");
X	    exit(4);
X	}
X	gp = gp->next;
X	strcpy(gp->name, buf);
X    }
X    gp->next = NULL;
X    fclose(fp);
X}
X
Xstatic char *
Xfinddir(dir)
Xchar *dir;
X{
X    struct group *gp, *dp = NULL;
X    char *p;
X    int c;
X
X    do {
X	p = dir;
X	do {
X	    c = *++dir;
X	} while (c != ' ' && c != ',' && c != '\n' && c != '\0');
X	*dir++ = '\0';
X
X	for (gp = groups.next; gp != NULL; gp = gp->next) {
X	    if (gp == dp)
X		break;
X	    if (strcmp(gp->name, p) == 0) {
X		dp = gp;
X		break;
X	    }
X	}
X    } while (c != '\n' && c != '\0');
X
X    if (dp)
X	return (dp->name);
X    return ("junk");        /* Oops, not a known newsgroup */
X}
X
X/*
X * unbatchnews: extract news in batched format and process it one article
X * at a time.  The format looks like
X *	#! rnews 1234
X *	article containing 1234 characters
X *	#! rnews 4321
X *	article containing 4321 characters
X */
X
Xstatic void
Xunbatch(hdr)
Xchar *hdr;
X{
X    long size;
X    char buf[64];
X
X    if (hdr) {
X	strcpy(buf, hdr);
X    } else {
X	buf[0] = 0;
X	fgets(buf, sizeof(buf), stdin);
X    }
X    if (strncmp(buf, "#! rnews ", 9) != 0) {
X	store_art(10000000L, buf);
X	return;
X    }
X    do {
X	/* second strcmp is kludge for bug */
X
X	if (strncmp(buf, "#! rnews ", 9) != 0 && strncmp(buf, "! rnews ", 8) != 0) {
X	    char *cp;
X
X	    for (cp = buf; *cp; ++cp) {
X		if (!isprint(*cp) && !isspace(*cp))
X		    *cp = '?';
X	    }
X	    *--cp = '\0';
X	    ulog(0, "out of sync, skipping <%s>", buf);
X	    continue;
X	}
X
X	size = atol(buf + 8 + (buf[0] == '#'));
X	if (size <= 0) {
X	    ulog(0, "nonsense size %ld", size);
X	    continue;
X	}
X
X	if (store_art(size, NULL) > 0) {
X	    /*
X	     * If we got a truncated batch, don't process the
X	     * last article; it will probably be received again.
X	     */
X	    ulog(0, "truncated batch");
X	    break;
X	}
X    } while (fgets(buf, sizeof(buf), stdin));
X}
X
Xstatic long
Xstore_art(size, ibuf)
Xlong size;
Xchar *ibuf;
X{
X    int c;
X    FILE *pfn;
X    FILE *seq;
X    unsigned long seqno;
X    char *dir;
X
X    initgroups();
X
X    ulog(2, "SIZE %ld", size);
X
X    if ((pfn = fopen("ArticleTemp", "w")) == NULL) {
X	ulog(0, "Could not creat article temp file");
X	exit(3);
X    }
X
X    dir = "Rejects";
X
X    if (ibuf)
X	fputs(ibuf, pfn);
X
X    /*
X     *	search for Newsgroups: line in a manner independant of the line
X     *	length, which can be anything.
X     */
X
X    {
X	int i = 0;
X
X	while (size && (c = getc(stdin)) != EOF) {
X	    putc(c, pfn);
X	    --size;
X	    TmpBuf[i++] = c;
X	    if (i == sizeof(TmpBuf))    /*  very long non-NewsGroups: header  */
X		i = 0;
X	    if (c == '\n')
X		i = 0;
X	    if (c == ':') {
X		if (strncmp(TmpBuf, "Newsgroups:", 11) == 0) {
X		    if (fgets(TmpBuf, sizeof(TmpBuf), stdin)) {
X			fputs(TmpBuf, pfn);
X			size -= strlen(TmpBuf);
X			for (i = 0; TmpBuf[i] == ' ' || TmpBuf[i] == 9; ++i);
X			dir = finddir(TmpBuf + i);
X			break;
X		    }
X		}
X	    }
X	}
X    }
X    while (size > 0) {
X	int n = (size > sizeof(TmpBuf)) ? sizeof(TmpBuf) : size;
X	int r = fread(TmpBuf, 1, n, stdin);
X
X	if (r <= 0)
X	    break;
X	fwrite(TmpBuf, 1, r, pfn);
X	size -= r;
X    }
X    fflush(pfn);
X    if (ferror(pfn)) {              /* disk full? */
X	fclose(pfn);
X	remove("ArticleTemp");
X	ulog(0, "error writing temporary file");
X	return (-1);
X    }
X    fclose(pfn);
X
X    sprintf(TmpBuf, "%s/.next", dir);
X    if (IsDir(dir)) {
X	if ((seq = fopen(TmpBuf, "r")) == NULL) {
X	    ulog(0, "sequencer file '%s' not found, will create", TmpBuf);
X	    seqno = 1000;
X	} else {
X	    fscanf(seq, "%ld", &seqno);
X	    fclose(seq);
X	}
X    } else if (mkdir(dir) != 0) {
X	ulog(0, "Cannot create directory for '%s'; article dropped", dir);
X	return (-1);
X    } else {
X	seqno = 1;
X    }
X    if ((seq = fopen(TmpBuf, "w")) == NULL) {
X	ulog(0, "Couldn't create sequencer for '%s'; article dropped", dir);
X	return (-1);
X    } else {
X	fprintf(seq, "%ld\n", (seqno + 1) & 0x7FFF);
X	fclose(seq);
X    }
X
X    sprintf(TmpBuf, "%s/%ld", dir, seqno);
X    ulog(2, "FILE %s", TmpBuf);
X    if (rename("ArticleTemp", TmpBuf) != 0) {
X	remove("ArticleTemp");
X	ulog(0, "Could not rename article to %s", TmpBuf);
X    }
X    return (size);
X}
X
X/*
X * Set USERMEM to the maximum amount of physical user memory available
X * in bytes.  USERMEM is used to determine the maximum BITS that can be used
X * for compression.
X *
X * SACREDMEM is the amount of physical memory saved for others; compress
X * will hog the rest.
X */
X
X#ifndef SACREDMEM
X#define SACREDMEM	0
X#endif
X
X#ifndef USERMEM
X#  define USERMEM	450000	/* default user memory */
X#endif
X
X#ifdef AMIGA			/* Commodore Amiga */
X# define BITS		16
X# define M_XENIX	/* so we can use small model (faster) */
X# undef USERMEM
X#endif
X
X#ifdef interdata		/* (Perkin-Elmer) */
X#define SIGNED_COMPARE_SLOW	/* signed compare is slower than unsigned */
X#endif
X
X#ifdef pdp11
X# define BITS	12	/* max bits/code for 16-bit machine */
X# define NO_UCHAR	/* also if "unsigned char" functions as signed char */
X# undef USERMEM
X#endif /* pdp11 */	/* don't forget to compile with -i */
X
X#ifdef z8000
X# define BITS	12
X# undef vax		/* weird preprocessor */
X# undef USERMEM
X#endif /* z8000 */
X
X#ifdef pcxt
X# define BITS	12
X# undef USERMEM
X#endif /* pcxt */
X
X#ifdef USERMEM
X# if USERMEM >= (433484+SACREDMEM)
X#  define PBITS 16
X# else
X#  if USERMEM >= (229600+SACREDMEM)
X#   define PBITS	15
X#  else
X#   if USERMEM >= (127536+SACREDMEM)
X#    define PBITS	14
X#   else
X#    if USERMEM >= (73464+SACREDMEM)
X#     define PBITS	13
X#    else
X#     define PBITS	12
X#    endif
X#   endif
X#  endif
X# endif
X# undef USERMEM
X#endif /* USERMEM */
X
X#ifdef PBITS		/* Preferred BITS for this memory size */
X# ifndef BITS
X#  define BITS PBITS
X# endif BITS
X#endif /* PBITS */
X
X#if BITS == 16
X# define HSIZE	69001		/* 95% occupancy */
X#endif
X#if BITS == 15
X# define HSIZE	35023		/* 94% occupancy */
X#endif
X#if BITS == 14
X# define HSIZE	18013		/* 91% occupancy */
X#endif
X#if BITS == 13
X# define HSIZE	9001		/* 91% occupancy */
X#endif
X#if BITS <= 12
X# define HSIZE	5003		/* 80% occupancy */
X#endif
X
X#ifdef M_XENIX			/* Stupid compiler can't handle arrays with */
X# if BITS == 16 		/* more than 65535 bytes - so we fake it */
X#  define XENIX_16
X# else
X#  if BITS > 13 		/* Code only handles BITS = 12, 13, or 16 */
X#   define BITS 13
X#  endif
X# endif
X#endif
X
X/*
X * a code_int must be able to hold 2**BITS values of type int, and also -1
X */
X#if BITS > 15
Xtypedef long int	code_int;
X#else
Xtypedef int		code_int;
X#endif
X
X#ifdef SIGNED_COMPARE_SLOW
Xtypedef unsigned long int count_int;
X#else
Xtypedef long int	count_int;
X#endif
X
X#ifdef NO_UCHAR
Xtypedef char		char_type;
X#else
Xtypedef unsigned char	char_type;
X#endif /* UCHAR */
Xchar_type magic_header[] = { "\037\235" };      /* 1F 9D */
X
X/* Defines for third byte of header */
X#define BIT_MASK	0x1f
X#define BLOCK_MASK	0x80
X/* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
X   a fourth header byte (for expansion).
X*/
X#define INIT_BITS	9	/* initial number of bits/code */
X
Xint n_bits;			/* number of bits/code */
Xint maxbits = BITS;		/* user settable max # bits/code */
Xcode_int maxcode;		/* maximum code, given n_bits */
Xcode_int maxmaxcode;	/* 1 << BITS */ /* should NEVER generate this code */
X#define MAXCODE(n_bits)         ((((code_int)1) << (n_bits)) - 1)
X
X#ifdef XENIX_16
Xcount_int * htab[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
Xunsigned short * codetab[5] = { NULL, NULL, NULL, NULL, NULL };
X#else	/* Normal machine */
Xcount_int	htab[HSIZE];
Xunsigned short	codetab[HSIZE];
X#endif /* XENIX_16 */
Xcode_int hsize = HSIZE; 	/* for dynamic table sizing */
X
X/*
X * The tab_suffix table needs 2**BITS characters.  We get this from the
X * beginning of htab.  The output stack uses the rest of htab, and contains
X * characters.	There is plenty of room for any possible stack (stack used
X * to be 8000 characters).
X */
X
X#ifdef XENIX_16
X# define tab_prefixof(i)        (codetab[(i)>>14][(i) & 0x3FFF])
X# define tab_suffixof(i)        ((char_type *)htab[(i)>>15])[(i) & 0x7FFF]
X# define de_stack		((char_type *)(htab[2]))
X#else	/* Normal machine */
X# define tab_prefixof(i)        codetab[i]
X# define tab_suffixof(i)        (((char_type *)htab)[i])
X/* FIXME??? This next line is suspect..... */
X# define de_stack		((char_type *)(((long)htab)+(((code_int)1)<<BITS)))
X#endif /* XENIX_16 */
X
Xcode_int free_ent = 0;	/* first unused entry */
X
Xstatic code_int getcode(void);
Xstatic void writeerr(void);
X
X/*
X * block compression parameters -- after all codes are used up,
X * and compression rate changes, start over.
X */
Xint block_compress = BLOCK_MASK;
Xint clear_flg = 0;
X
X/*
X * the next two codes should not be changed lightly, as they must not
X * lie within the contiguous general code space.
X */
X#define FIRST	257	/* first free entry */
X#define CLEAR	256	/* table clear output code */
X
X/*
X * Decompress stdin to stdout.	This routine adapts to the codes in the
X * file building the "string" table on-the-fly, requiring no table to
X * be stored in the compressed file.
X */
X
X#ifdef XENIX_16
X
Xstatic void *
Xsafealloc(long size)
X{
X    int retry = 30;
X    void *p;
X
X    while ((p = malloc(size)) == NULL) {
X	if (--retry < 0) {
X	    ulog(0, "Can't get memory to decompress news batch -- terminating");
X	    exit(20);
X	}
X	ulog(0, "Can't get memory to decompress news batch -- will retry");
X	sleep(30);
X    }
X    return p;
X}
X
X#endif /* XENIX_16 */
X
Xstatic void
Xdecompress(void)
X{
X	register char_type *stackp;
X	register int finchar;
X	register code_int code, oldcode, incode;
X
X	maxcode = MAXCODE(n_bits = INIT_BITS);
X	free_ent = ((block_compress) ? FIRST : 256);
X	finchar = oldcode = getcode();
X	if(oldcode == -1)       /* EOF already? */
X		return; 	/* Get out of here */
X
X#ifdef XENIX_16
X	htab[0] = (code_int *)safealloc(8192*sizeof(code_int));
X	htab[1] = (code_int *)safealloc(8192*sizeof(code_int));
X	htab[2] = (code_int *)safealloc(8192*sizeof(char));
X	for (code = 0; code < 5; ++code)
X		codetab[code] = (unsigned short *)
X				safealloc(16384*sizeof(unsigned short));
X#endif /* XENIX_16 */
X
X	/*
X	 * As above, initialize the first 256 entries in the table.
X	 */
X	for (code = 255; code >= 0; code--) {
X		tab_prefixof(code) = 0;
X		tab_suffixof(code) = (char_type)code;
X	}
X
X	putchar((char)finchar); /* first code must be 8 bits = char */
X	if(ferror(stdout))      /* Crash if can't write */
X		writeerr();
X	stackp = de_stack;
X
X	while ((code = getcode()) > -1) {
X		if ((code == CLEAR) && block_compress) {
X			for (code = 255; code >= 0; code--)
X				tab_prefixof(code) = 0;
X			clear_flg = 1;
X			free_ent = FIRST - 1;
X			if ((code = getcode()) == -1)   /* O, untimely death! */
X				break;
X		}
X		incode = code;
X		/*
X		 * Special case for KwKwK string.
X		 */
X		if (code >= free_ent) {
X			*stackp++ = finchar;
X			code = oldcode;
X		}
X
X		/*
X		 * Generate output characters in reverse order
X		 */
X#ifdef SIGNED_COMPARE_SLOW
X		while (((unsigned long)code) >= ((unsigned long)256))
X#else
X		while (code >= 256)
X#endif
X		{
X			*stackp++ = tab_suffixof(code);
X			code = tab_prefixof(code);
X		}
X		*stackp++ = finchar = tab_suffixof(code);
X
X		/*
X		 * And put them out in forward order
X		 */
X		do {	register int c = *--stackp;
X			putc(c, stdout);        /* putc is often a macro! */
X		} while (stackp > de_stack);
X
X		/*
X		 * Generate the new entry.
X		 */
X		if ((code=free_ent) < maxmaxcode) {
X			tab_prefixof(code) = (unsigned short)oldcode;
X			tab_suffixof(code) = finchar;
X			free_ent = code+1;
X		}
X		/*
X		 * Remember previous code.
X		 */
X		oldcode = incode;
X	}
X
X	fflush(stdout);
X	if(ferror(stdout))
X		writeerr();
X
X#ifdef XENIX_16
X	free(htab[0]), htab[0] = NULL;
X	free(htab[1]), htab[1] = NULL;
X	free(htab[2]), htab[2] = NULL;
X	for (code = 0; code < 5; ++code)
X		free(codetab[code]), codetab[code] = NULL;
X#endif /* XENIX_16 */
X}
X
X/*****************************************************************
X * TAG(getcode)
X *
X * Read one code from the standard input.  If EOF, return -1.
X * Inputs:
X *	stdin
X * Outputs:
X *	code or -1 is returned.
X */
X
X#ifndef vax
Xchar_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
X#endif /* vax */
X
Xstatic code_int
Xgetcode(void)
X{
X	/*
X	 * On the VAX, it is important to have the register declarations
X	 * in exactly the order given, or the asm will break.
X	 */
X	register code_int code;
X	static int offset = 0, size = 0;
X	static char_type buf[BITS];
X	register int r_off, bits;
X	register char_type *bp = buf;
X
X	if (clear_flg > 0 || offset >= size || free_ent > maxcode) {
X		/*
X		 * If the next entry will be too big for the current code
X		 * size, then we must increase the size.  This implies reading
X		 * a new buffer full, too.
X		 */
X		if (free_ent > maxcode) {
X			n_bits++;
X			if (n_bits == maxbits)
X				/* won't get any bigger now */
X				maxcode = maxmaxcode;
X			else
X				maxcode = MAXCODE(n_bits);
X		}
X		if (clear_flg > 0) {
X			maxcode = MAXCODE(n_bits = INIT_BITS);
X			clear_flg = 0;
X		}
X		size = fread(buf, 1, n_bits, stdin);
X		if (size <= 0)
X			return -1;	/* end of file */
X		offset = 0;
X		/* Round size down to integral number of codes */
X		size = (size << 3) - (n_bits - 1);
X	}
X	r_off = offset;
X	bits = n_bits;
X#ifdef vax
X	asm("extzv      r10,r9,(r8),r11");
X#else /* not a vax */
X	/*
X	 * Get to the first byte.
X	 */
X	bp += (r_off >> 3);
X	r_off &= 7;
X	/* Get first part (low order bits) */
X#ifdef NO_UCHAR
X	code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
X#else
X	code = (*bp++ >> r_off);
X#endif /* NO_UCHAR */
X	bits -= (8 - r_off);
X	r_off = 8 - r_off;	/* now, offset into code word */
X	/* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
X	if (bits >= 8) {
X#ifdef NO_UCHAR
X		code |= (*bp++ & 0xff) << r_off;
X#else
X		code |= *bp++ << r_off;
X#endif /* NO_UCHAR */
X		r_off += 8;
X		bits -= 8;
X	}
X	/* high order bits. */
X	code |= (*bp & rmask[bits]) << r_off;
X#endif /* vax */
X	offset += n_bits;
X
X	return code;
X}
X
X#ifdef DEBUG
X
Xstatic void _fprintf(FILE *fi, const char *ctl, ...) { }
X
Xstatic /*volatile*/ void
Xprintcodes(void)
X{
X	/*
X	 * Just print out codes from input file.  For debugging.
X	 */
X	code_int code;
X	int col = 0, bits;
X
X	bits = n_bits = INIT_BITS;
X	maxcode = MAXCODE(n_bits);
X	free_ent = ((block_compress) ? FIRST : 256);
X	while ((code = getcode()) >= 0) {
X		if ((code == CLEAR) && block_compress) {
X			free_ent = FIRST - 1;
X			clear_flg = 1;
X		} else if (free_ent < maxmaxcode)
X			free_ent++;
X		if (bits != n_bits) {
X			_fprintf(stderr, "\nChange to %d bits\n", n_bits);
X			bits = n_bits;
X			col = 0;
X		}
X		_fprintf(stderr, "%5d%c", code,
X			(col+=6) >= 74 ? (col = 0, '\n') : ' ');
X	}
X	_fprintf(stderr, "\n");
X	exit(0);
X}
X
Xstatic int
Xin_stack(register int c, register int stack_top)
X{
X	if ((isprint(c) && c != '\\') || c == ' ') {
X		de_stack[--stack_top] = c;
X	} else {
X		switch(c) {
X		case '\n': de_stack[--stack_top] = 'n'; break;
X		case '\t': de_stack[--stack_top] = 't'; break;
X		case '\b': de_stack[--stack_top] = 'b'; break;
X		case '\f': de_stack[--stack_top] = 'f'; break;
X		case '\r': de_stack[--stack_top] = 'r'; break;
X		case '\\': de_stack[--stack_top] = '\\'; break;
X		default:
X			de_stack[--stack_top] = '0' + c % 8;
X			de_stack[--stack_top] = '0' + (c / 8) % 8;
X			de_stack[--stack_top] = '0' + c / 64;
X			break;
X		}
X		de_stack[--stack_top] = '\\';
X	}
X	return stack_top;
X}
X#endif /* DEBUG */
X
Xstatic void
Xwriteerr(void)
X{
X    ulog(0, "Error while writing to '%s'", WKName);
X    remove(WKName);
X    exit(1);
X}
X
Xstatic void
Xuncompress_news(void)
X{
X    if (freopen(WKName, "w", stdout) == NULL) {
X	ulog(0, "Can't open uncompressed file for output");
X	return;
X    }
X
X    /* Check the magic number */
X
X    if ((getc(stdin)!=(magic_header[0] & 0xFF))
X      || (getc(stdin)!=(magic_header[1] & 0xFF))) {
X	    ulog(0, "input file not in compressed format");
X	    exit(1);
X    }
X    maxbits = getc(stdin);  /* set -b from file */
X    block_compress = maxbits & BLOCK_MASK;
X    maxbits &= BIT_MASK;
X    maxmaxcode = ((code_int)1) << maxbits;
X
X    decompress();
X
X    fclose(stdout);
X    if (freopen(WKName, "r", stdin) == NULL) {
X	ulog(0, "Can't reopen uncompressed file for input");
X	return;
X    }
X    unbatch(NULL);
X}
X
X#undef exit
Xstatic /*volatile*/ void
Xnews_exit(int stat)
X{
X    chdir(homedir);
X    exit(stat);
X}
X
X/*
X *  When debugging RNews, this copied the input file to somewhere else to save
X *  it.
X */
X
Xvoid
Xcopy_uualtspool()
X{
X    char *ident = MakeConfigPath(UUALTSPOOL, "altseqno");
X    FILE *fi;
X    int seqno = 0;
X    int error = 0;
X    char buf[32];
X
X    if (fi = fopen(ident, "r+")) {
X	fscanf(fi, "%d", &seqno);
X	fclose(fi);
X    }
X    if (fi = fopen(ident, "w")) {
X	fprintf(fi, "%d\n", seqno + 1);
X	fclose(fi);
X    } else {
X	ulog(-1, "Unable to update %s\n", ident);
X    }
X
X    sprintf(buf, "ND.%d", seqno);
X    ident = MakeConfigPath(UUALTSPOOL, buf);
X
X    if (fi = fopen(ident, "w")) {
X	int n;
X
X	while ((n = fread(TmpBuf, 1, sizeof(TmpBuf), stdin)) > 0) {
X	    if (fwrite(TmpBuf, 1, n, fi) != n) {
X		ulog(-1, "Error writing to alternate spool!");
X		error = 1;
X		break;
X	    }
X	}
X	fclose(fi);
X
X	/*
X	 *  if error use stdin.  If re-openning of ident fails use stdin.
X	 */
X
X	rewind(stdin);
X	if (error == 0)
X	    freopen(ident, "r", stdin);
X    }
X}
X
END_OF_FILE
if test 21274 -ne `wc -c <'uucp2/src/news/rnews.c'`; then
    echo shar: \"'uucp2/src/news/rnews.c'\" unpacked with wrong size!
fi
# end of 'uucp2/src/news/rnews.c'
fi
echo shar: End of archive 9 \(of 12\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 12 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.