示例#1
0
short
call_sap(SAPpb *pb)
{
    short	status;
    SAPpb	sap_pb;
    char	sapDrvrName[10];

    sapDrvrName[0] = 0x08;
    sapDrvrName[1] = '.';
    *(long *)&sapDrvrName[2] = 'NVL_';
    *(long *)&sapDrvrName[6] = 'SAP ';
    sap_pb.ioNamePtr = sapDrvrName;
    sap_pb.csCode = 0; /* We're actually setting the read/write permission here */
    status = PBOpen((ParmBlkPtr)&sap_pb, FALSE);
    if (status) {
        goto Exit0;
    }

    pb->ioCRefNum = sap_pb.ioCRefNum;
    (void)PBControl((ParmBlkPtr)pb, FALSE);
    status = pb->ioResult;

Exit0:
    return (status);
}
示例#2
0
/* open a TCP connection
 */
na_tcp NATCPopen(na_tcpreadp *callback, void *context, char *host, long port, short flags)
{
	int i, err = NATCP_notcpbuf;
	OSErr resolve = noErr;
	tcpinfo *tcp;
	
	if ((tcp = getTCPbuf(callback, context, &i)) == NULL) return (-1);
	if (flags & NATCP_server) tcp->server = 1;
	tcp->port = port;
	tcp->pb.csCode = TCPCreate;
	tcp->pb.csParam.create.rcvBuff = (Ptr) tcp->buf;
	tcp->pb.csParam.create.rcvBuffLen = (*tcpstate)->streamsize;
	tcp->pb.csParam.create.notifyProc = myTCPNotifyProc;
	tcp->pb.csParam.create.userDataPtr = (Ptr) tcp;
	PBControl((ParmBlkPtr)&tcp->pb, false);
	if (tcp->pb.ioResult == 0) {
		tcp->state = TCP_RESOLVE;
		tcp->stream = tcp->pb.tcpStream;
		/* a server isn't required to have a hostname */
		if (!host && tcp->server) return (i);
		tcp->dnrdone = 0;
		resolve = StrToAddr(host, &tcp->host, addrproc, (char *) tcp);
		if (resolve == noErr) tcp->dnrdone = 1;
		if (resolve == cacheFault || resolve == noErr) {
			return (i);
		}
		err = NATCP_nohost;
	}
	DisposPtr((Ptr) tcp);
	(*tcpstate)->tcpbufs[i] = NULL;
	(*callback)(context, -1, err, resolve, NULL);
	
	return (-1);
}
示例#3
0
/* get host name
 */
void NATCPgethost(na_tcpreadp *callback, void *context)
{
	int id;
	tcpinfo *tcp;
	struct IPParamBlock *ippb;
	na_win *win;
	
	if ((*tcpstate)->localhost[0]) {
		win = NAlockWindow((na_win **) tcpstate);
		(*callback)(context, -1, NATCP_connect, strlen(tstate->localhost),
			tstate->localhost);
		NAunlockWindowh((na_win **) tcpstate, win);
	} else if ((tcp = getTCPbuf(callback, context, &id)) != NULL) {
		/* here we make the assumption that an IP param block is smaller than
		 * a TCP param block.  This seems like a safe assumption to me.
		 */
		ippb = (struct IPParamBlock *) &tcp->pb;
		/* get IP address */
		ippb->ioCRefNum = (*tcpstate)->tcp_driver;
		ippb->csCode = ipctlGetAddr;
		PBControl((ParmBlkPtr)ippb, false);
		if (ippb->ioResult != 0) {
			(*callback)(context, -1, NATCP_notcpbuf, ippb->ioResult, NULL);
			DisposPtr((Ptr) tcp);
			(*tcpstate)->tcpbufs[id] = NULL;
		} else {
			/* begin IP address lookup */
			tcp->dnrdone = 0;
			AddrToName(ippb->ourAddress, &tcp->host, addrproc, (char *) tcp);
			tcp->state = TCP_GETHOST;
			tcp->gethost = 1;
		}
	}
}
示例#4
0
/* clean up the TCP task
 */
static short tcp_closep(na_win *win)
{
	short i, j;
	tcpinfo *tcp;
	tcpwb *wb;
	TCPiopb pb;
	
	tstate->waitstart = TickCount();
	tstate->waitpercent = 0;
	tcp_wait(tstate, NULL);
	memset((void *) &pb, 0, sizeof (pb));
	for (i = 0; i < MAX_TCPCON; ++i) {
		if ((tcp = tstate->tcpbufs[i]) != NULL) {
			/* wait for MacTCP to finish what it's doing, but permit user cancel */
			if (!tcp->server || tcp->state != TCP_CONNECT) tcp_wait(tstate, tcp);
			if (!tcp->gethost) {
				pb.ioCRefNum = tstate->tcp_driver;
				pb.tcpStream = tcp->stream;
				pb.csCode = TCPRelease;
				PBControl((ParmBlkPtr) &pb, false);
			}
			freewb(tcp->wb);
			freewb(tcp->wb + 1);
			DisposPtr((Ptr) tcp);
			tstate->tcpbufs[i] = NULL;
		}
	}
	tcpstate = NULL;
	if (tstate->tcp_driver) CloseResolver();
	
	return (NA_CLOSED);
}
示例#5
0
/* begin writing data
 */
static short beginwrite(tcpinfo *tcp)
{
	tcpwb *wb = tcp->wb + tcp->wbnum;
	
	/* if connection terminated, or we've sent a TCPclose, we can't write */
	if (tcp->rclose == 3 || tcp->lclose > 1) return (0);
	memset((void *) &tcp->pb.csParam, 0, sizeof (tcp->pb.csParam));
	tcp->pb.csCode = TCPSend;
	tcp->pb.csParam.send.ulpTimeoutValue = 60; /* 1 minute to send data */
	tcp->pb.csParam.send.ulpTimeoutAction = 0;
	tcp->pb.csParam.send.validityFlags = 0xC0;
	tcp->pb.csParam.send.wdsPtr = (Ptr) wb->rds;
	tcp->pb.csParam.send.pushFlag = tcp->pushed = tcp->push;
	PBControl((ParmBlkPtr) &tcp->pb, true);
	tcp->push = 0;
	tcp->wbnum = 1 - tcp->wbnum;
	wb->rused = -1;
	
	return (tcp->state = TCP_WRITING);
}
示例#6
0
/* do I/O polling
 */
short NATCPtask(na_win *win)
{
	tcpinfo *tcp;
	rdsEntry *rds, *trds;
	short result, newstate;
	short processed = NA_PROCESSED;
	na_tcp i;
	tcpwb *wb;
	int j;
	
	/* finish off driver initialization: */
	if (!tstate->tcp_driver) {
		if (!tcp_checkdriver()) return (NA_NOTPROCESSED);
		if (!tstate->tcp_driver) return (NA_REQCLOSE);
	}
	/* loop through connections */
	for (i = 0; i < MAX_TCPCON; ++i) {
		if ((tcp = tstate->tcpbufs[i]) != NULL) do {
			/* read data if we have it */
			if (!tcp->reading && !tcp->rclose && tcp->havedata && tcp->state != TCP_CONNECT) {
				tcp->rpb.ioCRefNum = tstate->tcp_driver;
				tcp->rpb.tcpStream = tcp->stream;
				tcp->rpb.csCode = TCPNoCopyRcv;
				tcp->rpb.csParam.receive.rdsPtr = (Ptr) tcp->rrds;
				tcp->rpb.csParam.receive.commandTimeoutValue = 5;
				tcp->rpb.csParam.receive.rdsLength = RDS;
				if (tcp->pushed) {
					tcp->rpb.csParam.receive.commandTimeoutValue = 1;
					tcp->rpb.csParam.receive.rdsLength = 1;
				}
				tcp->havedata = 0;
				PBControl((ParmBlkPtr) &tcp->rpb, tcp->pushed ? false : true);
				tcp->reading = 1;
				tcp->pushed = 0;
			}
			if (tcp->reading) {
				if ((result = tcp->rpb.ioResult) == 1) {
					processed = NA_NOTPROCESSED;
				} else {
					tcp->reading = 0;
					if (result != noErr) {
						if (result != commandTimeout) {
							(*tcp->callback)(tcp->context, i, NATCP_noread, result, NULL);
						}
					} else {
						result = NATCP_data | NATCP_more;
						if (tcp->rpb.csParam.receive.urgentFlag) tcp->urgent = 1;
						if (tcp->urgent) result |= NATCP_urgent;
						if (tcp->rpb.csParam.receive.markFlag) tcp->urgent = 0;
						for (rds = tcp->rrds; rds->length; ++rds) {
							if (!rds[1].length) result &= ~NATCP_more;
							(*tcp->callback)(tcp->context, i, result,
								rds->length, rds->ptr);
						}
						tcp->rpb.csCode = TCPRcvBfrReturn;
						PBControl((ParmBlkPtr) &tcp->rpb, false);
					}
				}
			}
			result = tcp->pb.ioResult;
			newstate = 0;
			switch (tcp->state) {
				case TCP_GETHOST:
					if (tcp->dnrdone) {
						tcp->rclose = 3;
						newstate = TCP_CLOSED;
						if (tcp->host.rtnCode != noErr) {
							(*tcp->callback)(tcp->context, i, NATCP_nohost,
								tcp->host.rtnCode, NULL);
						} else {
							(*tcp->callback)(tcp->context, i, NATCP_connect,
								strlen(tcp->host.cname), tcp->host.cname);
							strcpy(tstate->localhost, tcp->host.cname);
						}
					}
					break;
				case TCP_RESOLVE:
					if (tcp->dnrdone) {
						if (tcp->host.rtnCode != noErr) {
							tcp->rclose = 3;
							newstate = TCP_CLOSED;
							(*tcp->callback)(tcp->context, i, NATCP_nohost,
								tcp->host.rtnCode, NULL);
						} else if (!tcp->lclose) {
							memset((void *) &tcp->pb, 0, sizeof (tcp->pb));
							tcp->pb.ioCRefNum = tstate->tcp_driver;
							tcp->pb.tcpStream = tcp->stream;
							tcp->pb.csParam.open.ulpTimeoutValue = 30;
							tcp->pb.csParam.open.ulpTimeoutAction = 1; /* Abort on timeout */
							tcp->pb.csParam.open.tosFlags = tstate->TOS;
							tcp->pb.csParam.open.precedence = tstate->precedence;
							tcp->pb.csParam.open.validityFlags = 
								timeoutValue|timeoutAction|typeOfService|precedence;
							tcp->pb.csParam.open.remoteHost = tcp->host.addr[0];
							if (tcp->server) {
								tcp->pb.csCode = TCPPassiveOpen;
								tcp->pb.csParam.open.commandTimeoutValue = 0;
								tcp->pb.csParam.open.remotePort = 0;
								tcp->pb.csParam.open.localPort = tcp->port;
							} else {
								tcp->pb.csCode = TCPActiveOpen;
								tcp->pb.csParam.open.remotePort = tcp->port;
								tcp->pb.csParam.open.localPort = 0;
							}
							PBControl((ParmBlkPtr) &tcp->pb, true);
							newstate = TCP_CONNECT;
						}
					}
					break;
				case TCP_CONNECT:
					if (result == 1) {
						processed = NA_NOTPROCESSED;
						break;
					}
					if (result != noErr) {
						tcp->rclose = 3;
						newstate = TCP_CLOSED;
						(*tcp->callback)(tcp->context, i, NATCP_nocon, result, NULL);
					} else {
						newstate = TCP_READY;
						if (tcp->server) {
							tcp->port = tcp->pb.csParam.open.remotePort;
							if (!*tcp->host.cname) {
								AddrToStr(tcp->pb.csParam.open.remoteHost, tcp->host.cname);
							}
						}
						(*tcp->callback)(tcp->context, i, NATCP_connect,
							tcp->port, tcp->host.cname);
					}
					break;
				case TCP_READY:
					/* Write data if we have it */
					wb = tcp->wb + tcp->wbnum;
					if (wb->rused && (newstate = beginwrite(tcp))) {
						break;
					}
					/* check if other side wants to close */
					if (tcp->rclose == 1) {
						tcp->rclose = 2;
						(*tcp->callback)(tcp->context, i, NATCP_closing, 0, NULL);
					}
					/* check if connection needs closing at this end */
	 				if (tcp->lclose == 1) {
						tcp->lclose = 2;
						tcp->pb.csCode = TCPClose;
						tcp->pb.csParam.close.validityFlags = 0xC0;
						tcp->pb.csParam.close.ulpTimeoutValue = 30; /* give 30 secs to close */
						tcp->pb.csParam.close.ulpTimeoutAction = 0;
						PBControl((ParmBlkPtr) &tcp->pb, true);
						newstate = TCP_CLOSING;
						break;
					}
					/* check if connection closed at both ends */
					if (tcp->rclose == 3) {
						(*tcp->callback)(tcp->context, i, NATCP_closed, tcp->reason, NULL);
						newstate = TCP_CLOSED;
					}
					break;
				case TCP_WRITING:
					if (result == 1) {
						processed = NA_NOTPROCESSED;
						break;
					}
					wb = tcp->wb;
					if (wb->rused != -1) ++wb;
					freewb(wb);
					if (result != noErr) {
						tcp->pushed = 0;
						(*tcp->callback)(tcp->context, i, NATCP_nowrite, result, NULL);
					}
					newstate = TCP_READY;
					break;
				case TCP_CLOSING:
					if (result == 1) {
						processed = NA_NOTPROCESSED;
						break;
					}
					newstate = TCP_READY;
					break;
				case TCP_CLOSED:
					if (!tcp->rclose) break;
					if (!tcp->gethost) {
						tcp->pb.csCode = TCPRelease;
						PBControl((ParmBlkPtr)&tcp->pb, false);
					}
					freewb(tcp->wb);
					freewb(tcp->wb + 1);
					DisposPtr((Ptr) tcp);
					tstate->tcpbufs[i] = NULL;
					break;
			}
			if (newstate) tcp->state = newstate;
		} while (newstate);
	}
	
	return (processed);
}