This is abpapc.c in view mode; [Download] [Up]
/* * $Author: cck $ $Date: 88/04/30 09:06:17 $ * $Header: abpapc.c,v 1.13 88/04/30 09:06:17 cck Rel $ * $Revision: 1.13 $ */ /* * abpapc.c - Printer Access Protocol access - client only routines. * * AppleTalk package for UNIX (4.2 BSD). * * Copyright (c) 1986 by The Trustees of Columbia University in the * City of New York. * * Edit History: * * July 12, 1986 CCKim Created * */ #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <netat/appletalk.h> #include "abpap.h" #include "cap_conf.h" OSErr PAPStatus(); /* OSErr PAPStatus(char *, PAPStatusRec *, */ /* AddrBlock *) */ OSErr PAPOpen(); /* OSErr PAPOpen(int *, char *, int, */ /* PAPStatusRec *, int *) */ private void opendone(); /* private void opendone(ABusRecord *, u_long) */ private void res_open(); /* private void res_open(PRR *) */ void pcinit(); private boolean getpname(); /* * PAPStatus * * As documented * */ OSErr PAPStatus(printername, statusbuff, prtaddr) char *printername; PAPStatusRec *statusbuff; AddrBlock *prtaddr; { ABusRecord abr; atpProto *ap; PAPUserBytes *pub; BDS bds[1]; /* one bds */ PAP p; int len; AddrBlock addr; EntityName en; if (prtaddr->net == 0 || prtaddr->node == 0 || prtaddr->skt == 0) { create_entity(printername, &en); /* name to entity */ if (!getpname(&addr,&en)) { sprintf(statusbuff->StatusStr+1,"?Can't find %s", printername); statusbuff->StatusStr[0] = (byte)(strlen(statusbuff->StatusStr+1)); return(-1); } *prtaddr = addr; } else addr = *prtaddr; ap = &abr.proto.atp; ap->atpUserData = 0; pub = (PAPUserBytes *)&ap->atpUserData; pub->PAPtype = papSendStatus; ap->atpAddress = addr; ap->atpSocket = 0; ap->atpReqCount = 0; ap->atpDataPtr = NULL; ap->atpRspBDSPtr = bds; bds[0].buffSize = sizeof(PAPpkt); bds[0].buffPtr = (char *)&p; ap->fatpXO = 0; /* nyi */ ap->atpTimeOut = 1; /* retry in seconds */ ap->atpRetries = 3; /* 3 Retries */ ap->atpNumBufs = 1; /* number of bds segments */ len = ATPSndRequest(&abr, FALSE); if (len == reqFailed) { strcpy(statusbuff->StatusStr+1, "%Not responding"); statusbuff->StatusStr[0] = (byte)(sizeof("%Not responding")-1); return(reqFailed); } if (ap->atpNumRsp < 1 && bds[0].dataSize < min_PAPpkt_size) return(-1); pub = (PAPUserBytes *) &bds[0].userData; if (pub->PAPtype != papStatusReply) return(-1); /* should never happen? */ bcopy(p.papS.status, statusbuff->StatusStr, (int)p.papS.status[0]+1); return(noErr); /* return okay */ } /* * PAPOpen * * as documented * */ OSErr PAPOpen(refnum, printername, flowquantum, statusbuff, compstate) int *refnum; char *printername; int flowquantum; PAPStatusRec *statusbuff; int *compstate; { atpProto *ap; PAPUserBytes *pub; int cno, err; PAPSOCKET *ps; AddrBlock addr; EntityName en; create_entity(printername, &en); /* name to entity */ if (!getpname(&addr,&en)) { sprintf(statusbuff->StatusStr+1, "%Can't find %s",printername); statusbuff->StatusStr[0] = (byte)(strlen(statusbuff->StatusStr+1)+1); return(-1); } cno = ppgetskt(&addr); if (cno < 0) /* no slots left */ return(cno); if ((ps = cnotopapskt(cno)) == NULL) { fprintf(stderr,"AWK\n"); exit(9999); } /* initialize status string */ sprintf(statusbuff->StatusStr+1, "%%no status"); /* -2 instead of -1 to account for the eaten percent */ statusbuff->StatusStr[0] = (byte)(sizeof("%%no status")-2); *compstate = 1; /* start it out */ ps->comp = compstate; ps->statusbuff = statusbuff; ps->addr = addr; ps->flowq = flowquantum; time(&ps->wtime); /* get current time */ ps->state = PAP_OPENING; *refnum = cno; /* send back refnum */ ps->bds[0].buffPtr = (char *)&ps->por; /* establish bds here */ ps->bds[0].buffSize = sizeof(PAP); ap = &ps->abr.proto.atp; ap->atpUserData = 0; pub = (PAPUserBytes *)&ap->atpUserData; pub->PAPtype = papOpenConn; pub->connid = ps->connid; ps->po.papO.atprskt = ps->paprskt; ps->po.papO.flowq = ps->flowq; /* until further notice */ ps->po.papO.wtime = 1; ap->atpAddress = ps->addr; ap->atpSocket = 0; ap->atpReqCount = 4; /* cheating */ ap->atpDataPtr = (char *)&ps->po; ap->atpRspBDSPtr = ps->bds; ap->fatpXO = 1; /* set xo on */ ap->atpNumBufs = 1; /* number of bds segments */ ap->atpTimeOut = PAPOPENTIMEOUT; ap->atpRetries = PAPOPENRETRY; err = cbATPSndRequest(&ps->abr, opendone, (u_long)ps); return(err); } /* * Callback routine for open - called after sndrequest gets response * or a timeout occurs and no response received * */ private void opendone(abr, ps) ABusRecord *abr; PAPSOCKET *ps; { PAPUserBytes *pub; int sslen; if (ps->state != PAP_OPENING) { if (dbug.db_pap) fprintf(stderr,"papc: unexpected state change on session\n"); /* sigh, what else to do ???? */ *ps->comp = -1; return; } pub = (PAPUserBytes *) &ps->bds[0].userData; if (abr->abResult != reqFailed) { if (abr->abResult == sktClosed) { *ps->comp = sktClosed; /* only way to abort... */ return; } if (abr->abResult == noErr && pub->PAPtype == papOpenConnReply) { ps->rrskt = ps->por.papOR.atprskt; /* remote responding socket */ sslen = (int)(ps->por.papS.status[0]); bcopy(ps->por.papS.status, ps->statusbuff->StatusStr, sslen+1); if (dbug.db_pap) fprintf(stderr,"pap: open return from remote: %d\n", ps->por.papOR.result); if (ps->por.papOR.result == 0) { ps->rflowq = ps->por.papOR.flowq; /* save remote flow quantum */ start_papc(ps); return; } } /* wait two seconds */ Timeout(res_open, ps, 4*2); /* will always.. */ return; } res_open(ps); } /* * res_open(prr) - resume open call using prr. Really part of open done. * */ private void res_open(ps) PAPSOCKET *ps; { int err; struct timeval t; atpProto *ap = &ps->abr.proto.atp; time(&t); ps->po.papO.wtime = t.tv_sec - ps->wtime.tv_sec; ap->atpTimeOut = PAPOPENTIMEOUT; ap->atpRetries = PAPOPENRETRY; err = cbATPSndRequest(&ps->abr, opendone, (u_long)ps); if (err < 0) { *ps->comp = err; /* die */ } } void pcinit() { /* nothing to do */ } /* * Find the specified entity - return true and addr if found, false * o.w. * */ private boolean getpname(addr,ent) AddrBlock *addr; EntityName *ent; { nbpProto nbpr; NBPTEntry nbpt[1]; /* should be exact match */ nbpr.nbpRetransmitInfo.retransInterval = 8; nbpr.nbpRetransmitInfo.retransCount = 3; nbpr.nbpDataField = 1; nbpr.nbpEntityPtr = ent; nbpr.nbpBufPtr = nbpt; nbpr.nbpBufSize = sizeof(nbpt); NBPLookup(&nbpr, FALSE); if (nbpr.nbpDataField != 1) return(FALSE); NBPExtract(nbpt, nbpr.nbpDataField, 1, ent, addr); /* get lw entry */ return(TRUE); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.