home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
xsap1a.exe
/
CLIENT.C
next >
Wrap
Text File
|
1994-09-14
|
15KB
|
562 lines
/****************************************************************************
** File: CLIENT.C
**
** Desc:
**
** Example of a DOS client which enlists the help of a SAPing server
** process.
**
** 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
** -----------------------------------------------------------------------
** ABJ Adam B. Jerome Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 08-19-94 ABJ First code.
** 09-14-94 ABJ Fixed the LocateScanID() function so that it works.
** (See header to LocateScanID() for details.)
*/
/****************************************************************************
** Include headers, macros, function prototypes, etc.
*/
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdlib.h> /* exit() */
#include <stdio.h> /* printf() */
#include <string.h>
#include <conio.h>
#include <time.h>
/*------------------------------------------------------------------------
** NetWare
*/
#define NWDOS
#include <nwcalls.h>
#include <nwipxspx.h>
/*------------------------------------------------------------------------
** CLIENT
*/
#include "common.h"
/****************************************************************************
** Communicate with server.
*/
int ComReq(IPXAddress *addr, COM_DATA_PACKET *txData, COM_DATA_PACKET *rxData, int retryCount, double timeOut)
{
WORD listenSocket = 0x0000; /* zero value causes NetWare to allocate a socket dynamicly */
time_t dTime = 0L;
int cCode;
int transportTime;
ECB rxEcb;
IPXHeader rxIpxHeader;
ECB txEcb;
IPXHeader txIpxHeader;
/*------------------------------------------------------------------------
** Initialize storage.
*/
memset(&rxEcb, 0x00, sizeof(rxEcb));
memset(&rxIpxHeader, 0x00, sizeof(rxIpxHeader));
memset(&txEcb, 0x00, sizeof(txEcb));
memset(&txIpxHeader, 0x00, sizeof(txIpxHeader));
/*------------------------------------------------------------------------
** Get NetWare to assign us a dynamic socket number to listen on.
*/
cCode=IPXOpenSocket((BYTE *)&listenSocket, 0x00);
switch(cCode)
{
case 0x0000:
break;
case 0x00F0:
printf("ERROR: IPX is not installed.\n");
goto END;
case 0x00FF:
printf("ERROR: IPX socket 0x%04hX is already in use on this node.\n", listenSocket);
goto END;
case 0x00FE:
printf("ERROR: IPX socket table is full on this node.\n");
goto END;
default:
printf("ERROR: IPXOpenSocket() returned an unknown error: %d\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Set up a listen ECB.
*/
rxEcb.ESRAddress = NULL;
rxEcb.socketNumber = listenSocket;
rxEcb.fragmentCount = 2;
rxEcb.fragmentDescriptor[0].address = &rxIpxHeader;
rxEcb.fragmentDescriptor[0].size = sizeof(rxIpxHeader);
rxEcb.fragmentDescriptor[1].address = rxData;
rxEcb.fragmentDescriptor[1].size = sizeof(COM_DATA_PACKET);
IPXListenForPacket(&rxEcb);
/*------------------------------------------------------------------------
** Setup send ECB.
*/
txEcb.ESRAddress = NULL;
txEcb.socketNumber = listenSocket;
cCode=IPXGetLocalTarget(
/* I- networkAddress */ (BYTE *)addr,
/* -O immediateAddress */ txEcb.immediateAddress,
/* -O transportTime */ &transportTime
);
switch(cCode)
{
case 0x0000:
break;
case 0xFA:
printf("ERROR: No local target identified.\n");
goto END;
default:
printf("ERROR: IPXGetLocalTarget() returned unknown error: %d.\n", cCode);
goto END;
}
txEcb.fragmentCount = 2;
txEcb.fragmentDescriptor[0].address = &txIpxHeader;
txEcb.fragmentDescriptor[0].size = sizeof(txIpxHeader);
txEcb.fragmentDescriptor[1].address = txData;
txEcb.fragmentDescriptor[1].size = sizeof(COM_DATA_PACKET);
txIpxHeader.packetType = 0x04; /* IPX packet type. */
memcpy(&txIpxHeader.destination, addr, sizeof(IPXAddress));
/*------------------------------------------------------------------------
** Wait for recieve ECB to happen.
*/
while(rxEcb.inUseFlag != 0x00)
{
/*---------------------------------------------------------------------
** First time in or Timeout/re-send?
**
** time is initialized to 0, therfore, packet will be sent first time
** in.
*/
if(difftime(time(NULL), dTime) > timeOut)
{
/*------------------------------------------------------------------------
** Send packet.
*/
time(&dTime);
--retryCount;
IPXSendPacket(&txEcb);
/*------------------------------------------------------------------------
** Wait for send to happen.
*/
while(txEcb.inUseFlag != 0x00)
{
if(kbhit())
{
printf("NOTE: TX aborted by user request.\n");
cCode=IPXCancelEvent(&txEcb);
switch(cCode)
{
case 0x0000:
break;
case 0xF9:
printf("WARNING-tx: ECB cannot be canceled.\n");
break;
case 0xFF:
printf("NOTE-tx: ECB not in use.\n");
break;
default:
printf("ERROR-tx: IPXCancelEvent() returned unknown error: %d\n", cCode);
break;
}
}
IPXRelinquishControl();
}
switch(txEcb.completionCode)
{
case 0x00:
break;
case 0xFC:
printf("NOTE-tx: Request canceled.\n");
break;
case 0xFD:
printf("ERROR-tx: Packet did not have a 30 byte header as the first fragment,\n"
" or its total length exceeded 576 bytes.\n");
goto END;
case 0xFE:
printf("ERROR-tx: Packet not deliverable.\n");
goto END;
case 0xFF:
printf("ERROR-tx: Hardware failure.\n");
goto END;
default:
printf("ERROR-tx: Unknown ECB completion code on send: %d.\n", 0x000000FF & txEcb.completionCode);
goto END;
}
}
/*---------------------------------------------------------------------
** User or retry abort?
*/
if(kbhit() || (retryCount == 0))
{
if(kbhit())
{
if(!getch()) getch();
printf("NOTE: TX aborted by user request.\n");
}
else
printf("NOTE: Retry count limmit reached.\n");
cCode=IPXCancelEvent(&rxEcb);
switch(cCode)
{
case 0x0000:
break;
case 0xF9:
printf("WARNING-rx: ECB cannot be canceled.\n");
break;
case 0xFF:
printf("NOTE-rx: ECB not in use.\n");
break;
default:
printf("ERROR-rx: IPXCancelEvent() returned unknown error: %d\n", cCode);
break;
}
}
IPXRelinquishControl();
}
/*------------------------------------------------------------------------
** Did we get something?
*/
switch(rxEcb.completionCode)
{
case 0x00:
break;
case 0xFC:
printf("NOTE-rx: Request canceled.\n");
break;
case 0xFD:
printf("ERROR-rx: Bad packet\n");
goto END;
case 0xFF:
printf("ERROR-rx: Hardware failure.\n");
goto END;
default:
printf("ERROR-rx: Unknown ECB completion code: %d.\n", 0x000000FF & rxEcb.completionCode);
goto END;
}
cCode=rxEcb.completionCode;
END:
/*------------------------------------------------------------------------
** Give our socket back to NetWare.
*/
if(listenSocket != 0x0000)
IPXCloseSocket(listenSocket);
return(cCode);
}
/****************************************************************************
** Locate server using ScanID method.
**
** When Who What
** --------------------------------------------------------------------------
** 08-19-94 ABJ First code.
** 09-14-94 ABJ Again, I was brain dead when I flipped out the first rev
** of this code.
**
** -The function NWScanObject() was not needed and was
** removed.
**
** -The COM_SERVER_TYPE must be swapped in order for the older
** NWReadPropertyValue() function to operate correctly.
**
** -fgets() leaves a <CR> on the end of the string. It is now
** removed.
*/
int LocateScanID(IPXAddress *addr, char *serverName)
{
NWCCODE cCode;
NWOBJ_ID objectID = -1;
BYTE propValue[128];
/*------------------------------------------------------------------------
** Get the name of the server.
*/
if(serverName[0] == '\0')
{
printf("Server name: ");
fgets(serverName, 47, stdin);
serverName[strlen(serverName)-1] = '\0'; /* rid the nasty <CR> */
}
/*------------------------------------------------------------------------
** Read the address property
*/
cCode = NWReadPropertyValue(
/* I- connHandle */ 0, /* 0 = default server connection */
/* I- objectName */ serverName,
/* I- objectType */ NWWordSwap(COM_SERVER_TYPE),
/* I- propertyName */ "NET_ADDRESS",
/* I- dataSetIndx */ 1,
/* -O dataBuffer */ propValue,
/* -O moreFlag */ NULL,
/* -O propertyFlags */ NULL
);
switch(cCode)
{
case 0x0000:
break;
case 0x89F0:
printf("ERROR: NWReadPropertyValue() reports and invalid serverName or type.\n");
goto END;
case 0x89FC:
printf("ERROR: NWReadPropertyValue() reports \"No such object.\"\n");
goto END;
default:
printf("ERROR: NWReadPropertyValue() returned 0x%04X\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Copy network address
*/
memcpy(addr, propValue, sizeof(IPXAddress));
END:
return(cCode);
}
/****************************************************************************
** Locate server using Get Nearest method.
*/
int LocateGetNearest(IPXAddress *addr)
{
SAP sap;
int cCode;
memset(&sap, 0x00, sizeof(SAP));
cCode=QueryServices(
/* I- queryType */ 3,
/* I- serverType */ COM_SERVER_TYPE,
/* I- returnSize */ sizeof(SAP),
/* -O serviceBuffer */ &sap
);
switch(cCode)
{
case 0x0000:
printf("ERROR: ??? Cant find server ???\n");
cCode = 1;
goto END;
case 0x0001:
printf("Server: %s\n", sap.ServerName);
cCode = 0;
break;
default:
printf("ERROR: QueryServices() returned unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Copy network address
*/
memcpy(addr, sap.Network, sizeof(IPXAddress));
END:
return(cCode);
}
/****************************************************************************
** Select method to locate server.
*/
int LocateServer(IPXAddress *addr, int method, char *serverName)
{
int cCode;
if(!method)
{
printf("Specify method to locate server:\n");
printf("\n");
printf(" 0 Exit program.\n");
printf("\n");
printf(" 1 Get Nearest\n");
printf(" This method assumes one of the following:\n");
printf(" A. There is only one server of type 0x%04X\n", COM_SERVER_TYPE);
printf(" B. All servers of type 0x%04X, provide exactly the same services.\n", COM_SERVER_TYPE);
printf("\n");
printf(" 2 Scan Bindery or Directory services\n");
printf(" This method assumes that you are attached to a NetWare fileserver\n");
printf(" and the fileserver name must be discovered by the application, \n");
printf(" (ie, user specified, config file, OS environmental variable, etc).\n");
printf("\n");
printf("Enter choice: ");
do {
method = getch() - '0';
} while((method < 0) || (method > 2));
printf("%d\n", method);
}
switch(method)
{
case 0:
cCode = (-1);
break;
case 1:
cCode=LocateGetNearest(addr);
break;
case 2:
cCode=LocateScanID(addr, serverName);
break;
}
return(cCode);
}
/****************************************************************************
** Program start.
*/
void main(int argc, char *argv[])
{
COM_DATA_PACKET rxData;
COM_DATA_PACKET txData;
IPXAddress addr;
LONG cCode;
int method = 0;
char serverName[47+1];
/*------------------------------------------------------------------------
** Process command line.
*/
if(argc > 1) method = atoi(argv[1]);
memset(serverName, 0x00, sizeof(serverName));
if(argc > 2) memcpy(serverName, argv[2], sizeof(serverName)-1);
/*------------------------------------------------------------------------
** Say hello to IPX.
*/
cCode=IPXInitialize();
switch(cCode)
{
case 0x00:
break;
case 0xF0:
printf("ERROR: IPX is not installed on this node.\n");
goto END;
default:
printf("ERROR: IPXInitialize() returned unknown error: %d.\n", cCode);
goto END;
}
/*------------------------------------------------------------------------
** Get the servers IPX network address.
*/
cCode=LocateServer(&addr, method, serverName);
if(cCode) goto END;
/*------------------------------------------------------------------------
** Communicate with server.
*/
txData.type = COM_REQ_PING;
cCode=ComReq(&addr, &txData, &rxData, 10, 2.0);
if(cCode) goto END;
/*------------------------------------------------------------------------
** Print out rx packet data.
*/
switch(rxData.status)
{
case COM_SUCCESS:
printf("%s\n", rxData.data);
break;
case COM_ERR_UNKNOWN_TYPE:
printf("ERROR: Server indicates unknown request type.\n");
goto END;
default:
printf("ERROR: Unknown error returned from server: %d.\n", rxData.status);
goto END;
}
END:
exit(0);
}