home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PROGRAMS / UTILS / NOVELL / DEMO24.ZIP / DEMO24C
Encoding:
Text File  |  1990-01-19  |  7.7 KB  |  294 lines

  1. /*
  2.     File    : DEMO24.C
  3.     Author    : Grant Echols
  4.     Purpose    : To demonstrate the possible use of a critical error
  5.         handler to re-establish a connection to a server with
  6.         or without user intervention.
  7.     Return Values : 0 = Aborted operation.
  8.                     1 = Normal Termination.
  9.                     2 = Unable to re-establish connection.
  10.                     3 = NetWare shell was not loaded.
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <dos.h>
  15. #include <conio.h>
  16. #include <time.h>
  17. #include <dir.h>
  18.  
  19. #define EXIT_NORM        1
  20. #define    EXIT_NO_CONNECT    2
  21. #define    EXIT_NO_SHELL    3
  22.  
  23. int CheckForNetwork ();
  24. int EstablishConnection ();
  25. int FirstNetworkDisk ();
  26. void DoDirectory (int);
  27. int MyInt24Handler (int, int, int, int);
  28.  
  29. int main ()
  30. {
  31.     /* Install our own critical error handler. */
  32.     harderr (MyInt24Handler);
  33.  
  34.     /* first, check to see if we have a current connection */
  35.     if (!CheckForNetwork ())
  36.         EstablishConnection ();
  37.  
  38.     /* Ok, we have a connection. Now lets get started. */
  39.     /* Here we just do something representing a network task. */
  40.     /* In this case it attempts to do a directory of the first */
  41.     /* network drive, pausing between each directory entry to */
  42.     /* allow time to unplug the cable. */
  43.     DoDirectory (FirstNetworkDisk ());
  44.  
  45.     /* ok, we are exiting with normal exit code */
  46.     /* no need to restore the previous critical error handler, since */
  47.     /* DOS will do it for us when we terminate. */
  48.     exit (EXIT_NORM);
  49. }
  50.  
  51. int CheckForNetwork ()
  52. /*    returns 0 if no valid file server name is found.
  53.     else returns 1.
  54. */
  55. {
  56.     union    REGS regs;
  57.     struct    SREGS sregs;
  58.     int    count;
  59.     char    far *fsNamePtr;
  60.  
  61.     /* first, see if the NetWare shell is loaded */
  62.     regs.h.ah = 0xDC;    /* Get Connection Number */
  63.     regs.x.cx = 0;        /* the NetWare shell will return non-zero here */
  64.     intdos (®s, ®s);
  65.     if (!regs.x.cx)
  66.     {
  67.         printf ("\nError - NetWare shell not loaded.");
  68.         printf ("\nThis program depends on the NetWare DOS shell");
  69.         printf (" to be loaded first.%c", 7);
  70.         printf ("\nLoad the NetWare shell and then re-run this program.");
  71.         exit (EXIT_NO_SHELL);    /* the shell is not loaded */
  72.                                 /* this program cannot continue */
  73.     }
  74.  
  75.     /* get a pointer to the File Server Name Table */
  76.     regs.x.ax = 0xEF04;    /* Get File Server Name table */
  77.     intdosx (®s, ®s, &sregs);
  78.  
  79.     /* point our temporary pointer to the table */
  80.     fsNamePtr = MK_FP (sregs.es, regs.x.si);
  81.     for (count = 0; count < 8; count++)
  82.     {
  83.         if (fsNamePtr[0] != 0)
  84.             return (1);    /* found a valid file server */
  85.         fsNamePtr += 48;    /* point to the next table entry */
  86.     }
  87.     return (0);            /* no valid file server found */
  88. }
  89.  
  90. int EstablishConnection ()
  91. /*     returns to caller if able to establish a connection.
  92.     else exits with errorlevel = 2.
  93.     attempts to establish an initial connection to any file server
  94.         using the DOS function parse file name, with an invalid
  95.         drive as the path and file name.
  96. */
  97. {
  98.     char    string [4];
  99.     struct fcb    tFCB;
  100.  
  101.     sprintf (string, "%c:", 'A' + (FirstNetworkDisk () - 1));
  102.     if (!parsfnm (string, &tFCB, 0))
  103.     {
  104.         printf ("\nUnable to re-establish a connection to a server at this time.%c", 7);
  105.         exit (EXIT_NO_CONNECT);
  106.     }
  107. }
  108.  
  109. int FirstNetworkDisk ()
  110. /*     returns the number of the first network disk (ie. A = 1, etc.)
  111. */
  112. {
  113.     union    REGS regs;
  114.  
  115.     regs.h.ah = 0xDB;    /* Get Number Of Local Drives */
  116.     intdos (®s, ®s);
  117.     return (regs.h.al + 1);
  118. }
  119.  
  120. void DoDirectory (int disk)
  121. /*     returns nothing.
  122.     displays all directory entries on the specified disk.
  123. */
  124. {
  125.     struct    ffblk    fBlock;
  126.     char    fname[] = {" :*.*"};
  127.     int        ccode,
  128.             attrib = FA_DIREC;    /* label, directories and files */
  129.  
  130.     fname [0] = disk + 'A' - 1;
  131.     printf ("\nDirectory of drive %c:", fname[0]);
  132.     printf ("\nName          Type");
  133.     ccode = findfirst (fname, &fBlock, attrib);
  134.     while (!ccode)
  135.     {
  136.         printf ("\n%-12s %s", fBlock.ff_name, (fBlock.ff_attrib & FA_DIREC) ?
  137.             "<DIR>" : "<FILE>");
  138.  
  139.         /* slow down a bit so the cable can be pulled */
  140.         delay (100);
  141.  
  142.         /* now find the next directory entry */
  143.         ccode = findnext (&fBlock);
  144.     }
  145.     printf ("\nNo more files\n");
  146. }
  147.  
  148. /********************** Critical Error Data and Handler *****************/
  149.  
  150. char    *errStrList[] = {    "Write protecte viloation",
  151.                 "Unknown unit",
  152.                 "Drive not ready",
  153.                 "Unknown command",
  154.                 "Data error (CRC)",
  155.                 "Bad request structure length",
  156.                 "Seek error",
  157.                 "Unknown media type",
  158.                 "Sector not found",
  159.                 "Printer out of paper",
  160.                 "Write fault",
  161.                 "Read fault",
  162.                 "General failure"},
  163.     abortMess[] = {"\n\rAbort "},
  164.     retryMess[] = {", Retry "},
  165.     ignoreMess[] = {", Ignore "};
  166.  
  167. #define ABORT     2
  168. #define RETRY    1
  169. #define IGNORE    0
  170.  
  171. /************************** MyInt24Handler function *********************/
  172.  
  173. int MyInt24Handler (int errval, int ax, int bp, int si)
  174. /*     returns 0 if ignore, 1 if retry, 2 if abort.
  175.     prompts user for input, if no input, then selects abort.
  176. */
  177. {
  178.     char    string[80];
  179.     time_t    start, now;
  180.     double    delay = 30.0;
  181.     int        key;
  182.  
  183.     /* first, display that we had a Critical Error */
  184.     sprintf (string, "\n\rCritical error - %s", errStrList[errval]);
  185.     BIOSPrintString (string);
  186.  
  187.     /* now see if this is a Disk error or not */
  188.     if (ax & 0x8000)
  189.         /* Bit 7 was set, so its a non-disk error */
  190.         /* print out the device name that BP:SI is pointing at */
  191.         sprintf (string, "\n\rDevice = %.8Fs", MK_FP (bp, si+10));
  192.     else
  193.         sprintf (string, "\n\rDisk error on drive %c:", 'A' + (ax & 0x00FF));
  194.  
  195.     /* now display whatever error it was */
  196.     BIOSPrintString (string);
  197.  
  198.     /* now display the Abort option which is allways allowed */
  199.     BIOSPrintString (abortMess);
  200.  
  201.     /* print the Retry option if it is allowed */
  202.     if (ax & 0x1000)
  203.         BIOSPrintString (retryMess);
  204.  
  205.     /* print the Ignore option if it is allowed */
  206.     if (ax & 0x2000)
  207.         BIOSPrintString (ignoreMess);
  208.  
  209.     BIOSPrintString (" : ");
  210.     time (&start);
  211.  
  212.     /* start a loop which waits for a specified time for a key */
  213. WaitForKey:
  214.     key = 0;
  215.     while (!KeyHit(&key) && (difftime (time(&now), start) < delay));
  216.  
  217.     /* either a key was hit or the time elapsed, determine which */
  218.     if (key)
  219.     {
  220.         /* a key was hit so get the key and process it */
  221.         key = toupper (key);
  222.         switch (key)
  223.         {
  224.             case 'A': /* Abort selected */
  225.                 BIOSPrintString ("Abort\n\r");
  226.                 return (ABORT);
  227.             case 'R': /* Retry selected */
  228.                 BIOSPrintString ("Retry\n\r");
  229.                 return (RETRY);
  230.             case 'I': /* Ignore selected */
  231.                 BIOSPrintString ("Ignore\n\r");
  232.                 return (IGNORE);
  233.             default: /* invalid response, ring the bell */
  234.                 putch (7);
  235.                 goto WaitForKey;
  236.         }
  237.     }
  238.  
  239.     /* the time out occured without a key being hit so return Abort */
  240.     BIOSPrintString ("Automatic Abort\n\r");
  241.     return (ABORT);
  242. }
  243.  
  244. BIOSPrintString (char *str)
  245. /*    returns nothing.
  246.     prints out a NULL terminated string in TTY fashion on the current
  247.         video page using the BIOS video interrupt.
  248. */
  249. {
  250.     union    REGS regs;
  251.     char    *strPtr;
  252.  
  253.     /* first, get the current video state, page, etc. */
  254.     regs.h.ah =  0xF;        /* Get Current Video State */
  255.     int86 (0x10, ®s, ®s);
  256.     /* now regs.h.bh = active display page */
  257.  
  258.     /* set up the registers that won't be changing */
  259.     regs.h.bl = 0x7;        /* Normal, white on black attribute */
  260.     regs.h.ah = 0xE;        /* BIOS Video TTY Character Output */
  261.     strPtr = str;
  262.  
  263.     /* now print out the string through BIOS video */
  264.     while (*strPtr)
  265.     {
  266.         regs.h.al = *strPtr++;
  267.         int86 (0x10, ®s, ®s);
  268.     }
  269. }
  270.  
  271. KeyHit (int *key)
  272. /*     returns 0 if no key.
  273.     non-zero if a key is pressed, and key is set the the value.
  274. */
  275. {
  276.     union    REGS regs;
  277.  
  278.     regs.h.ah = 1;            /* Read Keyboard Status */
  279.     int86 (0x16, ®s, ®s);    /* Keyboard BIOS interrupt */
  280.  
  281.     /* check to see if the zero flag is set */
  282.     if (!(regs.x.flags & (1 << 6)))
  283.     {
  284.         /* it wasn't set so there was a key */
  285.         *key = regs.x.ax;
  286.         return (1);
  287.     }
  288.     else
  289.     {
  290.         *key = 0;
  291.         return (0);
  292.     }
  293. }
  294.