home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / lant / wt4lan.arc / WAIT4LAN.C < prev    next >
C/C++ Source or Header  |  1991-04-23  |  9KB  |  368 lines

  1. /*****************************************************************************
  2. * WAIT4LAN is designed to make it easier to start up a peer network where
  3. * the machines on the network log into each other's drives.  WAIT4LAN
  4. * waits for the server software to be loaded on each of the other machines
  5. * on the network before it exits.  In this way it is possible to
  6. * make sure all of the machines are in "sync" before continuing the
  7. * AUTOEXEC.BAT files.
  8. *
  9. * WAIT4LAN has been tested on LANtastic networks.  It should work
  10. * on other NetBIOS based peer networks.
  11. *
  12. * The syntax for WAIT4LAN is:
  13. *      WAIT4LAN [-waittime] node1 [node2 ...]
  14. * where:
  15. *      waittime is the number of seconds WAIT4LAN will wait before
  16. *      giving up (default is 180 seconds).
  17. *      node1, node2, ... are the names of the other servers on the 
  18. *      network ("node1" is the name assigned by the server software 
  19. *      when it is loaded).
  20. * WAIT4LAN returns an errorlevel of 0 if all of the nodes are active,
  21. * an errorlevel of 1 if one or more are inactive after the waittime
  22. * as elapsed.
  23. * The program is fully protected by copyright and all rights are 
  24. * reserved.  This program is distributed as "POSTware".  If you 
  25. * find the program useful please send a post card to:
  26. *
  27. *     Ken Brown
  28. *     5707 Jamestown Rd Apt 2
  29. *     Hyattsville, MD  20782
  30. *
  31. * No registration is required.
  32. *****************************************************************************/
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <malloc.h>
  38. #include <dos.h>
  39.  
  40.  
  41. #define TRUE      1
  42. #define FALSE     0
  43.  
  44. #define EOS       '\0'
  45.  
  46. #define ADAPTER_STATUS  0x33
  47.  
  48.  
  49. /* NetBIOS data structure */
  50.  
  51. struct NCB {
  52.    char Command;
  53.    char RetCode;
  54.    char Lsn;
  55.    char Num;
  56.    char far *Buffer;
  57.    int  Length;
  58.    char CallName[16];
  59.    char Name[16];
  60.    char Rto;
  61.    char Sto;
  62.    void (far *Post)();
  63.    char LanaNum;
  64.    char CmdCplt;
  65.    char Reserved[14];
  66.    };
  67.  
  68.  
  69.  
  70. struct NODE_LIST {
  71.    char  *NodeName;
  72.    int   ActiveStatusFlag;
  73.    };
  74.  
  75.  
  76. /* Global variables */
  77.  
  78. struct NODE_LIST NodeList[16];
  79. struct NCB Ncb;
  80.  
  81. char  ProgramName[14],
  82.       AdapterStatusBuffer[512];
  83.  
  84.  
  85. main(int argc, char *argv[])
  86. {
  87.    int   NodeCounter,
  88.          InactiveNodeCount,
  89.          Counter,
  90.          WaitTime,
  91.          KeyPressed;
  92.    char  *WaitPtr,
  93.          *StrPtr;
  94.    long  StartTime,
  95.          CurrentTime,
  96.          EndTime;
  97.    char  far *NetBiosInterrupt;
  98.  
  99.  
  100.    if(_osmajor < 3) {
  101.       printf("\nDOS 3.0 or later required\n");
  102.       exit(1);
  103.       }
  104.    else {
  105.       StrPtr = strrchr(argv[0],'\\');
  106.       if(StrPtr == NULL) {
  107.          strcpy(ProgramName,argv[0]);
  108.          }
  109.       else {
  110.          StrPtr++;
  111.          strcpy(ProgramName,StrPtr);
  112.          }
  113.       StrPtr = strchr(ProgramName,'.');
  114.       if(StrPtr != NULL) {
  115.          *StrPtr = EOS;
  116.          }
  117.       }
  118.  
  119.    printf("%s v1.0 (10/7/89)  Copyright 1989, Ken Brown\n",ProgramName);
  120.    printf("Startup utility for LANtastic networks\n");
  121.  
  122.    if(argc == 1) {
  123.       usage();
  124.       }
  125.  
  126.    WaitTime = -1;
  127.  
  128.  
  129.    /* Check that interrupt 5C is nonzero, if so assume that NetBios
  130.       is loaded */
  131.  
  132.    NetBiosInterrupt = _dos_getvect(0x5C);
  133.  
  134.    if(NetBiosInterrupt == NULL) {
  135.       printf("\nNetBIOS not loaded\n");
  136.       exit(1);
  137.       }
  138.  
  139.  
  140.    /* Parse the command line arguements */
  141.    NodeCounter = 0;
  142.  
  143.    for(Counter = 1; Counter < argc; Counter++) {
  144.       if(*argv[Counter] == '-') {
  145.             if(WaitTime > 0) {
  146.                 usage();
  147.                 }
  148.          WaitPtr = argv[Counter];
  149.          WaitPtr++;
  150.          if(*WaitPtr < '0' || *WaitPtr > '9') {
  151.             usage();
  152.             }
  153.          WaitTime = atoi(WaitPtr);
  154.          continue;
  155.          }
  156.       StrPtr = argv[Counter];
  157.       while(*StrPtr == '\\' && *StrPtr != EOS) {
  158.          StrPtr++;
  159.          }
  160.       if(*StrPtr == EOS) {
  161.          continue;
  162.          }
  163.       if((NodeList[NodeCounter].NodeName = strdup(StrPtr)) == NULL) {
  164.          printf("\nOut of memory, can not continue\n");
  165.          exit(1);
  166.          }
  167.       NodeList[NodeCounter].ActiveStatusFlag = FALSE;
  168.       NodeCounter += 1;
  169.       if(NodeCounter >= 16) {
  170.          printf("\nWarning, a maximun of 16 nodes may be checked\n");
  171.          NodeCounter = 16;
  172.          break;
  173.          }
  174.       }
  175.  
  176.    /* The default wait time is 180 seconds (3 minutes), if WaitTime
  177.       has not been set assume the default */
  178.  
  179.    if(WaitTime < 0) {
  180.       WaitTime = 180;
  181.       }
  182.  
  183.    InactiveNodeCount = NodeCounter;
  184.  
  185.    printf("\nChecking status of the following nodes\n");
  186.    for(Counter = 0; Counter < NodeCounter; Counter++) {
  187.       strupr(NodeList[Counter].NodeName);
  188.       printf("\t%s\n",NodeList[Counter].NodeName);
  189.       }
  190.  
  191.    printf("\nProgram will wait up to %d seconds, press ESC to exit early\n\n",WaitTime);
  192.  
  193.    /* Start the timer */
  194.  
  195.    time(&StartTime);
  196.    CurrentTime = StartTime;
  197.    EndTime = StartTime + (long)WaitTime;
  198.  
  199.  
  200.    /* Until the timer counts down and while there are still
  201.       inactive nodes, keep looping and checking */
  202.  
  203.    while(CurrentTime < EndTime && InactiveNodeCount > 0) {
  204.  
  205.       for(Counter = 0; Counter < NodeCounter; Counter++) {
  206.  
  207.          if(NodeList[Counter].ActiveStatusFlag == FALSE) {
  208.             printf("Checking %s, ",NodeList[Counter].NodeName);
  209.  
  210.             if(kbhit() != 0) {
  211.                KeyPressed = getch();
  212.                if(KeyPressed == 27) {
  213.                   printf("\n%s cancelled\n\n",ProgramName);
  214.                   exit(1);
  215.                   }
  216.                }
  217.  
  218.             /* Check to see it the node is active (by doing a
  219.                status check for the network adapter) */
  220.  
  221.             if(CheckNodeStatus(NodeList[Counter].NodeName) == TRUE) {
  222.                /* If CheckNodeStatus() returns TRUE change the
  223.                   node status and decrement the InactiveNodeCount */
  224.                NodeList[Counter].ActiveStatusFlag = TRUE;
  225.                InactiveNodeCount -= 1;
  226.                printf("node is active\n");
  227.                }
  228.             else {
  229.                printf("node is not active\n");
  230.                }
  231.             }
  232.          }
  233.       /* Wait a couple of seconds before starting over */
  234.       if(InactiveNodeCount > 0) {
  235.          Sleep(2);
  236.          }
  237.       time(&CurrentTime);
  238.       }
  239.  
  240.  
  241.    /* If the count is zero, we found all of the nodes, if not
  242.       we timed out waiting for one or more nodes which never
  243.       came on line */
  244.  
  245.    if(InactiveNodeCount == 0) {
  246.       exit(0);
  247.       }
  248.    else {
  249.       printf("\n\nThe following nodes are inactive:\n");
  250.       for(Counter = 0; Counter < NodeCounter; Counter++) {
  251.          if(NodeList[Counter].ActiveStatusFlag == FALSE) {
  252.             printf("\t%s\n",NodeList[Counter].NodeName);
  253.             }
  254.          }
  255.       printf("\n");
  256.       exit(1);
  257.       }
  258.  
  259. }
  260.  
  261.  
  262. usage()
  263. {
  264.    printf("\nSyntax: %s [-waittime] node1 [node2 ...]\n",ProgramName);
  265.    exit(1);
  266. }
  267.  
  268. Sleep(int Seconds)
  269. {
  270.    int   KeyPressed;
  271.    long  StartTime,
  272.          CurrentTime,
  273.          EndTime;
  274.  
  275.    time(&StartTime);
  276.    CurrentTime = StartTime;
  277.    EndTime = StartTime + (long)Seconds;
  278.  
  279.    while(CurrentTime < EndTime) {
  280.       if(kbhit() != 0) {
  281.          KeyPressed = getch();
  282.          if(KeyPressed == 27) {
  283.             printf("\n%s cancelled\n\n",ProgramName);
  284.             exit(1);
  285.             }
  286.          }
  287.       time(&CurrentTime);
  288.       }
  289.  
  290. }
  291.  
  292.  
  293. /* CheckNodeStatus() does a NetBIOS "Check Adapter Status" call
  294.    to see if a node is active.  Because the name used is the
  295.    name which is loaded into the name table by the server software,
  296.    the check will fail until after the server software loads
  297.    on the node in question. */
  298.  
  299. CheckNodeStatus(char *NodeName)
  300. {
  301.    union REGS inregs, outregs;
  302.  
  303.    struct SREGS sregs;
  304.  
  305.    segread(&sregs);
  306.    sregs.es = sregs.ds;
  307.  
  308.     ClearNCB(&Ncb);
  309.     Ncb.Command = ADAPTER_STATUS;
  310.     Ncb.Buffer = (char far *)AdapterStatusBuffer;
  311.     memset(AdapterStatusBuffer,'\0',512);
  312.     Ncb.Length = 512;
  313.     if(NodeName == NULL) {
  314.         memcpy(Ncb.CallName,"****************",16);
  315.         }
  316.     else {
  317.         memcpy(Ncb.CallName,NodeName,strlen(NodeName));
  318.         }
  319.  
  320.     inregs.x.bx = &Ncb;
  321.    int86x(0x5C,&inregs,&outregs,&sregs);
  322.  
  323.  
  324.    /* A RetCode of 0 means that the Adapter Status call succeeded,
  325.       any thing else means it failed */
  326.  
  327.     switch (Ncb.RetCode) {
  328.         case 0:
  329.          return TRUE;
  330.             break;
  331.         default:
  332.          return FALSE;
  333.             break;
  334.         }
  335.  
  336. }
  337.  
  338. ClearNCB(struct NCB *NcbPtr)
  339. {
  340.     NcbPtr->Command = 0;
  341.     NcbPtr->RetCode = 0xFF;
  342.     NcbPtr->Lsn = 0;
  343.     NcbPtr->Num = 0;
  344.     NcbPtr->Buffer = NULL;
  345.     NcbPtr->Length = 0;
  346.     NcbPtr->Rto = 0;
  347.     NcbPtr->Sto = 0;
  348.     NcbPtr->Post = NULL;
  349.     NcbPtr->LanaNum = 0;
  350.     NcbPtr->CmdCplt = 0;
  351.     memset(NcbPtr->CallName,' ',16);
  352.     memset(NcbPtr->Name,' ',16);
  353.     memset(NcbPtr->Reserved,'\0',14);
  354. }
  355.  
  356.