home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hall of Fame
/
HallofFameCDROM.cdr
/
lant
/
wt4lan.arc
/
WAIT4LAN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-23
|
9KB
|
368 lines
/*****************************************************************************
* WAIT4LAN is designed to make it easier to start up a peer network where
* the machines on the network log into each other's drives. WAIT4LAN
* waits for the server software to be loaded on each of the other machines
* on the network before it exits. In this way it is possible to
* make sure all of the machines are in "sync" before continuing the
* AUTOEXEC.BAT files.
*
* WAIT4LAN has been tested on LANtastic networks. It should work
* on other NetBIOS based peer networks.
*
*
* The syntax for WAIT4LAN is:
*
* WAIT4LAN [-waittime] node1 [node2 ...]
*
* where:
*
* waittime is the number of seconds WAIT4LAN will wait before
* giving up (default is 180 seconds).
*
* node1, node2, ... are the names of the other servers on the
* network ("node1" is the name assigned by the server software
* when it is loaded).
*
*
* WAIT4LAN returns an errorlevel of 0 if all of the nodes are active,
* an errorlevel of 1 if one or more are inactive after the waittime
* as elapsed.
*
*
* The program is fully protected by copyright and all rights are
* reserved. This program is distributed as "POSTware". If you
* find the program useful please send a post card to:
*
* Ken Brown
* 5707 Jamestown Rd Apt 2
* Hyattsville, MD 20782
*
* No registration is required.
*
*
*
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <dos.h>
#define TRUE 1
#define FALSE 0
#define EOS '\0'
#define ADAPTER_STATUS 0x33
/* NetBIOS data structure */
struct NCB {
char Command;
char RetCode;
char Lsn;
char Num;
char far *Buffer;
int Length;
char CallName[16];
char Name[16];
char Rto;
char Sto;
void (far *Post)();
char LanaNum;
char CmdCplt;
char Reserved[14];
};
struct NODE_LIST {
char *NodeName;
int ActiveStatusFlag;
};
/* Global variables */
struct NODE_LIST NodeList[16];
struct NCB Ncb;
char ProgramName[14],
AdapterStatusBuffer[512];
main(int argc, char *argv[])
{
int NodeCounter,
InactiveNodeCount,
Counter,
WaitTime,
KeyPressed;
char *WaitPtr,
*StrPtr;
long StartTime,
CurrentTime,
EndTime;
char far *NetBiosInterrupt;
if(_osmajor < 3) {
printf("\nDOS 3.0 or later required\n");
exit(1);
}
else {
StrPtr = strrchr(argv[0],'\\');
if(StrPtr == NULL) {
strcpy(ProgramName,argv[0]);
}
else {
StrPtr++;
strcpy(ProgramName,StrPtr);
}
StrPtr = strchr(ProgramName,'.');
if(StrPtr != NULL) {
*StrPtr = EOS;
}
}
printf("%s v1.0 (10/7/89) Copyright 1989, Ken Brown\n",ProgramName);
printf("Startup utility for LANtastic networks\n");
if(argc == 1) {
usage();
}
WaitTime = -1;
/* Check that interrupt 5C is nonzero, if so assume that NetBios
is loaded */
NetBiosInterrupt = _dos_getvect(0x5C);
if(NetBiosInterrupt == NULL) {
printf("\nNetBIOS not loaded\n");
exit(1);
}
/* Parse the command line arguements */
NodeCounter = 0;
for(Counter = 1; Counter < argc; Counter++) {
if(*argv[Counter] == '-') {
if(WaitTime > 0) {
usage();
}
WaitPtr = argv[Counter];
WaitPtr++;
if(*WaitPtr < '0' || *WaitPtr > '9') {
usage();
}
WaitTime = atoi(WaitPtr);
continue;
}
StrPtr = argv[Counter];
while(*StrPtr == '\\' && *StrPtr != EOS) {
StrPtr++;
}
if(*StrPtr == EOS) {
continue;
}
if((NodeList[NodeCounter].NodeName = strdup(StrPtr)) == NULL) {
printf("\nOut of memory, can not continue\n");
exit(1);
}
NodeList[NodeCounter].ActiveStatusFlag = FALSE;
NodeCounter += 1;
if(NodeCounter >= 16) {
printf("\nWarning, a maximun of 16 nodes may be checked\n");
NodeCounter = 16;
break;
}
}
/* The default wait time is 180 seconds (3 minutes), if WaitTime
has not been set assume the default */
if(WaitTime < 0) {
WaitTime = 180;
}
InactiveNodeCount = NodeCounter;
printf("\nChecking status of the following nodes\n");
for(Counter = 0; Counter < NodeCounter; Counter++) {
strupr(NodeList[Counter].NodeName);
printf("\t%s\n",NodeList[Counter].NodeName);
}
printf("\nProgram will wait up to %d seconds, press ESC to exit early\n\n",WaitTime);
/* Start the timer */
time(&StartTime);
CurrentTime = StartTime;
EndTime = StartTime + (long)WaitTime;
/* Until the timer counts down and while there are still
inactive nodes, keep looping and checking */
while(CurrentTime < EndTime && InactiveNodeCount > 0) {
for(Counter = 0; Counter < NodeCounter; Counter++) {
if(NodeList[Counter].ActiveStatusFlag == FALSE) {
printf("Checking %s, ",NodeList[Counter].NodeName);
if(kbhit() != 0) {
KeyPressed = getch();
if(KeyPressed == 27) {
printf("\n%s cancelled\n\n",ProgramName);
exit(1);
}
}
/* Check to see it the node is active (by doing a
status check for the network adapter) */
if(CheckNodeStatus(NodeList[Counter].NodeName) == TRUE) {
/* If CheckNodeStatus() returns TRUE change the
node status and decrement the InactiveNodeCount */
NodeList[Counter].ActiveStatusFlag = TRUE;
InactiveNodeCount -= 1;
printf("node is active\n");
}
else {
printf("node is not active\n");
}
}
}
/* Wait a couple of seconds before starting over */
if(InactiveNodeCount > 0) {
Sleep(2);
}
time(&CurrentTime);
}
/* If the count is zero, we found all of the nodes, if not
we timed out waiting for one or more nodes which never
came on line */
if(InactiveNodeCount == 0) {
exit(0);
}
else {
printf("\n\nThe following nodes are inactive:\n");
for(Counter = 0; Counter < NodeCounter; Counter++) {
if(NodeList[Counter].ActiveStatusFlag == FALSE) {
printf("\t%s\n",NodeList[Counter].NodeName);
}
}
printf("\n");
exit(1);
}
}
usage()
{
printf("\nSyntax: %s [-waittime] node1 [node2 ...]\n",ProgramName);
exit(1);
}
Sleep(int Seconds)
{
int KeyPressed;
long StartTime,
CurrentTime,
EndTime;
time(&StartTime);
CurrentTime = StartTime;
EndTime = StartTime + (long)Seconds;
while(CurrentTime < EndTime) {
if(kbhit() != 0) {
KeyPressed = getch();
if(KeyPressed == 27) {
printf("\n%s cancelled\n\n",ProgramName);
exit(1);
}
}
time(&CurrentTime);
}
}
/* CheckNodeStatus() does a NetBIOS "Check Adapter Status" call
to see if a node is active. Because the name used is the
name which is loaded into the name table by the server software,
the check will fail until after the server software loads
on the node in question. */
CheckNodeStatus(char *NodeName)
{
union REGS inregs, outregs;
struct SREGS sregs;
segread(&sregs);
sregs.es = sregs.ds;
ClearNCB(&Ncb);
Ncb.Command = ADAPTER_STATUS;
Ncb.Buffer = (char far *)AdapterStatusBuffer;
memset(AdapterStatusBuffer,'\0',512);
Ncb.Length = 512;
if(NodeName == NULL) {
memcpy(Ncb.CallName,"****************",16);
}
else {
memcpy(Ncb.CallName,NodeName,strlen(NodeName));
}
inregs.x.bx = &Ncb;
int86x(0x5C,&inregs,&outregs,&sregs);
/* A RetCode of 0 means that the Adapter Status call succeeded,
any thing else means it failed */
switch (Ncb.RetCode) {
case 0:
return TRUE;
break;
default:
return FALSE;
break;
}
}
ClearNCB(struct NCB *NcbPtr)
{
NcbPtr->Command = 0;
NcbPtr->RetCode = 0xFF;
NcbPtr->Lsn = 0;
NcbPtr->Num = 0;
NcbPtr->Buffer = NULL;
NcbPtr->Length = 0;
NcbPtr->Rto = 0;
NcbPtr->Sto = 0;
NcbPtr->Post = NULL;
NcbPtr->LanaNum = 0;
NcbPtr->CmdCplt = 0;
memset(NcbPtr->CallName,' ',16);
memset(NcbPtr->Name,' ',16);
memset(NcbPtr->Reserved,'\0',14);
}