|
|
BSD 4.3reno
#include <stdio.h>
#include <ctype.h>
#include <isode/rtsap.h>
#include "support.h"
/*
* General routines useful for supporting the tests of rtsap library routines
*/
extern int fnx_s(), fnx_r();
extern FILE *errfp; /* where to send our error messages */
#define TIMEOUT 40 /* seconds to wait for a transfer */
#define PE_SIZE 3 /* size to build pe's for testing transfer */
/*
* perform the given operation
*/
oper(sd, operation)
int sd;
int operation; /* to be performed */
{
struct RtSAPindication rtis;
struct AcSAPrelease acr;
PE data;
fprintf(errfp, "oper %d\n", operation);
switch (operation) {
case SIMP_SEND:
data = mkpelist(PE_SIZE);
if (RtTransferRequest(sd, data, TIMEOUT, &rtis) == NOTOK) {
fprintf(errfp, "SIMP_SEND:RT-TRANSFER.REQUEST: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(1);
}
pe_free(data);
break;
case CPLX_SEND:
if (RtSetDownTrans(sd, fnx_s, &rtis) == NOTOK) {
fprintf(errfp, "CPLX_SEND:RtSetDown: %s\n", /* Can never happen */
RtErrString (rtis.rti_abort.rta_reason));
exit(3);
}
if (RtTransferRequest(sd, NULLPE, TIMEOUT, &rtis) == NOTOK) {
fprintf(errfp, "CPLX_SEND:failed: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(1);
}
fprintf(errfp, "CPLX_SEND:done\n");
break;
case CPLX_RCV:
if (RtSetUpTrans(sd, fnx_r, &rtis) == NOTOK) {
fprintf(errfp, "CPLX_RCV:RtSetDown: %s\n", /* Can never happen */
RtErrString (rtis.rti_abort.rta_reason));
exit(3);
}
do {
if (RtWaitRequest(sd, TIMEOUT, &rtis) == NOTOK) {
fprintf(errfp, "CPLX_RCV:failed: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(1);
}
if (rtis.rti_type == RTI_CLOSE || rtis.rti_type == RTI_FINISH
|| rtis.rti_type == RTI_ABORT) {
fprintf(errfp, "Unexpected end\n");
exit(3);
}
} while (rtis.rti_type != RTI_TRANSFER);
fprintf(errfp, "CPLX_RCV:done\n");
break;
case SIMP_RCV:
case RCV_PLS:
case RCV_GIVE:
case RCV_ABRT:
case RCV_FINISH:
case RCV_CLOSE:
fprintf(errfp, "RtWaitRequest\n");
if (RtWaitRequest(sd, TIMEOUT, &rtis) == NOTOK) {
fprintf(errfp, "RtWaitRequest: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(1);
}
switch (rtis.rti_type) {
case RTI_TURN:
if (operation != RCV_GIVE && operation != RCV_PLS)
break;
if (rtis.rti_turn.rtu_please && operation != RCV_PLS) {
fprintf(errfp, "Unexpected RT-TURN-GIVE.INDICATION\n");
exit(4);
}
if (!rtis.rti_turn.rtu_please && operation == RCV_PLS) {
fprintf(errfp, "Unexpected RT-TURN-PLEASE.INDICATION\n");
exit(5);
}
return;
case RTI_TRANSFER:
if (operation != SIMP_RCV)
break;
data = mkpelist(PE_SIZE);
if (pe_cmp(data, rtis.rti_transfer.rtt_data))
fprintf(errfp, "oper:RTI_TRANSFER: data does not match\n");
RTTFREE(&rtis.rti_transfer);
pe_free(data);
return;
case RTI_ABORT:
if (operation != RCV_ABRT || operation != RCV_CLOSE)
break;
if (rtis.rti_abort.rta_peer)
fprintf(errfp, "RT-U-ABORT.INDICATION: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
else
fprintf(errfp, "RT-P-ABORT.INDICATION: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
return;
case RTI_CLOSE:
break;
case RTI_FINISH:
if (operation != RCV_CLOSE)
break;
if (RtCloseResponse(sd, ACR_NORMAL, NULLPE, &rtis) == NOTOK) {
fprintf(errfp, "RtWaitRequest:RT-CLOSE.RESPONSE: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(9);
}
return;
}
fprintf(errfp, "RtWaitRequest:unexpected indication %d received\n",
rtis.rti_type);
break;
case SEND_PLS:
if (RtPTurnRequest(sd, 0, &rtis) == NOTOK) {
fprintf(errfp, "SEND_PLS:RT-PLEASE-TURN.REQUEST: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(6);
}
break;
case SEND_GIVE:
if (RtGTurnRequest(sd, &rtis) == NOTOK) {
fprintf(errfp, "SEND_GIVE:RT-GIVE-TURN.REQUEST: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
exit(7);
}
break;
case SEND_CLOSE:
if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, &acr, &rtis) == NOTOK)
fprintf (errfp, "RT-CLOSE.REQUEST: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
return;
case SEND_ABRT:
data = mkpelist(PE_SIZE);
if (RtUAbortRequest(sd, data, &rtis) == NOTOK)
fprintf (errfp, "RT-CLOSE.REQUEST: %s\n",
RtErrString (rtis.rti_abort.rta_reason));
return;
default:
fprintf(errfp, "oper:unknown operation %d\n", operation);
}
}
#define MKMASK 0x7
#define MKSHIFT 6
/*
* Generate a randomish list of PElement s for use as ANY or SET OF ANY ....
*/
PE
mkpelist(i)
int i;
{
PE pe, fpe = NULL;
fpe = pe_alloc(PE_CLASS_PRIV, PE_FORM_CONS, i);
while (i > 0) {
pe = mkpe(i);
pe->pe_next = fpe->pe_cons;
fpe->pe_cons = pe;
i--;
}
return (fpe);
}
/*
* generate a randomish PElement
*/
PE
mkpe(i)
{
int id, class;
PE pe;
id = i * i + 1;
class = PE_CLASS_PRIV;
switch ((i*i >> MKSHIFT) & MKMASK) {
case 5:
case 0:
pe = flag2prim(i & 0x1, class, id);
break;
case 6:
case 1:
pe = num2prim(i, class, id);
break;
case 7:
case 2:
pe = str2prim("mkpelist:testdata", 17, class, id);
break;
case 3:
pe = strb2bitstr("\021\0245\375\0124", 4, class, id);
break;
case 4:
pe = mkpelist(i - 1);
break;
default:
fprintf(errfp, "mkpe:internal error %d case not handled\n",
(i*i >> MKSHIFT) & MKMASK);
exit(2);
}
return (pe);
}
#define MAXCNT 3 /* How many increments of data to send */
#define DATASIZE 1035 /* Size of maximum increment */
/*
* function which is called to incrementally send data
*/
fnx_s(sd, base, len, size, ack, ssn, rti)
int sd;
char **base;
int *len, size;
long ack, ssn;
struct RtSAPindication *rti;
{
static int cnt = MAXCNT;
if (base == NULLVP) { /* RT-PLEASE.INDICATION */
fprintf(errfp, "fnx_s: RT-PLEASE.INDICATION ignored\n");
return (OK);
}
fprintf(errfp, "fnx_s: cnt = %d size = %d ack = %d ssn = %d\n",
cnt, size, ack, ssn);
if (cnt > 0) { /* Send some data */
if (size < 0) {
fprintf(errfp, "fnx_s: bad value for size %d error\n", size);
return rtsaplose(rti, RTS_TRANSFER, NULLCP,
"fnx_s called with bad value for size");
}
if (size == 0) { /* Have to do all at once transfer */
cnt = MAXCNT;
}
if (DATASIZE < size)
size = DATASIZE;
if ((*base = malloc(size)) == NULL) {
fprintf(errfp, "fnx_s: malloc failed on size %d\n", size);
return rtsaplose(rti, RTS_TRANSFER, NULLCP, "malloc failed");
}
fill(*base, size);
*len = size;
cnt--;
} else {
cnt = MAXCNT;
*len = 0;
}
return (OK);
}
static char *SSAPact_names[] = {
"START.INDICATION", "RESUME.INDICATION", "INTERRUPT.INDICATION",
"INTERRUPT.CONFIRMATION", "DISCARD.INDICATION", "DISCARD.CONFIRMATION",
"END.INDICATION", "END.CONFIRMATION",
};
/* Number of entries */
#define NENTRIES(x) (sizeof (x)/sizeof ((x)[0]))
/*
* function called by rtsap library to handle the incremental reception
* of data.
*/
fnx_r(sd, event, addr, rti)
int sd;
int event;
caddr_t addr;
struct RtSAPindication *rti;
{
struct qbuf *qb;
struct SSAPactivity *pa;
int len;
char *p;
int place;
switch (event) {
case SI_DATA:
qb = (struct qbuf *)addr;
len = qb->qb_len;
fprintf(errfp, "fnx_r: %d octets of data arrived\n", len);
/* just assume it works - doesn't mention error conditions in the manual */
p = qb2str(qb);
if ((place = chk(p, len)) >= 0)
fprintf(errfp, "fnx_r: data failed check at octet %d\n", place);
break;
case SI_SYNC:
fprintf(errfp, "fnx_r: S-MINOR-SYNC.INDICATION ignored\n");
break;
case SI_ACTIVITY:
pa = (struct SSAPactivity *) addr;
if (pa->sv_type >= NENTRIES(SSAPact_names) || pa->sv_type < 0)
fprintf(errfp, "fnx_r: S-ACTIVITY of unknown type!\n");
else
fprintf(errfp, "fnx_r: S-ACTIVITY-%s\n", SSAPact_names[pa->sv_type]);
break;
case SI_REPORT:
fprintf(errfp, "fnx_r: S-U-EXCEPTION-REPORT.INDICATION\n");
break;
default:
fprintf(errfp, "fnx_r: unknown event received %d\n", event);
return rtsaplose(rti, RTS_TRANSFER, NULLCP, "fnx_r:Unknown event");
}
return (OK);
}
/*
* Fill a piece of memory with some data which has a pattern
*/
fill(data, len)
char *data;
int len;
{
while (len-- > 0) {
*data++ = len & 0xff;
}
}
/*
* check that data is filled as per fill routine. Return the place where it
* fails otherwise -1 if it doesn't
*/
chk(data, len)
char *data;
int len;
{
int i;
i = 0;
while (len-- > 0) {
if ((*data++ & 0xff) != (len & 0xff))
return (i);
i++;
}
return (-1);
}
/*
* Dump a bunch of hex digits printing out those that are printable
* Print out a given length of octets as hex (with the ASCII characters
* given if they have any
*/
fpclen(fp, s, len)
register FILE *fp;
register char *s;
register int len;
{
register int cnt = 0;
while (len-- > 0) {
if (cnt % 8 == 0)
fprintf(fp, "\n%d:", cnt/8 + 1);
if (isprint(*s&0x7f))
fprintf(fp, "\t%02x(%c)", *s&0xff, *s&0x7f);
else
fprintf(fp, "\t%02x", *s&0xff);
s++;
cnt++;
}
fputc('\n', fp);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.