home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
spxdos.exe
/
SUPPORT.C
< prev
Wrap
Text File
|
1995-01-27
|
12KB
|
480 lines
/****************************************************************************
** File: Support.C
**
** Desc: Sample SPX chat program.
**
** This Sample code demonstrates how to set up and use SPX
** communications to communicate between 2 nodes.
**
**
**
**
** DISCLAIMER
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
** Programmers:
**
** Ini Who Firm
** -----------------------------------------------------------------------
** TDOC Technical Documentation Team
** KLB Karl Bunnell Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 10-25-88 TDOC First code.
** 01-27-95 KLB Ported this example to the NetWare Client SDK
*/
/****************************************************************************
** Include headers, macros, function prototypes, etc.
*/
/*------------------------------------------------------------------------
** MACROS
*/
#define NWDOS
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
/*------------------------------------------------------------------------
** NetWare
*/
#include <nwcalls.h>
#include <nwipxspx.h>
#include <ctype.h>
#include "chat.h"
/*------------------------------------------------------------------------
** GLOBALS
*/
ECB sendECB[NUM_SEND_ECBS], *ECBqueue[NUM_RECEIVE_ECBS];
SPXHeader sendHeader[NUM_SEND_ECBS];
WORD SPXConnectionNumber, Socket = SESSION_SOCKET, connectionID,
preferredConnectionID = 0, listeningConnection;
BYTE immediateAddress[6], networkNumber[4];
CONNECTION_INFO connectionInfo[44];
char OutChars[NUM_SEND_ECBS], character,
hello[] = " wants to CHAT. To answer, type HELLO ";
int RECEIVE_FLAG = FALSE, ACTIVE_CONNECTION = 1;
extern int sendRow, sendCol, receiveRow, receiveCol;
NETWORK_NODE destNode, callNode;
void SetUpSendECB();
void SetUpReceiveECBs();
void SendPacket();
void TearDownConnection();
ECB *SetUpInitialECB();
void SendMessage();
void PrintCharacter();
int PollForMessage();
void ListenESR();
extern void far ESRHandler();
extern void Update();
extern void ScrollUp();
extern void SetCursor();
extern DeleteChar();
extern NWCONN_HANDLE connHandle;
ECB *SetUpInitialECB()
{
static ECB initialECB;
static SPXHeader initialHeader;
unsigned transportTime;
NETWORK_ADDR iNetAddress;
BYTE immediateAddress[6];
WORD mysocket;
NWGetInternetAddress (connHandle, listeningConnection, (BYTE *)&iNetAddress);
memcpy(&destNode, iNetAddress.node, 6);
memcpy(&networkNumber, iNetAddress.network, 4);
/* Put the destination header in the address */
memcpy(initialHeader.destination.network, networkNumber, 4);
memcpy(initialHeader.destination.node, &destNode, 6);
memcpy(&initialHeader.destination.socket, &Socket, 2);
initialHeader.packetType = 5;
initialHeader.length = IntSwap(sizeof(SPXHeader));
/* Now initialzie your initial ECB */
initialECB.socketNumber = Socket;
initialECB.inUseFlag = 0;
initialECB.ESRAddress = 0; /* no event service routine, just poll */
initialECB.fragmentCount = 1;
initialECB.fragmentDescriptor[0].address = &initialHeader;
initialECB.fragmentDescriptor[0].size = sizeof(initialHeader);
return( (ECB *)&initialECB );
}
void SetUpReceiveECBs()
{
int i;
char *inChar;
ECB *receiveECB;
SPXHeader *receiveHeader;
for ( i = 0; i < NUM_RECEIVE_ECBS; i++ )
{
if( (receiveECB = (ECB *)calloc(1,sizeof(ECB)) ) == (ECB *)NULL )
Error("Out of memory during packet allocation",0);
if( (receiveHeader = (SPXHeader *)calloc(1,sizeof(SPXHeader)) ) == (ECB *)NULL)
Error("Out of memory during packet allocation",0);
if ( (inChar = (char *)calloc(1,sizeof(char)) ) == (ECB *)NULL)
Error("Out of memory during packet allocation",0);
receiveHeader->packetType = (char)5;
receiveHeader->length = IntSwap(sizeof(SPXHeader));
receiveECB->ESRAddress = (void (far *)())ESRHandler;
receiveECB->socketNumber = Socket;
// memcpy(receiveECB->immediateAddress, &destNode, 6);
receiveECB->fragmentCount = 2;
receiveECB->fragmentDescriptor[0].address = receiveHeader;
receiveECB->fragmentDescriptor[0].size = sizeof(SPXHeader);
receiveECB->fragmentDescriptor[1].address = inChar;
receiveECB->fragmentDescriptor[1].size = sizeof(char);
SPXListenForSequencedPacket (receiveECB);
}
}
void SetUpSendECB()
{
int i;
for (i = 0; i < NUM_SEND_ECBS; i++)
{
/* Fill in your address */
IPXGetInternetworkAddress(sendHeader[i].source.network); /* includes the source node */
memcpy( &sendHeader[i].source.socket, &Socket, 2);
/* Fill in the destination address */
memcpy(sendHeader[i].destination.network, networkNumber, 4);
memcpy(sendHeader[i].destination.node, &destNode, 6);
memcpy(&sendHeader[i].destination.socket, &Socket, 2);
sendHeader[i].length = IntSwap(sizeof(SPXHeader));
sendHeader[i].packetType = 5;
/* Now initialize the Send ECBs */
sendECB[i].ESRAddress = 0; /* no routine, just polling */
sendECB[i].inUseFlag = 0;
sendECB[i].fragmentCount = 2;
sendECB[i].socketNumber = Socket;
// memcpy(sendECB[i].immediateAddress, &destNode, 6);
sendECB[i].fragmentDescriptor[0].address = (sendHeader + i);
sendECB[i].fragmentDescriptor[0].size = sizeof(SPXHeader);
sendECB[i].fragmentDescriptor[1].address = (OutChars + i);
sendECB[i].fragmentDescriptor[1].size = sizeof(char);
}
}
int PollForPacket()
{
BYTE dataType;
char ch, *charPtr;
static int out;
if (RECEIVE_FLAG > 0)
{
/* Set the queue pointer */
if (++out >= 20)
out = 0;
/* Get the data type */
dataType = (BYTE)( ((SPXHeader *)ECBqueue[out]->fragmentDescriptor[0].address)->dataStreamType);
if (dataType == TERMINATING_PACKET )
{
Update("Connection has been terminated");
return(0);
}
/* Get the character */
charPtr = (char *)(ECBqueue[out]->fragmentDescriptor[1].address);
memcpy (&character, charPtr, 1);
/* Release the ECB and print the character */
SPXListenForSequencedPacket (ECBqueue[out]);
--RECEIVE_FLAG;
PrintCharacter();
}
return(1);
}
void PrintCharacter()
{
int i;
char ch;
CursorOff();
switch (character)
{
case TAB:
ClearReceiveBox();
break;
case ENTER:
receiveRow++;
if (receiveRow > LAST_RECEIVE_ROW)
{
receiveRow = LAST_RECEIVE_ROW;
ScrollUp (1, TOP_RECEIVE_ROW, LAST_RECEIVE_ROW, FIRST_TEXT_COL, LAST_TEXT_COL);
}
receiveCol = FIRST_TEXT_COL;
break;
case BACKSPACE:
if (receiveCol > FIRST_TEXT_COL)
DeleteChar (&receiveCol, &receiveRow);
break;
default:
if (receiveCol >= LAST_TEXT_COL)
{
receiveCol = FIRST_TEXT_COL;
receiveRow++;
}
if (receiveRow > LAST_RECEIVE_ROW)
{
receiveRow = LAST_RECEIVE_ROW;
ScrollUp(1,TOP_RECEIVE_ROW,LAST_RECEIVE_ROW,FIRST_TEXT_COL,LAST_TEXT_COL);
}
SetCursor(receiveRow, receiveCol++);
putchar(character);
break;
}
SetCursor(sendRow, sendCol);
CursorOn();
}
void ListenESR(receiveECBptr)
ECB *receiveECBptr;
{
SPXHeader *header;
static int in;
if (++in >= 20)
in = 0;
ECBqueue[in] = receiveECBptr;
++RECEIVE_FLAG;
return;
}
void SendPacket(charBuffer)
char *charBuffer;
{
int ccode = 0, i;
i = FindECB();
/* Check for a valid connection */
ccode = SPXGetConnectionStatus(SPXConnectionNumber, connectionInfo);
if (ccode)
Error("Invalid connection.");
/* Send character */
memcpy( (OutChars + i), charBuffer, 1);
SPXSendSequencedPacket (SPXConnectionNumber, (sendECB + i) );
if(sendECB[i].completionCode != 0)
ACTIVE_CONNECTION = 0;
else
Update ("Connection is active.");
}
void TearDownConnection()
{
int i;
i = FindECB();
sendECB[i].ESRAddress = 0;
sendECB[i].fragmentCount = 1;
sendECB[i].fragmentDescriptor[0].size = 42;
SPXTerminateConnection( SPXConnectionNumber, (sendECB + i) );
/* Wait until the Terminate has completed */
while ( sendECB[i].inUseFlag )
/* wait */;
IPXCloseSocket(Socket);
ClearScreen();
}
FindECB()
{
int ALL_ECBS_ARE_BUSY = 1, ECBnumber;
while (ALL_ECBS_ARE_BUSY)
{
for (ECBnumber = 0; ECBnumber < NUM_SEND_ECBS; ECBnumber++)
{
if (!sendECB[ECBnumber].inUseFlag)
{
ALL_ECBS_ARE_BUSY = FALSE;
break;
}
else if (ECBnumber == (NUM_SEND_ECBS - 1) )
Update ("Your partner has suspended the connection. Please wait.");
}
}
return (ECBnumber);
}
ParseDestination(server, user, command)
char *server, *user, *command;
{
int ch, i = 0, j = 0;
while ( (ch = *(command + i)) != '/' )
{
ch = toupper (ch);
*(server + i++) = (char)ch;
if (ch == '\0')
{
printf ("CHAT.EXE v1.01\n");
printf ("by Novell Technical Documentation\n\n");
printf ("Format: Chat fileserver/username\n");
printf ("Example: Chat Server_1/Rasputin\n");
exit ();
}
}
*(server + i++) = '\0';
while( (ch = *(command + i++)) != '\0' )
{
ch = toupper(ch);
*(user + j++) = (char)ch;
}
*(user + j) = '\0';
}
GetConnectionAndNode(preferredServer, userName, connection)
char *preferredServer, *userName;
WORD *connection;
{
WORD *count, max = 100, mysocket;
int ccode;
char networkNumber[4];
BYTE address[6];
NETWORK_ADDR iNetAddress;
/* Get the connection number of listening side */
ccode = NWGetObjectConnectionNumbers(connHandle, userName, OT_USER, count,
connection, max);
/* Get the node address of the listening side */
NWGetInternetAddress (connHandle, listeningConnection, (BYTE *)&iNetAddress);
memcpy(&destNode, iNetAddress.node, 6);
memcpy(&networkNumber, iNetAddress.network, 4);
/* destNode.hiNode = IntSwap(destNode.hiNode);
destNode.loNode = LongSwap(destNode.loNode); */
}
SayHello(listeningConnection)
WORD *listeningConnection;
{
BYTE time[7], address[6];
NWFLAGS result;
WORD callingConnection;
char callerName[48], networkNumber[4], connString[3];
int type, ccode;
long IDNumber;
/* Get connection number of calling side */
NWGetConnectionNumber(connHandle, &callingConnection);
/* Use the connection number to get the name of the caller */
NWGetConnectionInformation(connHandle, callingConnection, callerName, &type,
&IDNumber, time);
/* Create broadcast message */
ConvertToString(&callingConnection, connString, 1);
strncat(callerName, hello, sizeof(hello) );
strncat(callerName, connString, sizeof(connString));
ccode = NWSendBroadcastMessage(connHandle, callerName, 1, listeningConnection, &result);
return( ccode );
}
ConvertToString(number, string, size)
char *number,*string,size;
{
char i, j, k;
int left = 1;
for (i = j = k = 0; i < size; i++)
{
if (left)
{
j = *(number + i--);
j = j & 0x00F0;
j = j >> 4;
left--;
}
else
{
j = *(number + i);
j = j & 0x000F;
left++;
}
if (j < 10)
*(string + k++) = j + 0x30;
else
*(string + k++) = j + 0x37;
}
*(string + k) = '\0';
}