/**********************************************************************
 * ti/ti.h -- header file for ti
 *
 * $Source: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/include/ti/RCS/ti.h,v $
 * $Author: brlewis $
 * $Header: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/include/ti/RCS/ti.h,v 0.1 92/07/01 10:10:34 brlewis Exp Locker: brlewis $
 *
 * Copyright 1990 by the Massachusetts Institute of Technology.
 * For copying and distribution information, see the file
 * "mit-copyright.h".
 **********************************************************************/

/* jms 7/9/92 -- windows-izing begun. */

#include "mit-copyright.h"

#ifndef _TI_H
#define _TI_H

#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ti/etti.h>

#ifdef DEBUG
#define TI_DEBUG(x) com_err x
#else /* DEBUG */
#define TI_DEBUG(x)
#endif /* DEBUG */

#if !defined(MEWEL) && !defined(WINDOWS)
  #define FAR
  typedef char *LPSTR;
  #define HSTR LPSTR
  #define lstrcpy strcpy
  #define TI_DEREFERENCE(handle) (handle)
  #define TI_REMOVE_DEREFERENCE(handle, lp)
#else
  #define TILock	GlobalLock
  #define TIUnlock	GlobalUnlock
  #define TIHND		GHND
  #define TIAlloc	GlobalAlloc
  #define TIFree	GlobalFree
  #define TIHANDLE	GLOBALHANDLE
  #define TIMEM_ZEROINIT GMEM_ZEROINIT
  /* just in case Local... stuff is better, we can switch easily */

  #define TI_DEREFERENCE(handle) (TILock(handle))
  #define TI_REMOVE_DEREFERENCE(handle,lp) \
     (lp ? (TIUnlock(handle), lp = NULL) : 0)
  #define HSTR TIHANDLE
#endif

#define TI_OFFSETS (4)
typedef struct _ti_node
{
  short	  nd_level;
  long    nd_id;
  short   nd_flags;
  short   nd_date;
  HSTR    nd_hdata;
  LPSTR   nd_data;
  u_char  nd_off[TI_OFFSETS];	/* saves 12 bytes per node, about 10% */
} ti_node, FAR *ti_node_LP;
#if defined(MEWEL) || defined(WINDOWS)
typedef TIHANDLE ti_node_H;
#else
  #define ti_node_H  ti_node_LP
#endif

/*** Don't refer to members of ti_node; use macros below ***/

#define ti_settopic(hnd, s)	ti_setdata((hnd), (s), -1)
#define ti_settitle(hnd, s)	ti_setdata((hnd), (s),  0)
#define ti_setsource(hnd, s)	ti_setdata((hnd), (s),  1)
#define ti_setlocker(hnd, s)	ti_setdata((hnd), (s),  2)
#define ti_setfile(hnd, s)	ti_setdata((hnd), (s),  3)
#define TI_NDSTRLIM		(4)

#define ti_level(lpnd)		((lpnd)->nd_level)
#define ti_id(lpnd)		((lpnd)->nd_id)
#define ti_flags(lpnd)    	((lpnd)->nd_flags)
#define ti_date(lpnd)     	((lpnd)->nd_date)
#define ti_topic(lpnd)    	((lpnd)->nd_data)

#define ti_title(lpnd)    	(&(lpnd)->nd_data[(int)(lpnd)->nd_off[0]])
		/* what about (lpnd)->nd_data + (lpnd)->nd_off[0] ? */
#define ti_source(lpnd)		(&(lpnd)->nd_data[(int)(lpnd)->nd_off[1]])
#define ti_locker(lpnd)   	(&(lpnd)->nd_data[(int)(lpnd)->nd_off[2]])
#define ti_file(lpnd)		(&(lpnd)->nd_data[(int)(lpnd)->nd_off[3]])
#define ti_numchild(lpnd) 	((lpnd)->nd_numchild)
#define ti_numparent(lpnd)	((lpnd)->nd_numparent)
#define ti_parent(lpnd, i)	((lpnd)->nd_parent_ptrs[i])
#define ti_child(lpnd, i) 	((lpnd)->nd_child_ptrs[i])

/* flags for nodes */
#define TI_NONSTACK	(1<<0)	/* Tag Used for infinite loop protection */
#define TI_NCALLEDON	(1<<1)	/* Already been passed to a traverse func */
#define TI_NRESOLVED	(1<<2)	/* Have link node-ids been resolved to ptrs? */
#define TI_NFAKE	(1<<3)	/* Created by web_node to keep things happy */
#define TI_NTEXT	(1<<4)	/* This is a document node */
#define TI_NSYSGEN_FN	(1<<5)	/* file name etc to be maintained by server */
#define TI_IMAGE	(1<<6)	/* The node is an image (GIF) */
#define TI_DONT_STAT	(1<<7)	/* don't try to update modify date */
#define TI_SERVER_NODE	(1<<8)	/* a link to another server */

#define ti_ismenu(lpnd)	(ti_file(lpnd)[0] == '\0')
#define ti_isimage(lpnd)	(ti_flags(lpnd) & TI_IMAGE)
#define ti_istext(lpnd)(!ti_ismenu(lpnd) && !ti_isimage(lpnd))

#define TI_FMOTD	1
#define TI_MAX_OPEN	64
#define TI_DEF_HOST	"techinfo"
#define TI_DEF_PORT	"9000"
#define TI_EOM		".\015\012"	/* End of Message */
#define TI_EOM_LEN	3
#define TI_EOLM		"\012.\015\012" /* EOL + EOM */
#define	TI_EOL_LEN	1
#define TI_EOLM_LEN	(TI_EOL_LEN + TI_EOM_LEN)
#define TI_DLM		':'
#define TI_MAXSRVERR	14
#define TI_ABOVE	'1'
#define TI_BELOW	'2'
#define TI_STRINGS	(6)
typedef struct _ti
{
  short links;
  short flags;
  int sock;
  struct sockaddr_in sname;
  HSTR strings[TI_STRINGS];
} TI, FAR *TI_LP;
#if defined(MEWEL) || defined(WINDOWS)
typedef TIHANDLE TI_H;
#else
  #define TI_H  TI_LP
#endif

#define TI_ANYSERVER	((LPSTR) 0)
#define TI_ANYPORT	((LPSTR) 0)

#define ti_host(tp)	((tp)->strings[0])
#define ti_port(tp)	((tp)->strings[1])
#define ti_banner(tp)	((tp)->strings[2])
#define ti_user(tp)	((tp)->strings[3])
#define ti_password(tp)	((tp)->strings[4])
#define ti_source1(tp)	((tp)->strings[5]) /* primary source */

typedef struct _ti_menu
{
  TI_H hti;
  HSTR query;
  short expand;
  HSTR title;
} ti_menu, FAR *ti_menu_LP;
#if defined(MEWEL) || defined(WINDOWS)
  typedef TIHANDLE ti_menu_H, FAR *ti_menu_LPH;
  typedef TIHANDLE ti_menu_HH;
#else
  #define ti_menu_H ti_menu_LP
  typedef ti_menu_H FAR *ti_menu_LPH;
  #define ti_menu_HH ti_menu_LPH;
#endif

/*** Don't refer to members of ti_menu; let library handle them ***/

/* info received with file */
#define TI_MAXMODSTRLEN (80)
typedef struct _ti_recvinfo
{
  int total, sent;
  char modified[TI_MAXMODSTRLEN+1];
} ti_recvinfo;

extern char ti_context[256];
extern int ti_nconnections;
extern TI_H ti_connections[TI_MAX_OPEN];

#define CLEANUP_AND_RETURN(retval) \
  { \
    code = retval; \
    goto CLEANUP; \
  }

/* standard memory check */

#define TI_MEM(foo) if (!(foo)) { *ti_context='\0'; \
                                  CLEANUP_AND_RETURN((long)ENOMEM) }

#if defined(__GNUC__)
#define TI_INLINE inline
#else
#define TI_INLINE
#endif /* __GNUC__ */

/* prototypes or function declarations */
#include <ti/libti-ptypes.h>

#endif /* _TI_H */
