home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / REACTDLC.ZIP / reactdlc.c < prev    next >
Text File  |  1992-12-21  |  25KB  |  483 lines

  1. /*************************************************************************/
  2. /*                                                                       */
  3. /*  MODULE NAME : REACTDLC.C                                             */
  4. /*                                                                       */
  5. /*  DESCRIPTIVE : REACTIVATE DLC "C" SAMPLE PROGRAM                      */
  6. /*                                                                       */
  7. /*  FUNCTION:   Issues a ACTIVATE_DLC when an error log type 17          */
  8. /*              and subtype 2 is received on the log queue.              */
  9. /*                                                                       */
  10. /*  NOTES:      1. When an adapter fails this program will attempt       */
  11. /*                 to reactivate the DLC at regular intervals.  If       */
  12. /*                 the adapter is in a condition such that it can not    */
  13. /*                 reactivated successfully then this program may        */
  14. /*                 attempt many times.  Each attempt will cause one      */
  15. /*                 or two errors to be logged.  For this reason the      */
  16. /*                 error log is copied to another file for safe keeping. */
  17. /*                 Also the error log should be configured to wrap       */
  18. /*                 instead of extend as the error log could grow very    */
  19. /*                 large in some unattended situations.                  */
  20. /*                                                                       */
  21. /*              2. Messages should be configured not to pop up because   */
  22. /*                 adapter failures generate pop up messages and many    */
  23. /*                 could get queued to the screen.                       */
  24. /*                                                                       */
  25. /*              3. The ACTIVATE_DLC verb is not officially 'external'.   */
  26. /*                 Communications Manager reserves to right to modifiy   */
  27. /*                 the verb control block if necessay.                   */
  28. /*                                                                       */
  29. /*              4. Link failures also create error log type 17 subtype 2 */
  30. /*                 entries and this program does not distinguish         */
  31. /*                 between the two.  If ACTIVATE_DLC is issued when      */
  32. /*                 the DLC is open then no harm is done only a return    */
  33. /*                 code indicating DUPLICATE_DLC.                        */
  34. /*                                                                       */
  35. /*              5. This program must be modified for different DLCs and  */
  36. /*                 adapters.  Currently this program is coded to only    */
  37. /*                 reactivate the Token Ring adapter 0.                  */
  38. /*                                                                       */
  39. /*  FORMAT:     REACTDLC time_interval                                   */
  40. /*                                                                       */
  41. /*              time_interval - Time between attempts to restart the     */
  42. /*                              the adapter with ACTIVATE_DLC.  The      */
  43. /*                              time is in seconds and the minimum is    */
  44. /*                              45 seconds.  This allows time for the    */
  45. /*                              adapter to determine an error condition  */
  46. /*                              after reactivating.                      */
  47. /*                                                                       */
  48. /*  EXAMPLE:    REACTDLC 50                                              */
  49. /*                                                                       */
  50. /*  MODULE:     IBM Personal Computer C/2 Compiler (Version 1.1)         */
  51. /*  TYPE        (Compiles with Small Memory Model)                       */
  52. /*                                                                       */
  53. /*************************************************************************/
  54.  
  55. #include <STDIO.H>
  56. #include <STDDEF.H>
  57. #include <STDLIB.H>
  58. #include <STRING.H>
  59. #include <io.h>
  60.  
  61. /* Macro clear_vcb sets the APPC verb control block to zeros */
  62.  
  63. #define clear_vcb()     memset(&vcb,(int)'\0',sizeof(vcb))
  64.  
  65. /* Extract selector or offset from far pointer */
  66. #define SELECTOROF(p)       (((unsigned short *)&(p))[1])
  67. #define OFFSETOF(p)         (((unsigned short *)&(p))[0])
  68.  
  69. /***********************************************************/
  70. /*        General Declares                                 */
  71. /***********************************************************/
  72.  
  73. unsigned far *vcbptr;                       /* Pointer to the vcb           */
  74. unsigned long time_interval;                /* Time between retry attempts  */
  75. unsigned long thirty_seconds = 30000;       /* Wait time for CM to start    */
  76. unsigned short error_code;                  /* Dos Call return code         */
  77. unsigned short qhandle;                     /* Queue handle                 */
  78. unsigned long qrequest;                     /* Queue request                */
  79. unsigned char qpriority;                    /* Queue priority               */
  80. void far *qsemhandle;                       /* Queue semephore handle       */
  81. unsigned short qlength;                     /* Queue element length         */
  82. unsigned char qname[17];                    /* Queue name \QUEUES\ERRLOG17  */
  83. unsigned char retry_mode;                   /* Flag to indicate retry mode  */
  84. unsigned char error_dat[19];                /* Error file ERROR.DAT         */
  85. unsigned short fhandle_new;                 /* File handle                  */
  86. unsigned short fhandle_error;               /* File handle                  */
  87. unsigned char buffer[20000];                /* Buffer for ERROR.DAT         */
  88. unsigned short buffer_length;               /* Buffer length                */
  89. unsigned short bytes_read;                  /* Size of ERROR.DAT            */
  90. unsigned short bytes_written;               /*                              */
  91. unsigned short msel;                        /* Selector of CM shared mem    */
  92. unsigned char mname[24];                    /* Memory \SHAREMEM\ACSLGMEM    */
  93. unsigned char prim_rc_prt[2];               /* Primary Return code swapped  */
  94.  
  95. struct new_file                             /* File name for copied err log */
  96.     {
  97.     unsigned char new_file_name[16];        /* File name ERRSAV. in CMLIB   */
  98.     unsigned short file_extension;          /* File ext A - Z               */
  99.     } error_file_name;
  100.  
  101. union
  102.     {
  103.     unsigned long log_ptr;
  104.     struct error_log_queue_element far *error_log_ptr;
  105.     } lp;
  106.  
  107. union
  108.     {
  109.     unsigned char filename[18];
  110.     struct new_file error_file_name;
  111.     } error;
  112.  
  113. /***********************************************************/
  114. /*        General Constants                                */
  115. /***********************************************************/
  116.  
  117. #define ON                  0x01
  118. #define OFF                 0x00
  119. #define LOGS                0x00
  120. #define ALL                 0x01
  121. #define SOME                0x00
  122. #define FIFO                0x0000
  123. #define WAIT                0x00
  124. #define NOWAIT              0x01
  125. #define WRITE               0000200      /* write permission, owner */
  126. #define READBINARY          0x8000       /* open for reading only   */
  127. #define WRITEBINARY         0x8101       /* open for writing only   */
  128. #define ERROR_QUE_EMPTY     342          /* DosReadQueue error code */
  129.  
  130. /***********************************************************/
  131. /*        External Entry Points                            */
  132. /***********************************************************/
  133.  
  134.      extern void pascal far ACSMGTI(long);  /* Managment Services           */
  135.      extern void pascal far ACSSVC(long);   /* Common Services              */
  136.                                             /* DosCreateQueue               */
  137.      extern unsigned short pascal far DosCreateQueue (
  138.             unsigned short far *,
  139.             unsigned short,
  140.             unsigned char far *);
  141.                                             /* DosReadQueue                 */
  142.      extern unsigned short pascal far DosReadQueue (
  143.             unsigned short,
  144.             unsigned long far *,
  145.             unsigned short far *,
  146.             unsigned long far *,
  147.             unsigned char,
  148.             unsigned char,
  149.             unsigned char far *,
  150.             void far *);
  151.                                             /* DosGetShrSeg                 */
  152.      extern unsigned short pascal far DosGetShrSeg (
  153.             unsigned char far *,
  154.             unsigned short far *);
  155.                                             /* DosSubFree                   */
  156.      extern unsigned short pascal far DosSubFree (
  157.             unsigned short,
  158.             unsigned short,
  159.             unsigned short);
  160.                                             /* DosSleep                     */
  161.      extern unsigned short pascal far DosSleep (
  162.             unsigned long);
  163.  
  164. /***********************************************************/
  165. /*            Verb Parameter Values                        */
  166. /***********************************************************/
  167.  
  168.    #define  ADAPT_0  0x00
  169.    #define  ADAPT_1  0x01
  170.    #define  ADAPT_2  0x02
  171.    #define  ADAPT_3  0x03
  172.    #define  ADAPT_4  0x04
  173.    #define  ADAPT_5  0x05
  174.    #define  ADAPT_6  0x06
  175.    #define  ADAPT_7  0x07
  176.  
  177.    char TOKEN_RING[] = "IBMTRNET";
  178.    char PC_NET[]     = "IBMPCNET";
  179.    char ETHERAND[]   = "ETHERAND";
  180.    char SDLC[]       = "SDLC    ";
  181.    char X25[]        = "X25DLC  ";
  182.    char TWINAX[]     = "TWINAX  ";
  183.  
  184. /***********************************************************/
  185. /*                Return Codes                             */
  186. /***********************************************************/
  187.  
  188.    #define  AP_COMM_SUBSYSTEM_ABENDED                 0x03F0
  189.    #define  AP_COMM_SUBSYSTEM_NOT_LOADED              0x04F0
  190.    #define  AP_INVALID_VERB_SEGMENT                   0x08F0
  191.    #define  AP_OK                                     0x0000
  192.    #define  AP_PARAMETER_CHECK                        0x0100
  193.    #define  AP_STATE_CHECK                            0x0200
  194.    #define  AP_UNEXPECTED_DOS_ERROR                   0x11F0
  195.    #define  AP_STACK_TOO_SMALL                        0x15F0
  196.  
  197.    #define  AP_NO_PU_ATTACHED                         0x08000000
  198.    #define  AP_DLC_FAILURE                            0x83020000
  199.    #define  AP_UNRECOGNIZED_DLC                       0x84020000
  200.    #define  AP_DUPLICATE_DLC                          0x86020000
  201.    #define  AP_ADAPTER_NOT_OPEN                       0x00020000
  202.  
  203.    #define SV_INVALID_VERB_SEGMENT                    0x08F0
  204.    #define SV_INVALID_VERB                            0xFFFF
  205.    #define SV_OK                                      0x0000
  206.    #define SV_PARAMETER_CHECK                         0x0100
  207.    #define SV_COMM_SUBSYSTEM_NOT_LOADED               0x12F0
  208.    #define SV_STATE_CHECK                             0x0200
  209.    #define SV_INVALID_KEY                             0x20F0
  210.    #define SV_UNEXPECTED_DOS_ERROR                    0x11F0
  211.  
  212.    #define SV_INVALID_FORWARD                         0x00070000
  213.    #define SV_INVALID_SUPPRESS                        0x01070000
  214.    #define SV_INVALID_SELECTION                       0x02070000
  215.    #define SV_TOO_HIGH_A_NUMBER                       0x03070000
  216.    #define SV_INVALID_QUEUE                           0x04070000
  217.    #define SV_QUEUE_ALREADY_IN_EFFECT                 0x05070000
  218.  
  219. /***********************************************************/
  220. /*               Operation Codes                           */
  221. /***********************************************************/
  222.  
  223.    #define AP_ACTIVATE_DLC                            0x002B
  224.    #define SV_SET_USER_LOG_QUEUE                      0x004B
  225.  
  226.    /**********************************************************/
  227.    /*            Application Control Interface               */
  228.    /**********************************************************/
  229.  
  230.  struct act_dlc
  231.      {
  232.      unsigned short  opcode;       /* Verb operation code      */
  233.      unsigned char   opext;        /* Verb extension code      */
  234.      unsigned char   reserv2;      /* Reserved                 */
  235.      unsigned char   primary_rc[2];/* Primary RETURN_CODE      */
  236.      unsigned long   secondary_rc; /* Secondary RETURN_CODE    */
  237.      unsigned char   keylock[8];   /* Keylock                  */
  238.      unsigned char   dlc_name[8];  /* DLC NAME                 */
  239.      unsigned char   adapt_num;    /* Adapter Number           */
  240.      unsigned char   reserv4[25];  /* Reserved                 */
  241.      };
  242.  
  243.  struct set_user_log_queue
  244.      {
  245.      unsigned short opcode;       /* Verb operation code      */
  246.      unsigned char opext;         /* Verb extension code      */
  247.      unsigned char reserv2;       /* Reserved                 */
  248.      unsigned char primary_rc[2]; /* Primary RETURN_CODE      */
  249.      unsigned long secondary_rc;  /* Secondary RETURN_CODE    */
  250.      unsigned char key[8];        /* KEY                      */
  251.      unsigned char queue_name[64];/* QUEUE_NAME               */
  252.      unsigned char forward;       /* FORWARD                  */
  253.                                   /*   SV_LOGS                */
  254.                                   /*   SV_SYSTEM_MESSAGES     */
  255.                                   /*   SV_USER_MESSAGES       */
  256.      unsigned char suppress;      /* SUPPRESS                 */
  257.                                   /*   SV_ALL                 */
  258.                                   /*   SV_FORWARD             */
  259.                                   /*   SV_NONE                */
  260.      unsigned char selection;     /* SELECTION                */
  261.                                   /*   SV_ALL                 */
  262.                                   /*   SV_SOME                */
  263.      unsigned char number[2];     /* NUMBERS                  */
  264.      };
  265.  
  266.  union verbs
  267.      {
  268.      struct act_dlc ad;
  269.      struct set_user_log_queue sulq;
  270.      } vcb;
  271.  
  272.  struct error_log_queue_element
  273.      {
  274.      unsigned short elqqueue_id;  /* Verb operation code      */
  275.      unsigned char reserv2[8];    /* Reserved                 */
  276.      unsigned char elqhour;       /* Hour                     */
  277.      unsigned char elqminute;     /* Minute                   */
  278.      unsigned char elqsecond;     /* Second                   */
  279.      unsigned char elqhundred;    /* Hundreth of second       */
  280.      unsigned char elqday;        /* Day                      */
  281.      unsigned char elqmonth;      /* Month                    */
  282.      unsigned short elqyear;      /* Year                     */
  283.      unsigned short elqtype;      /* Error Type               */
  284.      unsigned long elqsubtype;    /* Error Subtype            */
  285.      unsigned char elqconv_id[4]; /* Conversation ID          */
  286.      unsigned char elqorig_id[8]; /* Originator ID            */
  287.      unsigned char reserv3[4];    /* Reserved                 */
  288.      unsigned short elqpid;       /* Process ID               */
  289.      unsigned short elqlength;    /* Element Length           */
  290.      unsigned char elqdata[20];   /* Element Data             */
  291.      } far *error_log_ptr;
  292.  
  293. /*--------------------------------------------------------------------------*/
  294. /*                       Function Prototypes                                */
  295. /*--------------------------------------------------------------------------*/
  296.  
  297. void main(int, char **);
  298. void COPY_ERROR_LOG(void);                  /* Copy Error Log               */
  299. void SET_LOG_QUEUE(void);                   /* Set User Log Queue           */
  300. void ACTIVATE_DLC(void);                    /* Activate DLC                 */
  301.  
  302. /****************************************************************************/
  303. /*                                                                          */
  304. /*                       Main Program Section                               */
  305. /*                                                                          */
  306. /****************************************************************************/
  307.  
  308. void
  309. main (argc, argv)                           /* Need argc,argv to get        */
  310.                                             /* Time interval                */
  311. int  argc;
  312. char *argv[];
  313.  
  314. {
  315.   if (argc > 0) {
  316.      time_interval = atol(argv[1]) * 1000;  /* Convert to Milliseconds      */
  317.      if (time_interval < 45000 ) {          /* Minumum 45 seconds allows for*/
  318.         time_interval = 45000;              /* DLC to detect Adapter Failure*/
  319.      }
  320.   } else {
  321.      time_interval = 45000;
  322.   }
  323.                                             /* after restarting             */
  324.   buffer_length = 20000;                    /* Copy all ERROR.DAT with one  */
  325.                                             /* Read and Write               */
  326.   error_file_name.file_extension = 64;      /* 65 = ASCII 'A'               */
  327.   memcpy (error_file_name.new_file_name,"C:\\CMLIB\\ERRSAV.",16);
  328.  
  329.   printf("\nTime Interval in milliseconds:  %lu", time_interval);
  330.   qsemhandle = 0;                          /* Queue semephore not used     */
  331.  
  332.   SET_LOG_QUEUE();
  333.      while (1 == 1) {
  334.         printf("\nWaiting for Adapter Failure");
  335.                                             /* Read Queue with WAIT option  */
  336.         error_code = DosReadQueue(qhandle,
  337.                                   &qrequest,
  338.                                   &qlength,
  339.                                   &lp.log_ptr,
  340.                                   FIFO,
  341.                                   WAIT,
  342.                                   &qpriority,
  343.                                   qsemhandle);
  344.         printf("\nRead Queue Wait error code:  %u", error_code);
  345.         printf("\nError Log Subtype:  %lu", lp.error_log_ptr->elqsubtype);
  346.                                             /* If error subtype 00000002    */
  347.                                             /* then it is either a link     */
  348.                                             /* or an adapter failure.       */
  349.                                             /* Treat as an adapter failure  */
  350.         if (lp.error_log_ptr->elqsubtype == 2) {
  351.                                             /* Free the memory for the      */
  352.                                             /* error log                    */
  353.               error_code = DosSubFree (SELECTOROF(lp.error_log_ptr),
  354.                                        OFFSETOF(lp.error_log_ptr),
  355.                                        44 + lp.error_log_ptr->elqlength);
  356.               printf("\nDosSubFree error code:  %u", error_code);
  357.                                             /* Copy ERROR.DAT to save       */
  358.                                             /* previous errors because the  */
  359.                                             /* error log may get many       */
  360.                                             /* errors from an adapt failure */
  361.               COPY_ERROR_LOG();
  362.                                             /* Reactivate the DLC           */
  363.               ACTIVATE_DLC();
  364.                                             /* Set retry mode on to keep    */
  365.                                             /* reactivating until it works  */
  366.                                             /* or this program is manually  */
  367.                                             /* terminated.                  */
  368.               retry_mode = ON;
  369.                                             /* This loop is repeated until  */
  370.                                             /* the adapter reactivates      */
  371.                                             /* successfully.                */
  372.               while (retry_mode == ON) {
  373.                                             /* Sleep to let the adapter     */
  374.                                             /* fail if it is going to.      */
  375.                  printf("\nSleeping %lu Seconds",time_interval / 1000);
  376.                  error_code = DosSleep(time_interval);
  377.                  printf("\nDosSleep error code:  %u", error_code);
  378.                                             /* Check if another error was   */
  379.                                             /* received while sleeping.     */
  380.                  error_code = DosReadQueue(qhandle,
  381.                                            &qrequest,
  382.                                            &qlength,
  383.                                            &lp.log_ptr,
  384.                                            FIFO,
  385.                                            NOWAIT,
  386.                                            &qpriority,
  387.                                            qsemhandle);
  388.                  printf("\nRead Queue Nowait error code:  %u", error_code);
  389.                                             /* If the queue is empty then   */
  390.                                             /* the adapter must have        */
  391.                                             /* reactivated successfully.    */
  392.                  if (error_code == ERROR_QUE_EMPTY) {
  393.                     retry_mode = OFF;
  394.                  } else {
  395.                                             /* If error is not subtype 2    */
  396.                                             /* then the adapter must have   */
  397.                                             /* reactivated successfully.    */
  398.                     if (lp.error_log_ptr->elqsubtype == 2) {
  399.                        ACTIVATE_DLC();
  400.                        } else {
  401.                           retry_mode = OFF;
  402.                        } /* endif */
  403.                     } /* endif */
  404.                  } /* endif */
  405.               } /* endwhile */
  406.      } /* endwhile */
  407.  
  408. }
  409.  
  410. /****************************************************************************/
  411. /*                                                                          */
  412. /*                            FUNCTIONS                                     */
  413. /*                                                                          */
  414. /****************************************************************************/
  415.  
  416. void
  417. SET_LOG_QUEUE ()
  418. {
  419.    strcpy (qname,"\\QUEUES\\ERRLOG17");     /* Create the Queue             */
  420.    error_code = DosCreateQueue(&qhandle,FIFO,qname);
  421.    printf("\nCreate Queue error code:  %u", error_code);
  422.    strcpy (mname,"\\SHAREMEM\\ACSLGMEM");   /* Access the memory where CM   */
  423.    error_code = DosGetShrSeg(mname,&msel);  /* puts the error log           */
  424.    while (error_code == 2) {
  425.       printf("\nWaiting for 30 seconds for Comm Mgr to start");
  426.       DosSleep(thirty_seconds);
  427.       error_code = DosGetShrSeg(mname,&msel);
  428.    } /* endif */
  429.    printf("\nGet Share Memory error code:  %u", error_code);
  430.    clear_vcb();
  431.    vcb.sulq.opcode = SV_SET_USER_LOG_QUEUE;
  432.    strcpy (vcb.sulq.queue_name, qname);     /* Queue name                   */
  433.    vcb.sulq.forward = LOGS;                 /* Receive LOGS only            */
  434.    vcb.sulq.suppress = ALL;                 /* Suppress all onscreen msgs   */
  435.    vcb.sulq.selection = SOME;               /* Receive some error logs      */
  436.    vcb.sulq.number[0] = 23;                 /* Receive only Type 0017       */
  437.    vcb.sulq.number[1] = 0;                  /*                              */
  438.    vcbptr = (unsigned far *)&vcb;
  439.    ACSSVC((long) vcbptr);                   /* Call Common Services         */
  440.    printf("\nSet User Log Queue primary rc:  %2.2x%2.2x",
  441.           vcb.sulq.primary_rc[0], vcb.sulq.primary_rc[1]);
  442. }
  443.  
  444. void
  445. COPY_ERROR_LOG ()
  446. {
  447.    strcpy (error_dat, "C:\\CMLIB\\ERROR.DAT");
  448.                                             /* Start with ERRSAV.A and find */
  449.                                             /* the first available file.    */
  450.    do {
  451.       error_file_name.file_extension = error_file_name.file_extension + 1;
  452.    } while (access(error.filename,0) == 0);
  453.                                             /* Copy ERROR.DAT to the new    */
  454.                                             /* file.                        */
  455.    fhandle_new = open(error.filename, WRITEBINARY);
  456.    fhandle_error = open(error_dat, READBINARY);
  457.    bytes_read = read(fhandle_error, buffer, buffer_length);
  458.    bytes_written = write(fhandle_new, buffer, bytes_read);
  459.    close(fhandle_new);
  460.    close(fhandle_error);
  461.    printf ("\nError Log %s created ",&error_file_name);
  462. }
  463.  
  464. void
  465. ACTIVATE_DLC ()
  466. {
  467.   clear_vcb();                                /* Zero the vcb               */
  468.   vcb.ad.opcode = AP_ACTIVATE_DLC;            /* MGMT verb - ACTIVATE_DLC   */
  469.   memcpy (vcb.ad.dlc_name, SDLC, 8);
  470.                                               /* Set DLC Name               */
  471.   vcb.ad.adapt_num = ADAPT_0;                 /* Set Adapter Number         */
  472.  
  473.   vcbptr = (unsigned far *)&vcb;              /* Get pointer to the vcb     */
  474.  
  475.   ACSMGTI((long) vcbptr);                     /* Call MGMT Services         */
  476.   printf("\nActivate DLC primary rc:  %2.2x%2.2x",
  477.          vcb.sulq.primary_rc[0], vcb.sulq.primary_rc[1]);
  478.  
  479. }
  480.  
  481.  
  482. /* EOF - REACTDLC.C */
  483.