home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
REACTDLC.ZIP
/
reactdlc.c
< prev
next >
Wrap
Text File
|
1992-12-21
|
25KB
|
483 lines
/*************************************************************************/
/* */
/* MODULE NAME : REACTDLC.C */
/* */
/* DESCRIPTIVE : REACTIVATE DLC "C" SAMPLE PROGRAM */
/* */
/* FUNCTION: Issues a ACTIVATE_DLC when an error log type 17 */
/* and subtype 2 is received on the log queue. */
/* */
/* NOTES: 1. When an adapter fails this program will attempt */
/* to reactivate the DLC at regular intervals. If */
/* the adapter is in a condition such that it can not */
/* reactivated successfully then this program may */
/* attempt many times. Each attempt will cause one */
/* or two errors to be logged. For this reason the */
/* error log is copied to another file for safe keeping. */
/* Also the error log should be configured to wrap */
/* instead of extend as the error log could grow very */
/* large in some unattended situations. */
/* */
/* 2. Messages should be configured not to pop up because */
/* adapter failures generate pop up messages and many */
/* could get queued to the screen. */
/* */
/* 3. The ACTIVATE_DLC verb is not officially 'external'. */
/* Communications Manager reserves to right to modifiy */
/* the verb control block if necessay. */
/* */
/* 4. Link failures also create error log type 17 subtype 2 */
/* entries and this program does not distinguish */
/* between the two. If ACTIVATE_DLC is issued when */
/* the DLC is open then no harm is done only a return */
/* code indicating DUPLICATE_DLC. */
/* */
/* 5. This program must be modified for different DLCs and */
/* adapters. Currently this program is coded to only */
/* reactivate the Token Ring adapter 0. */
/* */
/* FORMAT: REACTDLC time_interval */
/* */
/* time_interval - Time between attempts to restart the */
/* the adapter with ACTIVATE_DLC. The */
/* time is in seconds and the minimum is */
/* 45 seconds. This allows time for the */
/* adapter to determine an error condition */
/* after reactivating. */
/* */
/* EXAMPLE: REACTDLC 50 */
/* */
/* MODULE: IBM Personal Computer C/2 Compiler (Version 1.1) */
/* TYPE (Compiles with Small Memory Model) */
/* */
/*************************************************************************/
#include <STDIO.H>
#include <STDDEF.H>
#include <STDLIB.H>
#include <STRING.H>
#include <io.h>
/* Macro clear_vcb sets the APPC verb control block to zeros */
#define clear_vcb() memset(&vcb,(int)'\0',sizeof(vcb))
/* Extract selector or offset from far pointer */
#define SELECTOROF(p) (((unsigned short *)&(p))[1])
#define OFFSETOF(p) (((unsigned short *)&(p))[0])
/***********************************************************/
/* General Declares */
/***********************************************************/
unsigned far *vcbptr; /* Pointer to the vcb */
unsigned long time_interval; /* Time between retry attempts */
unsigned long thirty_seconds = 30000; /* Wait time for CM to start */
unsigned short error_code; /* Dos Call return code */
unsigned short qhandle; /* Queue handle */
unsigned long qrequest; /* Queue request */
unsigned char qpriority; /* Queue priority */
void far *qsemhandle; /* Queue semephore handle */
unsigned short qlength; /* Queue element length */
unsigned char qname[17]; /* Queue name \QUEUES\ERRLOG17 */
unsigned char retry_mode; /* Flag to indicate retry mode */
unsigned char error_dat[19]; /* Error file ERROR.DAT */
unsigned short fhandle_new; /* File handle */
unsigned short fhandle_error; /* File handle */
unsigned char buffer[20000]; /* Buffer for ERROR.DAT */
unsigned short buffer_length; /* Buffer length */
unsigned short bytes_read; /* Size of ERROR.DAT */
unsigned short bytes_written; /* */
unsigned short msel; /* Selector of CM shared mem */
unsigned char mname[24]; /* Memory \SHAREMEM\ACSLGMEM */
unsigned char prim_rc_prt[2]; /* Primary Return code swapped */
struct new_file /* File name for copied err log */
{
unsigned char new_file_name[16]; /* File name ERRSAV. in CMLIB */
unsigned short file_extension; /* File ext A - Z */
} error_file_name;
union
{
unsigned long log_ptr;
struct error_log_queue_element far *error_log_ptr;
} lp;
union
{
unsigned char filename[18];
struct new_file error_file_name;
} error;
/***********************************************************/
/* General Constants */
/***********************************************************/
#define ON 0x01
#define OFF 0x00
#define LOGS 0x00
#define ALL 0x01
#define SOME 0x00
#define FIFO 0x0000
#define WAIT 0x00
#define NOWAIT 0x01
#define WRITE 0000200 /* write permission, owner */
#define READBINARY 0x8000 /* open for reading only */
#define WRITEBINARY 0x8101 /* open for writing only */
#define ERROR_QUE_EMPTY 342 /* DosReadQueue error code */
/***********************************************************/
/* External Entry Points */
/***********************************************************/
extern void pascal far ACSMGTI(long); /* Managment Services */
extern void pascal far ACSSVC(long); /* Common Services */
/* DosCreateQueue */
extern unsigned short pascal far DosCreateQueue (
unsigned short far *,
unsigned short,
unsigned char far *);
/* DosReadQueue */
extern unsigned short pascal far DosReadQueue (
unsigned short,
unsigned long far *,
unsigned short far *,
unsigned long far *,
unsigned char,
unsigned char,
unsigned char far *,
void far *);
/* DosGetShrSeg */
extern unsigned short pascal far DosGetShrSeg (
unsigned char far *,
unsigned short far *);
/* DosSubFree */
extern unsigned short pascal far DosSubFree (
unsigned short,
unsigned short,
unsigned short);
/* DosSleep */
extern unsigned short pascal far DosSleep (
unsigned long);
/***********************************************************/
/* Verb Parameter Values */
/***********************************************************/
#define ADAPT_0 0x00
#define ADAPT_1 0x01
#define ADAPT_2 0x02
#define ADAPT_3 0x03
#define ADAPT_4 0x04
#define ADAPT_5 0x05
#define ADAPT_6 0x06
#define ADAPT_7 0x07
char TOKEN_RING[] = "IBMTRNET";
char PC_NET[] = "IBMPCNET";
char ETHERAND[] = "ETHERAND";
char SDLC[] = "SDLC ";
char X25[] = "X25DLC ";
char TWINAX[] = "TWINAX ";
/***********************************************************/
/* Return Codes */
/***********************************************************/
#define AP_COMM_SUBSYSTEM_ABENDED 0x03F0
#define AP_COMM_SUBSYSTEM_NOT_LOADED 0x04F0
#define AP_INVALID_VERB_SEGMENT 0x08F0
#define AP_OK 0x0000
#define AP_PARAMETER_CHECK 0x0100
#define AP_STATE_CHECK 0x0200
#define AP_UNEXPECTED_DOS_ERROR 0x11F0
#define AP_STACK_TOO_SMALL 0x15F0
#define AP_NO_PU_ATTACHED 0x08000000
#define AP_DLC_FAILURE 0x83020000
#define AP_UNRECOGNIZED_DLC 0x84020000
#define AP_DUPLICATE_DLC 0x86020000
#define AP_ADAPTER_NOT_OPEN 0x00020000
#define SV_INVALID_VERB_SEGMENT 0x08F0
#define SV_INVALID_VERB 0xFFFF
#define SV_OK 0x0000
#define SV_PARAMETER_CHECK 0x0100
#define SV_COMM_SUBSYSTEM_NOT_LOADED 0x12F0
#define SV_STATE_CHECK 0x0200
#define SV_INVALID_KEY 0x20F0
#define SV_UNEXPECTED_DOS_ERROR 0x11F0
#define SV_INVALID_FORWARD 0x00070000
#define SV_INVALID_SUPPRESS 0x01070000
#define SV_INVALID_SELECTION 0x02070000
#define SV_TOO_HIGH_A_NUMBER 0x03070000
#define SV_INVALID_QUEUE 0x04070000
#define SV_QUEUE_ALREADY_IN_EFFECT 0x05070000
/***********************************************************/
/* Operation Codes */
/***********************************************************/
#define AP_ACTIVATE_DLC 0x002B
#define SV_SET_USER_LOG_QUEUE 0x004B
/**********************************************************/
/* Application Control Interface */
/**********************************************************/
struct act_dlc
{
unsigned short opcode; /* Verb operation code */
unsigned char opext; /* Verb extension code */
unsigned char reserv2; /* Reserved */
unsigned char primary_rc[2];/* Primary RETURN_CODE */
unsigned long secondary_rc; /* Secondary RETURN_CODE */
unsigned char keylock[8]; /* Keylock */
unsigned char dlc_name[8]; /* DLC NAME */
unsigned char adapt_num; /* Adapter Number */
unsigned char reserv4[25]; /* Reserved */
};
struct set_user_log_queue
{
unsigned short opcode; /* Verb operation code */
unsigned char opext; /* Verb extension code */
unsigned char reserv2; /* Reserved */
unsigned char primary_rc[2]; /* Primary RETURN_CODE */
unsigned long secondary_rc; /* Secondary RETURN_CODE */
unsigned char key[8]; /* KEY */
unsigned char queue_name[64];/* QUEUE_NAME */
unsigned char forward; /* FORWARD */
/* SV_LOGS */
/* SV_SYSTEM_MESSAGES */
/* SV_USER_MESSAGES */
unsigned char suppress; /* SUPPRESS */
/* SV_ALL */
/* SV_FORWARD */
/* SV_NONE */
unsigned char selection; /* SELECTION */
/* SV_ALL */
/* SV_SOME */
unsigned char number[2]; /* NUMBERS */
};
union verbs
{
struct act_dlc ad;
struct set_user_log_queue sulq;
} vcb;
struct error_log_queue_element
{
unsigned short elqqueue_id; /* Verb operation code */
unsigned char reserv2[8]; /* Reserved */
unsigned char elqhour; /* Hour */
unsigned char elqminute; /* Minute */
unsigned char elqsecond; /* Second */
unsigned char elqhundred; /* Hundreth of second */
unsigned char elqday; /* Day */
unsigned char elqmonth; /* Month */
unsigned short elqyear; /* Year */
unsigned short elqtype; /* Error Type */
unsigned long elqsubtype; /* Error Subtype */
unsigned char elqconv_id[4]; /* Conversation ID */
unsigned char elqorig_id[8]; /* Originator ID */
unsigned char reserv3[4]; /* Reserved */
unsigned short elqpid; /* Process ID */
unsigned short elqlength; /* Element Length */
unsigned char elqdata[20]; /* Element Data */
} far *error_log_ptr;
/*--------------------------------------------------------------------------*/
/* Function Prototypes */
/*--------------------------------------------------------------------------*/
void main(int, char **);
void COPY_ERROR_LOG(void); /* Copy Error Log */
void SET_LOG_QUEUE(void); /* Set User Log Queue */
void ACTIVATE_DLC(void); /* Activate DLC */
/****************************************************************************/
/* */
/* Main Program Section */
/* */
/****************************************************************************/
void
main (argc, argv) /* Need argc,argv to get */
/* Time interval */
int argc;
char *argv[];
{
if (argc > 0) {
time_interval = atol(argv[1]) * 1000; /* Convert to Milliseconds */
if (time_interval < 45000 ) { /* Minumum 45 seconds allows for*/
time_interval = 45000; /* DLC to detect Adapter Failure*/
}
} else {
time_interval = 45000;
}
/* after restarting */
buffer_length = 20000; /* Copy all ERROR.DAT with one */
/* Read and Write */
error_file_name.file_extension = 64; /* 65 = ASCII 'A' */
memcpy (error_file_name.new_file_name,"C:\\CMLIB\\ERRSAV.",16);
printf("\nTime Interval in milliseconds: %lu", time_interval);
qsemhandle = 0; /* Queue semephore not used */
SET_LOG_QUEUE();
while (1 == 1) {
printf("\nWaiting for Adapter Failure");
/* Read Queue with WAIT option */
error_code = DosReadQueue(qhandle,
&qrequest,
&qlength,
&lp.log_ptr,
FIFO,
WAIT,
&qpriority,
qsemhandle);
printf("\nRead Queue Wait error code: %u", error_code);
printf("\nError Log Subtype: %lu", lp.error_log_ptr->elqsubtype);
/* If error subtype 00000002 */
/* then it is either a link */
/* or an adapter failure. */
/* Treat as an adapter failure */
if (lp.error_log_ptr->elqsubtype == 2) {
/* Free the memory for the */
/* error log */
error_code = DosSubFree (SELECTOROF(lp.error_log_ptr),
OFFSETOF(lp.error_log_ptr),
44 + lp.error_log_ptr->elqlength);
printf("\nDosSubFree error code: %u", error_code);
/* Copy ERROR.DAT to save */
/* previous errors because the */
/* error log may get many */
/* errors from an adapt failure */
COPY_ERROR_LOG();
/* Reactivate the DLC */
ACTIVATE_DLC();
/* Set retry mode on to keep */
/* reactivating until it works */
/* or this program is manually */
/* terminated. */
retry_mode = ON;
/* This loop is repeated until */
/* the adapter reactivates */
/* successfully. */
while (retry_mode == ON) {
/* Sleep to let the adapter */
/* fail if it is going to. */
printf("\nSleeping %lu Seconds",time_interval / 1000);
error_code = DosSleep(time_interval);
printf("\nDosSleep error code: %u", error_code);
/* Check if another error was */
/* received while sleeping. */
error_code = DosReadQueue(qhandle,
&qrequest,
&qlength,
&lp.log_ptr,
FIFO,
NOWAIT,
&qpriority,
qsemhandle);
printf("\nRead Queue Nowait error code: %u", error_code);
/* If the queue is empty then */
/* the adapter must have */
/* reactivated successfully. */
if (error_code == ERROR_QUE_EMPTY) {
retry_mode = OFF;
} else {
/* If error is not subtype 2 */
/* then the adapter must have */
/* reactivated successfully. */
if (lp.error_log_ptr->elqsubtype == 2) {
ACTIVATE_DLC();
} else {
retry_mode = OFF;
} /* endif */
} /* endif */
} /* endif */
} /* endwhile */
} /* endwhile */
}
/****************************************************************************/
/* */
/* FUNCTIONS */
/* */
/****************************************************************************/
void
SET_LOG_QUEUE ()
{
strcpy (qname,"\\QUEUES\\ERRLOG17"); /* Create the Queue */
error_code = DosCreateQueue(&qhandle,FIFO,qname);
printf("\nCreate Queue error code: %u", error_code);
strcpy (mname,"\\SHAREMEM\\ACSLGMEM"); /* Access the memory where CM */
error_code = DosGetShrSeg(mname,&msel); /* puts the error log */
while (error_code == 2) {
printf("\nWaiting for 30 seconds for Comm Mgr to start");
DosSleep(thirty_seconds);
error_code = DosGetShrSeg(mname,&msel);
} /* endif */
printf("\nGet Share Memory error code: %u", error_code);
clear_vcb();
vcb.sulq.opcode = SV_SET_USER_LOG_QUEUE;
strcpy (vcb.sulq.queue_name, qname); /* Queue name */
vcb.sulq.forward = LOGS; /* Receive LOGS only */
vcb.sulq.suppress = ALL; /* Suppress all onscreen msgs */
vcb.sulq.selection = SOME; /* Receive some error logs */
vcb.sulq.number[0] = 23; /* Receive only Type 0017 */
vcb.sulq.number[1] = 0; /* */
vcbptr = (unsigned far *)&vcb;
ACSSVC((long) vcbptr); /* Call Common Services */
printf("\nSet User Log Queue primary rc: %2.2x%2.2x",
vcb.sulq.primary_rc[0], vcb.sulq.primary_rc[1]);
}
void
COPY_ERROR_LOG ()
{
strcpy (error_dat, "C:\\CMLIB\\ERROR.DAT");
/* Start with ERRSAV.A and find */
/* the first available file. */
do {
error_file_name.file_extension = error_file_name.file_extension + 1;
} while (access(error.filename,0) == 0);
/* Copy ERROR.DAT to the new */
/* file. */
fhandle_new = open(error.filename, WRITEBINARY);
fhandle_error = open(error_dat, READBINARY);
bytes_read = read(fhandle_error, buffer, buffer_length);
bytes_written = write(fhandle_new, buffer, bytes_read);
close(fhandle_new);
close(fhandle_error);
printf ("\nError Log %s created ",&error_file_name);
}
void
ACTIVATE_DLC ()
{
clear_vcb(); /* Zero the vcb */
vcb.ad.opcode = AP_ACTIVATE_DLC; /* MGMT verb - ACTIVATE_DLC */
memcpy (vcb.ad.dlc_name, SDLC, 8);
/* Set DLC Name */
vcb.ad.adapt_num = ADAPT_0; /* Set Adapter Number */
vcbptr = (unsigned far *)&vcb; /* Get pointer to the vcb */
ACSMGTI((long) vcbptr); /* Call MGMT Services */
printf("\nActivate DLC primary rc: %2.2x%2.2x",
vcb.sulq.primary_rc[0], vcb.sulq.primary_rc[1]);
}
/* EOF - REACTDLC.C */