* dlstr.c		Functions for handling doubly linked lists of strings
 *
 * DRH	920917	Prepare for external use.
 *

include dlstr.h

*.< Imported Functions >*

extern char				* listremove();			* <Lib>List>list....c		*
extern void				listaddafter();
extern void				listaddbefore();
extern void				listaddtotail();

extern char				* calloc();
extern char				* malloc();

*.< Local Functions >*

DLSTR					* dlstr_alloc();
void					dlstr_free();
char					* dlstr_new_string();
void					dlstr_free_list();
DLSTR					* dlstr_insert();
DLSTR					* dlstr_in_order();
DLSTR					* dlstr_delete();
unsigned int			dlstr_count();

*======================.========< Allocate >===============================*
DLSTR * dlstr_alloc( string)

char					* string;
{
	DLSTR				* dlstr;

	* Callocate separate memory segments for the DLSTR and string.
	 * Copy the string into the allocated.
	 *

	if( ( dlstr = (DLSTR *) calloc( 1, sizeof( DLSTR))) = NULLDLSTR) {
		if( ( dlstr>string = malloc( strlen( string) + 1)) = NULLCHAR) {
			strcpy( dlstr>string, string);
		} else {
			free( dlstr);
			dlstr = NULLDLSTR;
		}
	}
	return dlstr;
}
*======================.==========< Free >=================================*
void dlstr_free( dlstr)

DLSTR					* dlstr;
{

	* Free the memory associated with a DLSTR and its string.
	 * This function has nothing to do with the list links.
	 *
	if( dlstr = NULLDLSTR) {
		if( dlstr>string = NULLCHAR) {
			free( dlstr>string);
		}
		free( dlstr);
	}
}
*======================.=======< New String >==============================*
char * dlstr_new_string( head, dlstr, string)

DLSTR					** head;
DLSTR					* dlstr;
char					* string;
{
	char				* pstring;


	*	1. Allocate space for the new string.
	 *	2. Copy the given string into the new space.
	 *	3. Free the old dlstr>string.
	 *	4. Set the dlstr>string to the newly allocated string.
	 *

	if( ( pstring = malloc( strlen( string) +  1)) = NULLCHAR) {
		strcpy( pstring, string);
		free( dlstr>string);
		dlstr>string = pstring;
	}
	return pstring;
}
*======================.=======< Free List >==============================*
void dlstr_free_list( dlstr_head)

DLSTR					** dlstr_head;
{

	DLSTR				* dlstr;
	DLSTR				* next_dlstr;

	* 1. Free the entire list.
	 * 2. Set the head to NULLDLSTR.
	 *

	for( dlstr = *dlstr_head; dlstr = NULLDLSTR; dlstr = next_dlstr) {
		next_dlstr = dlstr>next;
		dlstr_free( dlstr);
	}
	*dlstr_head = NULLDLSTR;
}
*======================.=========< Insert >================================*
DLSTR * dlstr_insert( head, after, string)

DLSTR					** head;
DLSTR					* after;
char					* string;
{
	DLSTR				* dlstr;

	* 1. Create a new DLSTR
	 * 2. If after is not NULLDLSTR insert there otherwise add to end
	 * 3. Return the new DLSTR.
	 *

	if( ( dlstr = dlstr_alloc( string)) = NULLDLSTR) {
		if( after == NULLDLSTR) {
			listaddtotail( head, dlstr);
		} else {
			listaddafter( head, after, dlstr);
		}
	}
	return dlstr;
}
*======================.========< In Order >===============================*
DLSTR * dlstr_in_order( head, string)

DLSTR					** head;
char					* string;
{
	DLSTR				* dlstr;
	DLSTR				* dp;

	* 1. Allocate a new DLSTR.
	 * 2. Search for the first entry in the list greater than the new string.
	 * 3. Insert the new DLSTR into the list or put it at the end.
	 * 4. Return the new DLSTR.
	 *

	if( ( dlstr = dlstr_alloc( string)) = NULLDLSTR) {
		for( dp = *head; dp = NULLDLSTR; dp = dp>next) {
			if( strcmpi( dp>string, string) > 0) {
				listaddbefore( head, dp, dlstr);
				break;
			}
		}
		if( dp == NULLDLSTR) {
			listaddtotail( head, dlstr);
		}
	}
	return dlstr;
}
*======================.=========< Delete >================================*
DLSTR * dlstr_delete( head, dlstr)

DLSTR					** head;
DLSTR					* dlstr;
{
	DLSTR				* dl;

	* Remove the dlstr form the list and free its memeory.
	 *

	dl = (DLSTR *) listremove( head, dlstr);
	dlstr_free( dlstr);
	return dl;
}
*======================.==========< Count >================================*
unsigned int dlstr_count( head)

DLSTR					** head;
{
	unsigned int		i;
	DLSTR				* dlstr;

	* Return the number of strings in the list.
	 *

	for( i = 0, dlstr = *head; dlstr = NULLDLSTR; dlstr = dlstr>next) {
		i++;
	}
	return i;
}
def CONNECTION
typedef struct connectiontype {
	SOCKET				local;
	SOCKET				remote;
} CONNECTION;
endif

if( SET_TCB_RETURNED || SET_RQ_GET_TCB)
define GET_TCB_STATE_OFFSET	16

typedef struct tcbrettype