home *** CD-ROM | disk | FTP | other *** search
- /*
- * link.c - routines to open/close serial link for PPP
- *
- * Copyright 1992-1993 Merit Network, Inc. and The Regents of the
- * University of Michigan. Usage of this source code is restricted
- * to non-profit, non-commercial purposes. The source is provided
- * "as-is", without warranty.
- */
- #include "ppp.h"
- #include <Folders.h>
- #include <GestaltEqu.h>
- #include <CommResources.h>
- #include <CRMSerialDevices.h>
- #include <ShutDown.h>
-
- /* Trap numbers */
- #define TN_UnknownOS 0xA09F
- #define TN_CommToolbox 0xA08B
- #define TN_DTInstall 0xA082
-
- unsigned char PortBUse : 0x291;
-
- /* function prototypes */
- OSErr waitstr(LapInfo *, b_8 *, short);
- OSErr sendstr(b_8 *);
- void adjustbuf(LapInfo *, short);
- void install_tm(LapInfo *, struct TMprocess *, ProcPtr);
- void init_dt(LapInfo *, struct DeferredTask *, ProcPtr);
- void AppendStr(b_8 *, b_8 *);
- OSErr parsestr(b_8 *, Boolean);
- OSErr TermMode();
- void sendlcpecho();
- void time_check();
- void MySetText(b_8);
- pascal Boolean nullfilt(DialogPtr, EventRecord *, short *);
-
- /* define some globals */
- b_8 **gmessages;
- Handle ghandle;
- b_8 reserrmes[]="\pMacPPP: resource error";
- b_8 okmes[]={1, 2,'O','K',0};
- extern struct NMRec errnmrec;
- b_8 resFile[] = "\pPPP";
- b_8 sys6resFile[] = "\p:System Folder:PPP";
-
- /* resource defines */
- #define SYS6FOLDER -4034
- #define PREFFILENAME -4033
-
- #define MODEMRESPONSES 128 /* resource id of modem responses */
- #define STATUSSTRINGS 129
- #define MODEMCOMMANDS 130
- #define PHASETEXT 131
-
- #define MODEMCONNECT 1 /* # for connect message */
- #define MODEMBUSY 2 /* # for busy message */
-
- #define MESSCHECK 1
- #define MESSINIT 2
- #define MESSDIAL 3
- #define MESSBUSY 4
- #define MESSERROR 5
- #define MESSSENDING 6
- #define MESSWAITING 7
- #define MESSTERM 8
- #define MESSTIMEOUT 9
- #define MESSPHASE 10
-
- #define MODEMALERT 128 /* Modem connect failure alert */
- #define NOPREFALERT 129 /* no preferences alert */
- #define SERIALALERT 130 /* alert for error when opening serial port */
- #define CTSALERT 131 /* CTS signal not present */
- #define IDLEALERT 132
- #define ECHOALERT 133
- #define OLDPREFSALERT 135
- #define INUSEALERT 136 /* port in use alert */
-
- /* dialogs */
- #define PPPSTATUS 129 /* status dialog */
- #define TERMDLOG 130 /* terminal window dialog box */
- #define PAPMESDLOG 131 /* display message returned by PAP */
- #define TIMEOUTDLOG 132 /* timeout waiting for a string */
-
- #define IGNOREIDLE 2
- #define IGNOREECHO 2
- #define CLOSEPPP 3
-
- void
- link_open(register LapInfo *lap)
- {
- register OSErr rc, savrc;
- OSErr waitresult;
- register b_8 *hshake;
- Boolean HaveFindFolder = false, HavePrefFolder = false;
- long ffresp, count, whichDir, oldA4, oldA5, timeout;
- Byte i;
- short whichVol, rn = -1, len, prefref;
- short savresfile, itemhit, type;
- b_8 *strptr;
- register DialogPtr statusdlog;
- DialogPtr dlog;
- Rect rect;
- Handle itemH, itemH2;
- pascal Boolean modemfilt();
- struct bufheader *bufptr;
- b_8 curphase, curstate;
- b_8 **modemstrings;
- b_8 tempstr[MAXSLEN + 4];
- b_8 indriv[128],outdriv[128];
- long qd_save;
-
- /* save current Resource file */
- savresfile = CurResFile();
-
- oldA4 = seta4((long)lap->LapA4); /* setup PPP's A4 for globals */
- oldA5 = seta5((long) CurrentA5);
- qd_save = *((long *)geta5()); /* save current pointer to QD globals */
- InitGraf(&thePort); /* init our QD globals */
- if (WWExist != 0) { /* see if initwindows has been called yet */
- InitFonts(); /* init fonts */
- InitWindows(); /* init window manager port */
- TEInit();
- InitDialogs(nil);
- DeskHook = 0;
- }
- InitCursor(); /* make the cursor an arrow */
-
- /* see if findfolder is available */
- if ( Gestalt(gestaltFindFolderAttr, &ffresp) == noErr) {
- if ( ( 1L << gestaltFindFolderPresent ) & ffresp )
- HaveFindFolder = true;
- }
-
- if ( HaveFindFolder ) {
- if ( FindFolder(kOnSystemDisk,kExtensionFolderType,
- kDontCreateFolder,&whichVol,&whichDir) == noErr)
- rn = HOpenResFile(whichVol,whichDir,resFile,fsRdPerm);
- } else {
- GetVRefNum(SysMap, &whichVol); /* get system Vol ref */
- rn = OpenRFPerm(sys6resFile,whichVol,fsRdPerm);
- }
-
- if (rn == -1) {
- errnmrec.nmStr = reserrmes; /* initialize pointer to error message */
- NMInstall(&errnmrec); /* Install the notification */
- goto noresbye;
- }
-
- if (lap->ppp_flags & ECHO_FAIL) {
- itemhit = NoteAlert(ECHOALERT, nil);
- if (itemhit == IGNOREECHO) {
- lap->echo_count = 0;
- PrimeTime((QElemPtr) &lap->echo_task, (long)lap->prefdata.echo * 1000L);
- goto exitout;
- }
- if (itemhit == CLOSEPPP) {
- ppp_iostatus(lap, PARAM_DOWN); /* link must be down */
- goto close_ppp; /* close drivers */
- }
- link_close(); /* must want to restart */
- }
-
- if (lap->ppp_flags & IDLE_TIMEOUT) {
- if (!lap->prefdata.quiet) {
- itemhit = NoteAlert(IDLEALERT, nil);
- if (itemhit == IGNOREIDLE) {
- lap->idle_timer = 0;
- PrimeTime((QElemPtr) &lap->timeout_task, 60000L); /* one minute interval */
- goto exitout;
- }
- }
- goto close_ppp;
- }
-
- lap->ppp_flags &= ~(ECHO_FAIL | IDLE_TIMEOUT);
-
- if (lap->ppp_phase != pppDEAD)
- return; /* return if not in DEAD phase */
-
- if (HaveFindFolder) {
- if (noErr == FindFolder(kOnSystemDisk,kPreferencesFolderType,
- kCreateFolder,&whichVol,&whichDir))
- HavePrefFolder = true;
- }
-
- tempstr[0] = 0;
- if (!HavePrefFolder) {
- itemH = GetResource('STR ',SYS6FOLDER); /* system 6 folder */
- AppendStr(tempstr, *((b_8 **) itemH));
- ReleaseResource(itemH);
- }
- itemH = GetResource('STR ',PREFFILENAME); /* get pref file */
- AppendStr(tempstr, *((unsigned char **) itemH));
- ReleaseResource(itemH);
-
- if (HavePrefFolder)
- rc = HOpen(whichVol,whichDir,tempstr,fsRdPerm,&prefref);
- else {
- /* if we don't have PrefFolder, just use System Folder */
- GetVRefNum(SysMap, &whichVol); /* get system Vol ref */
- rc = FSOpen(tempstr,whichVol,&prefref);
- }
- savrc = rc;
-
- count = sizeof (struct ppp_pref);
- if (rc == opWrErr ) /* must already be opened by control panel */
- rc = SetFPos(prefref,fsFromStart,0L);
- if (rc == noErr)
- rc = FSRead(prefref, &count, &(lap->prefdata)); /* read in preferences data */
-
- if (lap->prefdata.version < PREF_VERSION) {
- NoteAlert(OLDPREFSALERT,nil);
- FSClose(prefref);
- goto exitout;
- }
- if (rc == noErr) {
- if (count != sizeof (struct ppp_pref)) /* check number of bytes */
- rc = -1; /* set return code to non-zero */
- }
- if (rc == noErr)
- rc = SetFPos(prefref, fsFromMark,
- lap->prefdata.active_config * sizeof(struct ppp_config));
- if (rc == noErr) {
- count = sizeof(struct ppp_config);
- rc = FSRead(prefref, &count, &(lap->configdata));
- }
- if (savrc != opWrErr )
- FSClose(prefref); /* close the preferences file */
-
- if ( rc != noErr ) {
- NoteAlert(NOPREFALERT, nil);
- goto exitout;
- }
- indriv[0] = 0;
- outdriv[0] = 0;
- if (NGetTrapAddress(TN_CommToolbox, OSTrap)
- != GetTrapAddress(TN_UnknownOS)) {
- CRMRec *crmrecptr, acrmrec;
- CRMSerialRecord *serrec;
- long old = 0;
- int index = 1;
-
- InitCRM();
- acrmrec.qType = crmType;
- while (true) {
- acrmrec.crmDeviceType = crmSerialDevice;
- acrmrec.crmDeviceID = old;
- if (!(crmrecptr = (CRMRec *)CRMSearch((QElemPtr)(&acrmrec))))
- break;
- serrec = (CRMSerialRecord *)crmrecptr->crmAttributes;
- old = crmrecptr->crmDeviceID;
- ++index;
- if (EqualString(lap->prefdata.portname, *serrec->name,
- FALSE, TRUE))
- break;
- }
- if (!crmrecptr)
- goto sererr;
- AppendStr(indriv, *serrec->inputDriverName);
- AppendStr(outdriv, *serrec->outputDriverName);
-
- } else {
- if (!(itemH = GetNamedResource('Port', lap->prefdata.portname)))
- goto sererr;
- strptr = * ((b_8 **) itemH);
- AppendStr(indriv,strptr);
- strptr += *strptr + 1;
- AppendStr(outdriv,strptr);
- ReleaseResource(itemH);
- }
- rc = OpenDriver(indriv, &lap->serinrefnum);
- if (rc == portInUse) {
- if (EqualString(indriv,"\p.BIn", FALSE, FALSE)) {
- if (NoteAlert(INUSEALERT, nil) == OK) {
- PortBUse = (Byte) 0xff; /* Hack to mark port as free */
- rc = OpenDriver(indriv, &lap->serinrefnum);
- }
- }
- }
- if (rc == noErr) {
- rc = OpenDriver(outdriv, &lap->seroutrefnum);
- if (rc != noErr)
- CloseDriver(lap->serinrefnum);
- }
-
- if (rc != noErr)
- goto sererr;
- rc = SerReset(lap->serinrefnum,stop10+noParity+data8);
- if (rc == noErr)
- rc = SerReset(lap->seroutrefnum,stop10+noParity+data8);
- if (rc == noErr)
- rc = SerSetBuf(lap->serinrefnum, (Ptr) lap->sdinbuf, SDINBUFLEN); /* give driver a new buffer */
-
- lap->stat_pb.csCode = 13; /* baud rate routine */
- *( (unsigned int *) lap->stat_pb.csParam) = lap->configdata.baudrate;
- lap->stat_pb.ioCRefNum = lap->serinrefnum;
- PBControlImmed((ParmBlkPtr) &lap->stat_pb);
-
- *( (unsigned int *) lap->stat_pb.csParam) = lap->configdata.baudrate;
- lap->stat_pb.ioCRefNum = lap->seroutrefnum;
- PBControlImmed((ParmBlkPtr) &lap->stat_pb);
-
- hshake = (b_8 *) lap->stat_pb.csParam;
- *hshake++ = false; /* fXOn */
- *hshake++ = lap->configdata.flags & CTSBIT; /* fCTS */
- hshake += 2; /* skip Xon/Xoff character settings */
- *hshake++ = 0; /* errs */
- *hshake++ = 0; /* evts */
- *hshake++ = false; /* fInX */
- *hshake = lap->configdata.flags & RTSBIT; /* fDTR */
-
- lap->stat_pb.csCode = 14; /* new SerHShake routine */
- lap->stat_pb.ioCRefNum = lap->seroutrefnum;
- PBControlImmed((ParmBlkPtr) &lap->stat_pb);
-
- lap->stat_pb.ioCRefNum = lap->serinrefnum;
- PBControlImmed((ParmBlkPtr) &lap->stat_pb);
-
- if (rc != noErr) {
- SerSetBuf(lap->serinrefnum, (Ptr) lap->sdinbuf, 0); /* reset buffer */
- CloseDriver(lap->serinrefnum);
- CloseDriver(lap->seroutrefnum);
- sererr:
- NoteAlert(SERIALALERT, nil);
- goto exitout;
- }
-
- /* Initialize lists of buffers */
- lap->buflist = (struct bufheader * ) nil;
- for ( i = 0; i < NUMBUFFERS; i++ ) {
- bufptr = (struct bufheader *) lap->blockarray[i].block;
- bufptr->dataptr = (b_8 *) lap->buflist;
- lap->buflist = bufptr;
- }
-
- lap->rds.rdsparm.lnb.lnb_ptr = nil; /* clear rcv buffer pointer */
-
- lap->active = nil;
- lap->out_q.qFlags = 0;
- /* initialize queue of iopbs */
- lap->pppbq.qFlags = 0;
- lap->pppbq.qHead = nil;
- lap->pppbq.qTail = nil;
- for (i = 0; i < NUMIOPBS; i++)
- Enqueue( (QElemPtr) &lap->pppiopbs[i], (QHdrPtr) &lap->pppbq);
-
- /* initialize FIFO params */
- lap->XmitQHead = 0;
- lap->XmitQTail = 0;
- lap->XmitQSize = 0;
-
- /* initialize our serial driver iopb's */
- lap->w_iopb.lap = lap;
- lap->w_iopb.iop.ioCompletion = hdlcwioc; /* where to go when done */
- lap->w_iopb.iop.ioRefNum = lap->seroutrefnum; /* set output to serial port*/
-
- lap->r_iopb.lap = lap;
- lap->r_iopb.iop.ioRefNum = lap->serinrefnum;
- lap->r_iopb.iop.ioBuffer = (Ptr) lap->rxbuf;
- lap->r_iopb.iop.ioCompletion = SerReadDone;
-
- lap->stat_pb.ioCRefNum = lap->serinrefnum;
-
- lap->read_state = s_Init;
- lap->write_state = s_Init;
- lap->needTxPrime = true;
- lap->term_mode = false; /* not in terminal emulation mode */
-
- lap->bufptr = getbuffer(); /* allocate initial rcv. buffer */
- lap->rddata = lap->bufptr->dataptr; /* point to data area */
- lap->ok_to_xmit = true;
-
- SystemTask(); /* some serial drivers need SystemTask time to open */
- Delay(60L, &count); /* wait some (if DTR need to "wake up" device */
- SystemTask(); /* more system task time for good measure */
-
- /* check if deferred task manager available */
- lap->HasDeferredTasks = (NGetTrapAddress(TN_DTInstall, OSTrap) !=
- GetTrapAddress(TN_UnknownOS));
-
- /* initialize Deferred Task queue entries */
- init_dt(lap, &lap->defer_rx, RcvDeferred);
- init_dt(lap, &lap->defer_tx, XmtDeferred);
- init_dt(lap, &lap->defer_txcomplete, TxCDeferred);
-
- /* set up receive time manager task */
- install_tm(lap, &lap->rxp_task, ProcRcvPPP);
- PrimeTime( (QElemPtr) &lap->rxp_task, 4L); /* Prime receive task */
-
- /* set up transmit time manager task (gets primed as needed) */
- install_tm(lap, &(lap->txp_task), XmtTMProc);
-
- if (lap->prefdata.echo != 0) /* LCP echo test */
- install_tm(lap, &lap->echo_task, sendlcpecho);
- if (lap->prefdata.timeout != 0) /* idle timeout */
- install_tm(lap, &lap->timeout_task, time_check);
-
- statusdlog = GetNewDialog(PPPSTATUS, nil, (WindowPtr) -1L);
- DrawDialog(statusdlog);
- SetCursor(&qd.arrow);
- GetDItem(statusdlog, 3, &type, &ghandle, &rect);
- GetDItem(statusdlog, 4, &type, &itemH2, &rect);
- SetIText(itemH2, "\p"); /* set to nil */
- gmessages = (b_8 **) Get1Resource('STR#', STATUSSTRINGS);
-
- if (lap->prefdata.use_term) {
- if (TermMode() != noErr)
- goto getout;
- goto start_ppp;
- }
-
- if (lap->configdata.phonenum[0] != 0) {
- retrymodem:
- DrawDialog(statusdlog);
- MySetText(MESSCHECK);
- rc = sendstr("\pATE0V1\r"); /* see if modem is there */
- if ( rc == 0 )
- rc = waitstr(lap, okmes, 5);
- if ( rc == -1 )
- goto getout;
-
- rc = 0;
- if ( i = lap->configdata.modeminit[0] ) {
- MySetText(MESSINIT);
- lap->configdata.modeminit[0] = 2;
- if (! EqualString(lap->configdata.modeminit, "\pAT", FALSE, FALSE) )
- rc = sendstr("\pAT");
- lap->configdata.modeminit[0] = i;
- if (rc == 0)
- rc = sendstr(lap->configdata.modeminit); /* send modem init command */
- if (rc == 0)
- rc = sendstr("\p\r"); /* add a carriage return */
- if (rc == 0)
- rc = waitstr(lap, okmes, 5);
- if (rc == -1)
- goto getout;
- }
-
- MySetText(MESSDIAL);
- doredial:
- modemstrings = (b_8 **) Get1Resource('STR#',MODEMRESPONSES);
- DrawDialog(statusdlog);
- if (lap->configdata.flags & USE_PULSE)
- rc = sendstr("\pATDP");
- else
- rc = sendstr("\pATDT");
- if (rc == 0)
- rc = sendstr(lap->configdata.phonenum);
- if (rc == 0)
- rc = sendstr("\p\r");
- if (rc == -1)
- goto getout;
- HLock((Handle) modemstrings);
- rc = waitstr(lap, *modemstrings + 1,
- lap->configdata.connecttimeout);
- HUnlock((Handle) modemstrings);
- ReleaseResource((Handle) modemstrings);
- if (rc == MODEMBUSY) {
- MySetText(MESSBUSY);
- if (sendstr("\pAT\r") == -1) /* get the modems' attention */
- goto getout;
- Delay(120L, &count); /* add some delay before we redial */
- goto doredial;
- }
- if (rc == -1)
- goto getout;
- if (rc != MODEMCONNECT) {
- ResetAlrtStage();
- if ( NoteAlert(MODEMALERT, nil) == 1 ) { /* alert user */
- goto getout;
- }
- goto doredial;
- }
- }
-
- DrawDialog(statusdlog);
- for ( i=0 ; i < NUMCOMMANDS; i++) {
- strptr = tempstr;
- *strptr++ = 1;
- *strptr = 0;
- AppendStr(strptr, lap->configdata.commands[i].scriptstr);
- if (lap->configdata.commands[i].addreturn)
- AppendStr(strptr, "\p\\r");
- if ( *strptr != 0 ) {
- if ( lap->configdata.commands[i].sendout ) {
- MySetText(MESSSENDING);
- SetIText(itemH2, strptr);
- rc = parsestr(strptr, true);
- } else {
- MySetText(MESSWAITING);
- SetIText(itemH2, strptr);
- parsestr(strptr, false);
- rc = waitstr(lap, tempstr, lap->configdata.waittimeout);
- }
- if (rc == -1)
- goto getout;
- }
- }
-
- start_ppp:
-
- lap->write_state = s_Idle; /* serial port now ready for PPP */
- lap->read_state = s_Idle;
-
- ppp_iostatus(lap, PARAM_UP); /* let PPP know that link is up */
-
- curphase = 255; /* initialize state holder */
-
- MySetText(MESSPHASE);
- ReleaseResource( (Handle) gmessages); /* release messages resource */
- gmessages = (b_8 **) Get1Resource('STR#', PHASETEXT);
- ghandle = itemH2;
- while (lap->ppp_fsm[IPcp].state != fsmOPENED) { /* wait for IPCP */
- ModalDialog((ProcPtr) nullfilt, &itemhit);
- if (itemhit == 1) { /* check if user wants to quit */
- goto getout;
- }
- if (lap->ppp_phase != curphase) {
- curphase = lap->ppp_phase;
- MySetText(curphase + 1); /* display the PPP phase */
- }
- if (lap->pap_i.IOFlag == TRUE && lap->pap_i.message[0] == 0)
- if (pap_userio(&(lap->ppp_fsm[Pap])) != noErr ) { /* get user name and password */
- goto getout;
- }
- if (lap->pap_i.message[0] != 0) {
- if (!lap->prefdata.quiet || lap->pap_i.IOFlag == true) {
- dlog = GetNewDialog(PAPMESDLOG, 0L, (WindowPtr) -1L);
- DrawDialog(dlog);
- GetDItem(dlog, 3, &type, &itemH, &rect);
- SetIText(itemH, lap->pap_i.message); /* set mess field */
- do
- ModalDialog( (ProcPtr) nullfilt, &itemhit);
- while (itemhit != OK );
- DisposDialog(dlog);
- }
- lap->pap_i.message[0] = 0; /* reset the message */
- }
- }
-
- DisposDialog(statusdlog);
-
- if (lap->prefdata.hangup) /* hangup modem on restart/shutdown */
- ShutDwnInstall((ProcPtr) link_close, sdOnDrivers);
-
- if (lap->prefdata.echo != 0) {
- lap->echo_count = 0;
- PrimeTime((QElemPtr) &lap->echo_task, (long)lap->prefdata.echo * 1000L);
- }
-
- if (lap->prefdata.timeout != 0) {
- lap->idle_timer = 0;
- PrimeTime((QElemPtr) &lap->timeout_task, 60000L); /* one minute interval */
- }
- goto exitout; /* everything okey-dokey */
-
- getout:
- DisposDialog(statusdlog); /* get rid of status dialog */
- ReleaseResource((Handle) gmessages); /* release resource */
- close_ppp:
- if (lap->ppp_phase > pppESTABLISH && lap->ppp_phase < pppTERMINATE)
- PPPClose(lap);
- else
- link_close(); /* just Close link */
- exitout:
- CloseResFile(rn); /* make sure to close the resource file */
- noresbye:
- *((long *)geta5()) = qd_save; /* restore QD globals ptr */
- seta4(oldA4); /* restore previous value of A4 */
- seta5(oldA5);
- UseResFile(savresfile); /* restore resource file */
- }
-
- void
- link_close(void)
- {
- register LapInfo *lap;
- short i;
- long count;
- register b_8 *xbufptr;
-
- lap = GetLAPPtr();
- ppp_iostatus(lap, PARAM_DOWN); /* link is going down */
- if (lap->transProc != nil)
- (*(lap->transProc))(TransitionClose); /* let MacTCP know we are down */
-
- if (lap->prefdata.echo != 0)
- RmvTime((QElemPtr) &lap->echo_task);
- if (lap->prefdata.timeout != 0)
- RmvTime((QElemPtr) &lap->timeout_task);
- RmvTime((QElemPtr) &lap->rxp_task);
- KillIO(lap->serinrefnum);
- RmvTime((QElemPtr) &lap->txp_task);
- KillIO(lap->seroutrefnum); /* kill pending writes */
- SerSetBuf(lap->serinrefnum, (Ptr) lap->sdinbuf, 0); /* reset buffer */
-
- if (lap->prefdata.hangup) { /* hangup modem */
- ShutDwnRemove((ProcPtr) link_close); /* remove routine */
- lap->XmitQSize = 0; /* don't send any queued data */
- lap->ok_to_xmit = true; /* set flag so we can send hangup */
- Delay(65L, &count); /* wait ~1 second */
- for (i = 0 ; i < 3 ; i++) {
- lap->xbuf[0] = '+';
- xmitfifo(lap, 1); /* send a '+' 3 times */
- Delay(12L, &count); /* wait 200 milliseconds */
- }
- Delay(65L, &count); /* wait ~1 second */
- xbufptr = lap->xbuf;
- *xbufptr++ = 'A';
- *xbufptr++ = 'T';
- *xbufptr++ = 'H';
- *xbufptr = '\r';
- xmitfifo(lap, 4); /* send the hang-up command */
- Delay(30L, &count); /* wait another 1/2 second */
- }
- KillIO(lap->seroutrefnum); /* kill pending writes */
- CloseDriver(lap->serinrefnum);
- CloseDriver(lap->seroutrefnum);
- }
-
- void
- MySetText(b_8 stringnum)
- {
- register b_8 *strptr;
-
- strptr = *gmessages;
- strptr++;
- if (stringnum > *strptr++ ) /* check if string is out of range */
- return;
- while (--stringnum > 0) /* find string in list */
- strptr += *strptr + 1;
- HLock((Handle) gmessages); /* lock down the Handle */
- SetIText(ghandle, strptr); /* set the text in the dialog */
- HUnlock((Handle) gmessages);
- }
-
- pascal Boolean modemfilt(DialogPtr dlog, EventRecord *evt, short *item)
- {
- b_8 c;
- ioParam iopb;
- LapInfo *lap;
-
- lap = GetLAPPtr();
- *item = 0;
- if (evt->what == keyDown || evt->what == autoKey) {
- lap->xbuf[0] = 1;
- lap->xbuf[1] = evt->message & charCodeMask;
- *item = 3;
- } else if (evt->what == mouseDown)
- return FALSE;
-
- return TRUE;
- }
-
- pascal Boolean nullfilt(DialogPtr dlog, EventRecord *evt, short *item)
- {
- *item = 0;
- if (evt->what == mouseDown)
- return false;
- return true;
- }
-
- OSErr parsestr(b_8 *instr, Boolean sendout)
- {
- OSErr rc;
- long count;
- register b_8 *outptr;
- register b_8 *inptr;
- b_8 inlen;
- register b_8 c;
-
- outptr = inptr = instr;
- if ( (inlen = (*outptr++ = *inptr++) ) == 0 )
- return;
- while ( inlen-- != 0 ) {
- if ( ( c = *inptr++ ) == '^' ) {
- if ( inlen-- == 0) /* and check for 0 */
- break;
- c = *inptr++ & 0x1F; /* generate the control char */
- *outptr++ = c;
- } else if (c == '\\') {
- c = *inptr++;
- if ( inlen-- == 0)
- break;
- switch (c) {
- case '^': /* literals */
- case '\\':
- *outptr++ = c;
- break;
- case 'r':
- *outptr++ = 13; /* carriage return */
- break;
- case 'b':
- case 'd':
- case 't':
- if (!sendout) /* only allow on outgoing strings */
- break;
- *instr = (unsigned char) (outptr - instr - 1);
- if (sendstr(instr) == -1) /* send the current string */
- return -1;
- instr = outptr - 1; /* point to current place in string */
- if ( c == 'd' )
- Delay(60L, &count); /* Delay 1 second */
- else if (c == 'b') {
- LapInfo *lap;
-
- lap = GetLAPPtr(); /* get our Lap Pointer */
- SerSetBrk(lap->seroutrefnum); /* put line in breaking state */
- Delay(6L, &count); /* wait a huner' milliseconds */
- SerClrBrk(lap->seroutrefnum); /* clear break condition */
- } else {
- if ( (rc = TermMode()) != noErr)
- return rc;
- }
- break;
- default:
- if ( c >= '0' && c <= '7' ) {
- *outptr = 0;
- count = 3;
- do {
- *outptr <<= 3;
- *outptr += c - '0';
- c = *inptr++;
- } while ( c >= '0' && c <= '7' && --count != 0 && inlen-- != 0);
- inptr--; /* point back to charcter */
- outptr++;
- if (inlen == 0xff)
- inlen = 0;
- }
- break;
- }
- } else {
- *outptr++ = c;
- }
- }
- *instr = (unsigned char) (outptr - instr - 1); /* store len byte */
- if (sendout)
- return (sendstr(instr)); /* send the string */
- }
-
- /* simple terminal window routine */
-
- OSErr TermMode()
- {
- LapInfo *lap;
- TEHandle teH;
- Rect rect;
- register DialogPtr dlog;
- Handle itemH;
- short type, len, nlines, itemhit;
- GrafPtr oldport;
-
- lap = GetLAPPtr();
- lap->term_mode = true; /* in terminal emulation mode */
- MySetText(MESSTERM);
- dlog = GetNewDialog(TERMDLOG, nil, (WindowPtr) -1L);
- GetPort(&oldport);
- SetPort(dlog);
- DrawDialog(dlog); /* draw the dialog so title shows up */
-
- GetDItem(dlog, 3, &type, &itemH, &rect);
- TextFont(courier);
- TextSize(10);
-
- teH = TENew(&rect, &rect);
- len = 0;
- nlines = 10;
- FrameRect(&rect);
-
- do {
- ModalDialog(modemfilt, &itemhit);
- if (itemhit == 3) {
- if (sendstr(lap->xbuf) == -1) {
- itemhit = Cancel;
- break;
- }
- }
-
- if (lap->bufptr->length != len) {
- if (len > 512)
- adjustbuf(lap, 128);
- len = lap->bufptr->length;
- EraseRect(&rect);
- TESetText(lap->bufptr->dataptr, (long)len, teH);
- TECalText(teH);
- if ((**teH).nLines > nlines) {
- TEScroll(0, (**teH).lineHeight * -1 * ((**teH).nLines - nlines), teH);
- nlines = (**teH).nLines;
- }
- TEUpdate(&rect, teH);
- FrameRect(&rect);
- }
- } while (itemhit != OK && itemhit != Cancel);
-
- lap->term_mode = false;
- DisposeDialog(dlog); /* Dispose the Dialog */
- SetPort(oldport);
- if (itemhit == Cancel)
- return -1;
- return noErr;
- }
-
- /* routine to send out a string. may want to add timeout code. */
-
- OSErr sendstr(b_8 *s)
- {
- long timeout;
- short itemhit;
- LapInfo *lap;
- b_16 len;
-
- lap = GetLAPPtr();
- len = *s++; /* get length */
- while (len > 0) {
- lap->xbuf[0] = *s++;
- xmitfifo(lap, 1);
- len--;
- }
-
- timeout = TickCount() + 3*60; /* seconds before timing out */
- while (!lap->ok_to_xmit) { /* wait for transmitter to empty */
- SystemTask();
- if (TickCount() > timeout) {
- NoteAlert(CTSALERT,nil);
- return -1;
- }
- }
- return 0;
- }
-
- void
- adjustbuf(LapInfo *lap, short i)
- {
- long savsr;
- struct bufheader *bufptr = lap->bufptr;
-
- savsr = set_sr(0x2100); /* disable timer ints, so we don't buffer more */
- bufptr->length -= i; /* subtract from count */
- lap->rddata -= i; /* adjust pointer */
- BlockMove(bufptr->dataptr + i, bufptr->dataptr, bufptr->length); /*move down buffer */
- set_sr(savsr); /* restore timer interrupts */
- }
-
- OSErr waitstr(LapInfo *lap, b_8 *s, short waitseconds )
- {
- long timeout;
- register short i;
- short itemhit, type;
- Rect rect;
- Handle itemH;
- DialogPtr dlog;
- b_8 len, numstrs, j;
- b_8 *lenptr;
-
- timeout = TickCount() + waitseconds*60; /* seconds before timing out */
-
- for (i=1; true; i++) {
- ModalDialog( (ProcPtr) nullfilt, &itemhit);
- if (itemhit == 1) { /* check if user wants to quit */
- return -1;
- }
-
- if (TickCount() > timeout) { /* don't sit in for loop forever */
- dlog = GetNewDialog(TIMEOUTDLOG, 0L, (WindowPtr) -1L);
- DrawDialog(dlog);
- GetDItem(dlog, 3, &type, &itemH, &rect);
- SetIText(itemH, s+1); /* set mess field */
- do
- ModalDialog( (ProcPtr) nullfilt, &itemhit);
- while (itemhit != OK );
- DisposDialog(dlog);
- return -1;
- }
-
- if (lap->bufptr->length < i) { /* check if any chars came in */
- --i;
- continue;
- }
-
- if (i > 255) { /* don't let buffer get too full */
- adjustbuf(lap, 128);
- i -= 128;
- }
-
- lenptr = s; /* point to number of string field */
- numstrs = *lenptr++; /* get the number of strings */
- j = 0;
- while ( j < numstrs ) {
- j++;
- if ((len = *lenptr++) == 0 )
- continue;
- if (i >= len) { /* do we have enough to do a compare? */
- if ( bytecmp(lap->bufptr->dataptr + i - len, lenptr, len)
- == 0) { /* compare and exit if equal */
- adjustbuf(lap, i); /* shift the data in the buffer */
- return j; /* return success */
- }
- }
- lenptr += len; /* point to next string */
- }
- }
- }
-
- void sendlcpecho() {
- register LapInfo *lap;
- struct TMprocess *tmprocp;
-
- asm {
- move.l a1,tmprocp
- }
-
- lap = tmprocp->tmsavptr.lap;
- if (lap->echo_count++ >= lap->prefdata.echo_tries) {
- if (!(lap->ppp_flags & IDLE_TIMEOUT) && lap->transProc != nil) {
- lap->ppp_flags |= ECHO_FAIL;
- (*(lap->transProc))(TransitionClose);
- (*(lap->transProc))(TransitionOpen); /* a hack to get system time */
- return;
- } else
- lap->echo_count = 0;
- }
- /* send a LCP echo request */
- lap->lcp_echo_buf.header.dataptr = lap->lcp_echo_buf.buffer
- + LCP_ECHO_BUFSIZE; /* initialize dataptr */
- lap->lcp_echo_buf.header.length = 0; /* initialize count */
- fsm_send(&lap->ppp_fsm[Lcp], ECHO_REQ, 0, &lap->lcp_echo_buf.header);
- }
-
- void time_check() {
- register LapInfo *lap;
- struct TMprocess *tmprocp;
-
- asm {
- move.l a1,tmprocp
- }
-
- lap = tmprocp->tmsavptr.lap;
- if (lap->idle_timer++ >= lap->prefdata.timeout) {
- if (!(lap->ppp_flags & ECHO_FAIL) && lap->transProc != nil) {
- lap->ppp_flags |= IDLE_TIMEOUT;
- (*(lap->transProc))(TransitionClose);
- (*(lap->transProc))(TransitionOpen); /* a hack to get system time */
- } else
- lap->idle_timer = 0; /* reset idle timer */
- }
- PrimeTime((QElemPtr) &lap->timeout_task, 60000L); /* re-prime for 1 minute */
- }
-
- void init_dt(LapInfo *lap, struct DeferredTask *dtptr, ProcPtr task)
- {
- bzero((b_8 *) dtptr, sizeof(struct DeferredTask));
- dtptr->qType = dtQType;
- dtptr->dtAddr = (ProcPtr) task;
- dtptr->dtParm = (long) lap;
- }
-
- void install_tm (LapInfo *lap, register struct TMprocess *tmptr, ProcPtr task) {
- bzero((b_8 *) tmptr, (short) sizeof(TMTask));
- tmptr->atm.tmAddr = task;
- tmptr->tmsavptr.lap = lap;
- InsTime((QElemPtr) tmptr);
- }