#include #include #include #include #define MAX_LEN 1500 #define MAX_CHAN 6 #define ERR -1 #define OK 1 #define READY 1 #define NOT_READY 0 #define SIG_V24 417 #define SIG_ETH 418 #define max(x,y) ((x) > (y) ? (x) : (y)) #define min(x,y) ((x) < (y) ? (x) : (y)) typedef unsigned char uchar; typedef enum {seven_bit, seven_plus, eight_bit} traffic_type; int vpath[MAX_CHAN]; char *term[MAX_CHAN] = {"/term","/t1","/t2","/t3","/t4","/t5"}; char sys_com[220]; char com[220]; extern int dataready; extern void rpc_os9_init(); /* Initialise a V24 channel v24_open() ** */ v24_open(chan,baud, traffic_bits, trace) int chan, baud; traffic_type traffic_bits; char trace; { /* * tsmon for correct channel must be disabled before setup. * However, never disable /term !! * Set-up the port here, i.e. baud rate ... */ int istat; rpc_os9_init(); /* Set up intercept handler */ if (chan <=0 || chan > (MAX_CHAN -1) ) { printf(" FATAL ERROR: addressing unsupported port number %d\n",chan); return( ERR); } istat = check_tsmon(term[chan]); if (istat != OK) return ERR; istat = setup_port(term[chan],baud,traffic_bits); if (istat != OK) return ERR; dataready = NOT_READY; /* set the flag */ vpath[chan] = open(term[chan], S_IREAD | S_IWRITE); if (vpath[chan] >=3 ){ if (trace) printf(" OPEN vpath %d\n",vpath[chan]); istat = _ss_ssig(vpath[chan],SIG_V24); return OK; } if (trace) printf(" V24_OPEN ERROR\n"); return ERR; } v24_close(chan) int chan; { close(vpath[chan]); enable_tsmon(term[chan]); return OK; } v24_get(buf,len,timeout,chan,trace) uchar *buf; int len, timeout, chan; char trace; { int nch,n_byte, n_loop, istat, mod_time; if (dataready == NOT_READY) { if (timeout != -1) { mod_time = abs(timeout); tsleep((mod_time | 0x80000000)); /* 100/256th of a second */ } else sleep(0); } if (dataready == READY ) { if ((n_byte = _gs_rdy(vpath[chan])) != ERR) { nch = read(vpath[chan],buf,len); if (trace) printf(" V24_GET %2x %d\n",(*buf), (*buf)); return OK; } else { printf(" NO DATA \n"); return ERR; } } /* printf(" V24_GET ERROR in reading from path %d\n",vpath[chan]); */ return ERR; } v24_send(buf,len,chan,trace) uchar *buf; int len, chan; char trace; { int stat, istat; /* GET READY FOR ACCEPTING DATA */ dataready = NOT_READY; if (setsigmask(1) == -1 ) printf(" Can't set signal mask error= %d\n", errno); stat = _ss_ssig(vpath[chan],SIG_V24); if (trace) for (stat =0; stat < len && stat < 40; stat++) printf(" V24_SEND %2x %d\n", *(buf+stat), *(buf+stat)); stat = write(vpath[chan],buf,len); if (stat == len) { istat = _ss_ssig(vpath[chan],SIG_V24); return OK; } /* printf(" V24_SEND ERROR in sending to path %d\n",vpath[chan]); */ return ERR; } void v24_clear(chan) int chan; { /* ** clear the output */ uchar buf[MAX_LEN]; int i, nch; while ((nch = _gs_rdy(vpath[chan])) != ERR) { /* ** printf(" V24_CLEAR path %d bytes %d\n",vpath[chan],nch); */ i = read(vpath[chan],buf,nch); } } /* * THESE ARE THE TSMON CONTROL ROUTINES * OPAL SPECIFIC !!!! */ setup_port(term, speed, bits) char *term; int speed; traffic_type bits; { int path, pos, i, j, rem, next; char rate[6]; static char *b7[3] = {"noupc bsb nobsl noecho nolf null=0 nopause pag=0 bsp=00 del=18", " eor=0D eof=02 reprint=04 dup=01 psc=17 abort=03 quit=05 ", "bse=08 bell=07 type=00 baud=00000 xon=11 xoff=13 tabc=09 tabs=4"}; static char *b8[3] = {"noupc bsb nobsl noecho nolf null=0 nopause pag=0 bsp=00 del=00", " eor=00 eof=00 reprint=00 dup=00 psc=00 abort=00 quit=00 ", "bse=00 bell=00 type=00 baud=00000 xon=00 xoff=00 tabc=00 tabs=0"}; /* setup the terminal here using XMODE commands; note device descriptor * must be in modifiable address space. * Also find out whether the descriptor has turned into what we want. */ /* DISABLE PROGRAMS USING THE PORT */ i = disable_tsmon(term); /* CHECK THAT WE HAVE A LEGAL BAUD RATE (default 9600) */ if (speed != 300 && speed != 600 && speed != 1200 && speed != 1800 && speed != 2400 && speed != 3600 && speed != 4800 && speed != 7200 && speed != 9600 && speed != 19200) speed = 9600; /* CONVERT THE BAUD RATE TO ASCII */ pos = 10000; rem = 0; for (i = 5; i > 0; --i) { next = (speed - rem) / pos; rate[5-i] = next + '0'; rem += next * pos; pos = pos / 10; } rate[6] = '\0'; /* MOVE THE NUMBERS TO DELETE LEADING 0'S */ while (rate[0] == '0') { for (pos = 0; pos <= 3; ++pos) rate[pos] = rate[pos+1]; rate[4] = 0x20; } /* ASSEMBLE THE COMMAND */ com[0]='\0'; if (bits == eight_bit) for (i=0; i<=2; ++i) strcat( com, b8[i]); else for (i=0; i<=2; ++i) strcat( com, b7[i]); /* PUT IN THE BAUD RATE ; SAVE THE com STRING */ i = findstr(130,com,"baud="); strncpy(&com[i+4], rate, 5); /* GET THE RID OF THE POSSIBLE BLANKS AFTER BAUD RATE */ while ( (i = findstr(130,com," ")) != 0) { strcpy(&com[i],&com[i+1]); } /* DEINIZ THE PORT */ sys_command("deiniz",term); sys_command("deiniz",term); sys_command("deiniz",term); /* SET UP THE XMODE COMMAND */ strcpy( &sys_com[0],"xmode "); strcat( &sys_com[6], term); pos = 6 + strlen(term); sys_com[pos] = '\0'; strcat(sys_com," "); strcat( &sys_com[pos], com); system(sys_com); /* INITIALIZE */ sys_command("iniz",term); /* GET THE FINAL PORT CHARACTERISTICS (THE ONES WE JUST SET) */ strcpy(sys_com,"xmode "); strcat( sys_com,term); strcat( sys_com," >-/queue/xm_temp"); system(sys_com); /* COMPARE FINAL CHARACTERISTICS WITH THOSE IN com STRING */ path = open("/queue/xm_temp",S_IREAD); pos = read(path,sys_com,359); close(path); sys_com[pos] = '\0'; /* GET RID OF THE PORT NAME AND CARRIAGE CONTROLS */ i = strlen(term); strcpy(&sys_com[0],&sys_com[i+1]); /* GET THE STRING END RIGHT */ i = findstr(pos-20,sys_com,"tabs="); pos = strlen(sys_com); for (j = pos; j > i; --j) if (sys_com[j] <= 0x0d) sys_com[j] = '\0'; pos = strlen(sys_com); for (i = 0; i <= pos; ++i) if (sys_com[i] == 0x0d) sys_com[i] = 0x20; /* COMPARE WITH WHAT WE SET UP */ j = strlen(com); pos = _cmpnam(com,sys_com,j); if (pos != 0) { printf(" %d \n",pos); printf(" ERROR: device descriptor not changed. \n"); return (ERR); } return OK; } check_tsmon(term) char *term; /* CHECK THAT DESCRIPTOR IS IN PROPER PLACE, AND NO PROCESSES CONNECTED */ { int last, first, diff; int i, j , path; /* SET UP THE mdir COMMAND */ sys_com[0]='\0'; strcat(sys_com,"mdir -e "); strcat(sys_com,(term+1)); strcat(sys_com," >>>-/queue/mdir"); system(sys_com); /* READ THE mdir OUTPUT */ j = 0; path = open("/queue/mdir",S_IREAD); while ( (i = readln(path,sys_com,100)) != 0 ) { sys_com[i] = '\0'; ++j; if (j == 3) break; } close(path); system("del /queue/mdir"); /* DECODE THE mdir OUTPUT */ last = first = 0; j = 0; while (last <= strlen(sys_com)) { if (sys_com[last] > 0x20) { first = last; while (sys_com[++last] > 0x20) ; diff = last-first; strcpy(com, (sys_com+first), diff); com[diff] = '\0'; switch (j) { case 0: if (findstr(1,com,"doe") == 1 || findstr(1,com,"DOE") == 1) { printf(" module has been relocated \n"); relocate(term); return OK; } else if (diff <= 7 && findstr(1,com,"00") == 1) { printf(" module has been relocated \n"); relocate(term); return OK; } break; case 7: if ( atoi(com) > 2) { printf(" ERROR: processes linked to this module\n"); return ERR; } break; default: break; } } ++last; } return OK; } disable_tsmon(term) char *term; { char pid[5]; int pos,path,nch; nch = 0; sys_com[0]='\0'; strcpy(&sys_com[0],"procs -e ! grep \">"); strcat(sys_com, term+1); strcat(sys_com,"\" >/queue/k_tsmon"); system(sys_com); path = open("/queue/k_tsmon", S_IREAD); for (pos=0; pos < 10; pos++) { while (_gs_rdy(path) != ERR) { nch = readln(path,sys_com,100); if (nch > 5) { strncpy(pid,sys_com,3); pid[3]='\0'; strcpy(sys_com,"echo >+/pipe/rshell \"kill "); strcat(sys_com,pid); strcat(sys_com,"\""); printf(" %s \n",sys_com); system(sys_com); } else goto jump_out; } tsleep(20); } jump_out: close(path); return (OK); } enable_tsmon(term) char *term; { int i, pos; static char *def[3] = {" noupc bsb nobsl echo lf null=0 nopause pag=24 bsp=7F del=18 ", "eor=0D eof=02 reprint=04 dup=01 psc=17 abort=03 quit=05 ", "bse=08 bell=07 type=00 baud=9600 xon=11 xoff=13 tabc=09 tabs=4"}; /* RESET THE SUCKER */ /* DEINIZ */ strcpy( sys_com,"deiniz "); strcat( &sys_com[5], (term+1)); system(sys_com); /* SETUP THE DEFAULT XMODE COMMANDS */ sys_com[0]='\0'; strcpy(sys_com,"xmode "); strcat(sys_com,term); pos = strlen(sys_com); for (i = 0; i <=2; ++i) { strcpy(&sys_com[pos],def[i]); system(sys_com); } /* INIZ */ strcpy( sys_com,"iniz "); strcat( &sys_com[5], (term+1)); system(sys_com); /* INSTALL TSMON */ strcpy(sys_com,"tsmon "); strcat(sys_com,term); strcat(sys_com," &"); system(sys_com); return (OK); } relocate(term) char *term; { /* RELOCATE THE MODULE */ sys_command("deiniz",term); sys_command("newrev",term); sys_command("iniz",term); } sys_command(pcom,term) char *pcom; char *term; { strcpy(sys_com,"echo >+/pipe/rshell \""); strcat(sys_com,pcom); strcat(sys_com," "); strcat(sys_com, (term+1)); strcat(sys_com," \""); system(sys_com); } /* Set the OS9 Signal Mask setsigmask() ** ----------------------- ** ** rpc_status setsigmask(signal_number s) ** ** This function allows signals to be queued when the task is ** not ready to receive them. It is called once to set up this way of ** working. ** ** On entry, ** ** The parameteter is the signal number which is to be treated ** in this way. ** */ #asm setsigmask move.l d0,d1 clr.l d0 os9 F$SigMask bcc.s nbad bad move.l d1,errno(a6) move.l #-1,d0 bra.s done nbad clr.l d0 done rts #endasm