/*
 *	Name:				xferqint.h
 *
 * Description:	Private include file for xferq.library
 *
 * Copyright:		1992-1993 by David Jones.
 *
 * Distribution:
 *		This program is free software; you can redistribute it and/or modify
 *		it under the terms of the GNU General Public License as published by
 *		the Free Software Foundation; either version 2 of the License, or
 *		(at your option) any later version.
 *
 *		This program is distributed in the hope that it will be useful,
 *		but WITHOUT ANY WARRANTY; without even the implied warranty of
 *		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *		GNU General Public License for more details.
 *
 *		You should have received a copy of the GNU General Public License
 *		along with this program; if not, write to:
 *
 *				The Free Software Foundation		David Jones
 *				675 Mass Ave							6730 Tooney Drive
 *				Cambridge, MA							Orleans, Ontario
 *				02139										K1C 6R4
 *				USA										Canada
 *
 *	Usenet:	gnu@prep.ai.mit.edu					dej@qpoint.ocunix.on.ca
 *	Fidonet:												1:163/109.8
 *
 *		$Log: $
 *
 */

#ifndef XFERQINT_H
#define XFERQINT_H

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#ifndef EXEC_LISTS_H
#include <exec/lists.h>
#endif

#ifndef EXEC_NODES_H
#include <exec/nodes.h>
#endif

#define	USE_PRIVATE_POOL
#ifndef USE_PRIVATE_POOL
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#endif

#ifndef UTILITY_TAGITEM_H
#include <utility/tagitem.h>
#endif

/*
*	Work node entry
*		Work nodes are used to hold attributes of files queued for
*		transmission.
*/

struct WorkNode {
	struct Node node;				/* ln_Name and ln_Pri are valid */
	UWORD userFlags;				/* User accessible flags */
	char *asname;					/* Name to send file as */
	struct SiteNode *site;		/* Back pointer to site node */
	struct NetAddress *addr;	/* Address that node should be queued to */
	UBYTE sysFlags;				/* System-use flags */
	UBYTE status;					/* Transmission status of node */
};

/*
*	System flags
*/

#define	XQ_INQUEUE		64			/* Node is in queue */
#define	XQ_LOCKED		128		/* Node is locked by another */


/*
*	Site entry
*		The queue database consists of a linked list of site nodes, one
*		per site.  The site node is a linked list of work nodes.
*/

struct SiteNode {
	struct MinNode node;			/* Link into global structure */
	struct NetAddress *site;	/* Address that site node refers to */
	struct MinList workList;	/* List of work nodes queued to site */
	UWORD flags;					/* See below */
	UWORD numSessions;			/* Number of sessions up to node */
	UWORD numLocks;				/* Number of nested LockMailer() calls */
};

#define	XQSITE_DIRTY		1		/* needs to be written to disk */
#define	XQSITE_UNREAD		2		/* needs to be read in from disk */

/*
*	Error handling
*		Errors are maintained on a per-process basis.  A list of these
*		structures keeps the error info.  In addition, the library
*		tracks which users are ARexx and which are not through this
*		structure.
*/

struct ENode {
	struct MinNode node;
	struct Task *task;
	ULONG error;
	UWORD flags;
};

#define	EN_ISREXX		1					/* Process is spawned by ARexx */

/*
*	Session structures
*		A session cookie is a linked list of session nodes.  Each session
*		node points to an address.  Sessions can be walked with the walk
*		structure, which allows for fancy operations.
*/

struct Session {
	struct Node node;				/* Link into global structure */
	UWORD flags;					/* See below */
	struct MinList sessList;	/* List of sites */
};

struct SessNode {
	struct MinNode node;			/* Link into session cookie */
	struct NetAddress *addr;	/* Address to which session is up */
};

struct ExtSessWalk {
	struct NetAddress *na;
	struct SiteNode *sn;
	BOOL (*func)(struct ExtSessWalk *);
};


/*
*	Variable lists
*
*	The SNVal structure is a combination string/numeric data item where
*	either or both of the string and numeric fields may be valid.
*	A VarList is a linked list of named SNVal structures.
*/

struct SNVal {
	char *str;						/* String value */
	long num;						/* Numeric value */
	short flags;					/* Type(s) of value */
};

#define	VAR_NUMERIC		1		/* numeric field is valid */
#define	VAR_STRING		2		/* string field is valid */
	
struct VarListEntry {
	struct Node node;				/* Link to varlist structure */
	short nameLen;					/* Length of name */
	struct SNVal val;				/* Value of variable */
};

struct VarList {
	struct MinList list;
};


/*
*	Address structure
*/

struct NetAddress {
	LONG type;						/* One of the XQNT_... types */
	char *userName;				/* Name of user */
	struct {
		struct {
			char *domain;			/* Fidonet */
			char *zone;				/* Numeric quantities are stored as strings */
			char *net;				/* to facilitate templates */
			char *node;
			char *point;
		} fido;
		char *machine;				/* UUCP machine name */
		char *fqda;					/* Fully qualified domain address */
		char *text;					/* Generic text */
	} addr;
};

#define	ADDR_MAX			8		/* Max. fields in address */

#define	ET_ERROR			0
#define	ET_NUMBER		1
#define	ET_ALPHA			2

/*
*	Objects
*		The following structure precedes all objects in memory.  It allows
*		for multiple use and type identification.
*/

struct XfqObject {
	UWORD useCount;				/* number of users */
	UWORD type;						/* type of object */
};

struct SizedObject {				/* allows access to size */
	LONG link;
	ULONG size;
	UWORD useCount;
	UWORD type;
};

#define ObjectType(x) ((struct XfqObject *)(x))[-1].type
#define ObjectSize(x) ((struct SizedObject *)(x))[-1].size

/*
 *		Level 2/3 private data structures.
 *
 *	What follows are field descriptions of objects that can be examined
 * or modified.  The structures relate an ARexx field name to an offset
 * in the structure having a specified type.
 */

struct FieldDesc {
	char *name;							/* Name of field (for ARexx) */
	Tag tag;								/* Tag item for field */
	short type;							/* Type of field */
	short offset;						/* Offset into structure */
};

#define	XQO_BYTE		256			/* Signed byte */
#define	XQO_WORD		257			/* Signed word */
#define	XQO_LONG		258			/* Long */
#define	XQO_NUMSTR	259			/* KLUDGE string <-> number */

#define	XQO_OBJECT	128

#define	XODIP_OK			0			/* Data xfer OK */
#define	XODIP_NOTFOUND	1			/* Item not found */
#define	XODIP_ERROR		2			/* Conversion error */

/*
 * All objects have the following descriptor to allow efficient
 * examines, modifies and copies.
 */

struct ObjectDesc {
	/* Level 2 */
	char *abbr;							/* Abbreviation for ARexx cookies */
	short headSize, fieldSize;		/* Size of base + elements */
	void (*postCreate)(void *);	/* Function to call after create */
	void (*preDrop)(void *);		/* Function to call before dropping */
	/* Level 3 */
	struct FieldDesc *fields;		/* Description of fields */
	BOOL (*preExamine)(void *);	/* Function to call before examine */
	BOOL (*postExamine)(void *);	/* Function to call after examine */
	BOOL (*preModify)(void *);		/* Function to call before modify */
	BOOL (*postModify)(void *);	/* Function to call after modify */
};

/*
*	Tags for all functions
*/

#define	XQ_WNBase		(XQ_OBASE + 0)		/* Base of WorkNode tags */
#define	XQ_ADBase		(XQ_OBASE + 16)	/* Base of Address tags */
#define	XQ_SSBase		(XQ_OBASE + 32)	/* Base of session tags */
#define	XQ_DeathKiss	(XQ_BASE + 64)		/* Shut down NOW!!! */
#define	XQ_GetCore		(XQ_BASE + 65)		/* Get memory list */

/*
*	Internal functions
*/

void InitMemory(void);
void DropMemory(void);
#ifdef USE_PRIVATE_POOL
void *AllocMemory(ULONG);
void FreeMemory(void *);
#else
#define	AllocMemory(x) AllocVec(x, MEMF_PUBLIC)
#define	FreeMemory(x) FreeVec(x)
#endif
void *AllocObject(ULONG, ULONG);	/* Used in error.c */
void *DupObject(void *);

char *CopyStringN(char *, ULONG);
char *CopyString(char *);
char *NeedString(char *, ULONG);
BOOL ExamObject(void *, short (*func)(), void *);
void *ModifyObject(void *, short (*func)(), void *, BOOL);
BOOL ExamObjectVarList(void *, struct VarList *);
void *ModifyObjectVarList(void *, struct VarList *);

void NewSNVal(struct SNVal *);
void SetSNValNum(struct SNVal *, long);
BOOL SetSNValStr(struct SNVal *, char *, int);
BOOL GetSNValNum(struct SNVal *, long *);
char *GetSNValStr(struct SNVal *);
void CopySNVal(struct SNVal *, struct SNVal *);

struct Node *FindNameNoCase(struct MinList *, UBYTE *);
struct VarList *NewVarList(void);
void EmptyVarList(struct VarList *vl);
void DropVarList(struct VarList *vl);
BOOL AddVarListNum(struct VarList *, char *, int, long);
BOOL AddVarListStr(struct VarList *, char *, int, char *, int);
BOOL GetVarListNum(struct VarList *, char *, int, long *);
struct VarListEntry *FindVarList(struct VarList *, char *, int);
char *GetVarListStr(struct VarList *, char *, int);
struct VarList *CopyVarList(struct VarList *);
short GetNumber(char *string, short base, short maxLen, long *num);
short PutNumber(char *string, short base, short maxLen, long num);
char *MakeString(char *string, char *template, struct VarList *list);
BOOL ScanString(char *string, char *template, struct VarList *list);
int GetAddrElement(char **, BOOL);

void InitErrors(void);
ULONG *PeekError(void);
struct ENode *FindENode(BOOL);
void DropENode(struct ENode *);
void Error(long);
void SetErrorTags(struct TagItem *);

void InitAddress(void);
BOOL CanonAddress(struct NetAddress *);

BOOL PreExamWork(struct WorkNode *);
BOOL PostExamWork(struct WorkNode *);
BOOL PreModifyWork(struct WorkNode *);
BOOL PostModifyWork(struct WorkNode *);
void SessionDownQueue(struct SiteNode *);
struct SiteNode *FindSiteQueue(struct NetAddress *);
struct SiteNode *NewSiteQueue(struct NetAddress *);
void InitQueue(void);
void DropQueue(void);
void DropSiteNode(struct SiteNode *);
BOOL AnyDirty(void);

void PostCreateSession(struct Session *);
void PreDropSession(struct Session *);

void ScanQueue(void);
void ReadQueue(struct SiteNode *);
BOOL WriteQueue(struct ExtSessWalk *);
char *FullPath(char *);
ULONG TruncateFile(char *);
void ReadConfig(void);

void InitRexx(void);

#ifdef DEBUG
void kprintf(const char *, ...);
int GetCount(void *);
void CheckCount(char *, void *, int);
#endif

ULONG __asm CallHookRes(register __a0 struct Hook *, register __a2 void *,
	register __a1 void *, register __a4 void *);

#endif /* XFERQINT_H */
