\documentstyle{article}
\begin{document}
\setlength{\parindent}{0mm}
\setlength{\parskip}{1 ex}

\def\tilde{\~{ }}

%
% Formats for various types of identifiers.
%

\def\filename{\em}
\def\proc{\em}

%
% Change page heading to correspond to current definitions.
%

%@textform(setheading=[
%    @pageheading(odd,immediate,
%	right="\begin{box,boxtype standardrowlines, size 12)@parm(text)@end(box)@\")
%    @pageheading(even,immediate,
%	left="\begin{box,boxtype standardrowlines,size 12)@parm(text)@end(box)@\")])

\newcommand{\addtomargins}[1]{
	\addtolength{\oddsidemargin}{#1}
	\addtolength{\evensidemargin}{#1}
}

%\newenvironment{arglist}
\def\arglist
{	% ``arglist'' begin text
	Arguments:
	\begin{list}
		{ }
		{
			\setlength{\rightmargin}{\leftmargin}
			\setlength{\itemsep}{0mm}
		}
	\def\arg##1##2{ \item[\ \ {\bf ##1} (##2)]\mbox{}\\}
%	\addtomargins{4 em}
%	\def\arg##1##2{\addtomargins{-2 cm}{\bf ##1} (##2)\\}
}
\def\endarglist
{
	\end{list}
}

%
%

\newcommand{\decl}[1]{
	\vspace{2 ex}
	Entry: {\bf #1}\\
	% should set page headings here
}

\title{Discuss (subroutine foo)}
\author{Ken Raeburn}
\date{Printed: \today}

% ****************************************************************

\maketitle
\newpage

\section{Subroutines}

{\large This document is a draft, and is most definitely incomplete.}

Please keep in mind that the interfaces to these routines may change
in form.  In particular, handling of error-code return values may
change.  Some subroutine names may change for parity as extra
functionality is added to the library.  Many others will change for
conformance to the pattern that all Discuss library routines have
names which begin with ``dsc\_''.

\subsection{Reading and writing transactions.}

These routines are responsible for the interaction between the
user-level program and the Discuss servers.

One of the key data structures used by these routines (and others) is
the name\_blk structure, which is defined in {\filename dsname.h} as:

\begin{verbatim}
typedef struct {
    char *hostname;
    char *pathname;
    char *user_id;
    char **aliases;
    char *spare;   /* "reserved for future expansion" */
    int status;
    int date_attended;
    int last;
} name_blk;
\end{verbatim}

The values currently defined which may be used in the ``status'' word
(also defined in {\filename dsname.h)} are:

\begin{verbatim}
#define DSC_ST_CHANGED (0x0001)
#define DSC_ST_DELETED (0x0002)
\end{verbatim}

Other useful typedef's are:

%
%       DOCUMENT THESE!!!!!!!!!
%

\begin{verbatim}
/* "types.h", included by "interface.h" */
typedef int trn_nums;	/* what a transaction number could be */
typedef int date_times;	/* time format */
typedef short bool;
typedef char *mtg_names; /* what a meeting name is */
typedef char *pathnames; /* Fixed, or what? */
typedef int faddr;	/* addr in a file (absolute offset) */
typedef short slen;	/* length of a string */

/* "interface.h" */
typedef struct {
    int version;		 /* version of this structure */
    trn_nums current;	 /* trans # of this transaction */
    trn_nums prev;		 /* trans # of previous non-deleted trans */
    trn_nums next;		 /* etc, etc. */
    trn_nums pref;
    trn_nums nref;
    trn_nums fref;
    trn_nums lref;

    int chain_index;	/* index of trn in chain. Fref is 1 */
    date_times date_entered; /* date/time entered */
    int num_lines;	/* # lines in transaction */
    int num_chars;	/* # chars in transaction */
    char *subject;	/* subject of transaction */
    char *author;	/* author of transaction */
} trn_info;

typedef struct {
    int version;		/* version of this structure */
    pathnames location;		/* location of actual meeting */
    mtg_names long_name;	/* long name of meeting */
    char *chairman;		/* #1 chairman of meeting */
    trn_nums first,last;	/* first & last trns of mtg */
    trn_nums lowest,highest;	/* first & last non-dl trns */

    date_times date_created;	/* date meeting created */
    date_times date_modified;	/* last modification of meeting */

    bool public_flag;		/* if mtg is public */
    char *access_modes;		/* Access modes we have to this mtg. */
} mtg_info;

\end{verbatim}

There is also another package, called ``tfile'', in use, which allows
for a stdio-like I/O interface with the added functionality of
callback procedures called from within the library.  This is described
in another section.

\decl{dsc\_announce\_mtg}

Function: This procedure places a specially-formatted announcement of
a Discuss meeting into another Discuss meeting.  These announcement
transactions are the common means of sharing information concerning
new meetings.

Syntax:\begin{verbatim}
int dsc_announce_mtg ();

(void) dsc_announce_mtg (nbpsrc, nbpdest, public, tf, trn_no,
			 code_ptr);
\end{verbatim}

\begin{arglist}
\arg{nbpsrc}{name\_blk *}
is the new meeting which is to be announced.

\arg{nbpdest}{name\_blk *}
indicates the meeting in which the announcement is to be placed.

\arg{public}{int}
is non-zero if the meeting is to be announced as ``public''.

\arg{tf}{tfile}
is the source of the text for the main body of the announcement.

\arg{trn\_no}{int *}
will contain, on successful return, the transaction number of the new
transaction in the announcement meeting.

\arg{code\_ptr}{int *}
will contain a standard error code on return.  It will be zero if no
error occurred, non-zero otherwise.

\end{arglist}

\decl{dsc\_add\_trn}

Function:  Dsc\_add\_trn adds a new transaction to a Discuss meeting,
either as the initial transaction in a new chain, or as a reply to a
previous transaction.

Syntax:\begin{verbatim}
int dsc_add_trn();

(void) dsc_add_trn(nbp, text, subject, reply_trn, result_trn,
		   code_ptr)
\end{verbatim}

\begin{arglist}
\arg{nbp}{name\_blk *}

\arg{text}{tfile}

\arg{subject}{char *}

\end{arglist}

\decl{dsc\_get\_trn\_info}

Syntax:\begin{verbatim}
int dsc_get_trn_info();

(void) dsc_get_trn_info(nbp, trn, info, code_ptr)
\end{verbatim}

\decl{dsc\_delete\_trn}

Syntax:\begin{verbatim}
int dsc_delete_trn();

(void) dsc_delete_trn(nbp, trn, code_ptr)
\end{verbatim}

\decl{dsc\_retrieve\_trn}

Syntax:\begin{verbatim}
int dsc_retrieve_trn();

(void) dsc_retrieve_trn(nbp, trn, code_ptr)
\end{verbatim}

\decl{dsc\_get\_mtg\_info}

Syntax:\begin{verbatim}
int dsc_get_mtg_info();

(void) dsc_get_mtg_info(nbp, info, code_ptr)
\end{verbatim}

\decl{dsc\_get\_trn}

Syntax:\begin{verbatim}
int dsc_get_trn();

(void) dsc_get_trn(nbp, trn, dest, code_ptr)
\end{verbatim}

\decl{dsc\_remote\_mtg}

Syntax:\begin{verbatim}
int dsc_remote_mtg();

(void) dsc_remote_mtg(nbp, code_ptr)
\end{verbatim}

\decl{dsc\_updated\_mtg}

Syntax:\begin{verbatim}
int dsc_updated_mtg();

(void) dsc_updated_mtg(nbp, updated, code_ptr)
\end{verbatim}

\decl{dsc\_whoami}

Syntax:\begin{verbatim}
int dsc_whoami();

(void) dsc_whoami(nbp, ident, code_ptr)
\end{verbatim}

\subsection{Access control in Discuss meetings.}

Structures used:

\begin{verbatim}
typedef struct _acl_entry {
    char *principal;	/* The principal */
    char *modes;	/* The allowed modes */
} acl_entry;

typedef struct _acl {
    int acl_length;
    acl_entry *acl_entries; /* Members of list (gets realloc'ed) */
} Acl;
\end{verbatim}

\decl{dsc\_get\_acl}

Syntax:\begin{verbatim}
int dsc_get_acl();

(void) dsc_get_acl(nbp, code_ptr, list)
\end{verbatim}

\decl{dsc\_get\_access}

Syntax:\begin{verbatim}
int dsc_get_access();

(void) dsc_get_access(nbp, principal, modes, code_ptr)
\end{verbatim}

\decl{dsc\_set\_access}

Syntax:\begin{verbatim}
int dsc_set_access();

(void) dsc_set_access(nbp, principal, modes, code_ptr)
\end{verbatim}

\decl{dsc\_delete\_access}

Syntax:\begin{verbatim}
int dsc_delete_access();

(void) dsc_delete_access(nbp, principal, code_ptr)
\end{verbatim}

\subsection{Interface to user's {\filename .meetings} file.}

These routines provide an interface to the user's {\filename
.meetings} file, where Discuss stores all of the information it has
concerning meetings the user is interested in.  This file is stored in
a format not unlike the {\filename /etc/passwd} file, containing
alphanumeric and numeric fields separated by colons.

There is much functionality which is not yet provided by this small
set of routines, and some do not yet conform to the ``dsc\_'' standard
of subroutine naming used elsewhere in the library.

\decl{dsc\_expand\_mtg\_set}

Function: This procedure expands a Discuss meeting name (possibly a
starname) into a list of names, in the context of the users'
{\filename .meetings} file.

Syntax:\begin{verbatim}
void dsc_expand_mtg_set();

dsc_expand_mtg_set (user_id, mtgname, set, num, result)
\end{verbatim}

\begin{arglist}
\arg{user\_id}{char *}
is the name of the user whose {\filename .meetings} file should be
referenced for the expansion of the supplied name.  If this value is
NULL, the user's own {\filename .meetings} file is used.  (Input)

\arg{mtgname}{char *}
is the meeting name (or starname) to be expanded.  (Input)

\arg{set}{name\_blk **}
indicates where the pointer to the resulting values should be stored.
These values are allocated by this routine, and should be freed when
no longer needed.  (Output)

\arg{num}{int *}
indicates where the number of expanded names should be returned.
(Output)

\arg{result}{int *}
is the location of a standard system error code, to be filled in by
this routine.  (Output)

\end{arglist}

This routine performs the first portion of the lookup, translating
mtgname in the context of the user\_id into zero or more name\_blk
structures.

Set is assigned the address of an array of name\_blk structures; this
array is allocated by this routine and should be freed when no longer
needed.  Num is set to the number of matches found for the name
mtgname among meeting long\_names and the user's aliases for meetings.
Result is set to zero if the routine executes successfully (this
includes the case of no matches for mtgname), non-zero otherwise.

\decl{dsc\_update\_mtg\_set}

Function: This procedure updates the entries in a {\filename .meetings}
file to correspond with the data supplied.

Syntax:\begin{verbatim}
void dsc_update_mtg_set();

dsc_update_mtg_set (user_id, set, num, result)
\end{verbatim}

\begin{arglist}
\arg{user\_id}{char *}
as above.

\arg{set}{name\_blk *}
contains the data to be stored in the user's {\filename .meetings}
file.

\arg{num}{int}
indicates how many name\_blk structures are supplied.

\arg{result}{int *}
as above.

\end{arglist}

This routine updates the user's {\filename .meetings} file information,
replacing the entries already there for the specified meetings.
Information about meetings not supplied to this routine is unchanged.
If a name\_blk structure supplied has the ``deleted'' flag set, the
meeting info will not be retained in the new version of the
{\filename .meetings} file.

The {\filename .meetings} file is updated by writing a new file,
{\filename .meetings\tilde}, containing the new data, and replacing the
original file with an atomic rename() system call.

\decl{dsc\_get\_mtg}

This routine is available for use when a single expansion of a name is
desirable.  It returns the first expansion of the starname, if there
is one.  ({\bf BUG:}  This should probably return an entry only if it is
a unique match.)

Syntax:\begin{verbatim}
int dsc_get_mtg();

(void) dsc_get_mtg(user_id, name, nbp, result)
\end{verbatim}

\begin{arglist}
\arg{user\_id}{char *}
as above.  (Input)

\arg{name}{char *}
the name to be expanded.  (Input)

\arg{nbp}{name\_blk *}
the location in which to store the name\_blk record, if any is found.
(Output)

\arg{result}{int *}
as above.  (Output)

\end{arglist}

\decl{find\_rc\_filename}

Find\_rc\_filename will attempt to locate the user's own
{\filename .meetings} file.

Syntax:\begin{verbatim}
int find_rc_filename();

code = find_rc_filename();
\end{verbatim}

\begin{arglist}
\arg{code}{int}
indicates whether this routine succeeded in finding a writable
{\filename .meetings} file.

\end{arglist}

	This function requires that the user have an entry in the
local {\filename /etc/passwd} file; this entry is looked up once and
cached for reference in future calls.

	The order of search is: {\filename \$MEETINGS} environment
variable; {\filename \$HOME/.meetings}; {\filename \tilde
user/.meetings}.  If the {\filename MEETINGS} environment variable is
set, the home directory will not be checked; if {\filename HOME} is
defined, the password file entry will not be used to locate the file
(though the user name from the password file is retained as an
identifier).

	This routine only accepts a file which are writable by the
user.  If the file found is not writable, an error is returned.

\subsection{Tfiles}

A bit of a crock to get around stdio not providing call-back I/O
modules.  The tfile generation routines and some pre-defined routines
are described here.

Definitions used:

\begin{verbatim}
struct trecord {
    int (*proc)();		/* file proc */
    int size;			/* file size */
    char *infop;		/* pointer to misc info */
    int info;
};

typedef struct trecord *tfile;

#define TFOPEN 1
#define TFCLOSE 2
#define TFREAD 3
#define TFWRITE 4
#define TFDESTROY 5
#define TFCONTROL 6

/* TF Control orders (start high just for fun) */

#define TFC_FORCE_NL 15
\end{verbatim}

\decl{tcreate}

Function:  Creates a tfile object which uses a specified procedure to
perform its operations.

Syntax:\begin{verbatim}
tfile tcreate();

tf = tcreate(tfs, infop, info, proc);
\end{verbatim}

\begin{arglist}
\arg{tfs}{int}
the size of the tfile. (???)

\arg{infop}{char *}

\arg{info}{int}

\arg{proc}{int (*)()}
the procedure to be called in order to perform operations on the
tfile.
\end{arglist}

\end{document}
