void* GC_MacGetDataStart() { CodeZeroHandle code0 = (CodeZeroHandle)GetResource('CODE', 0); if (code0) { long belowA5Size = (**code0).belowA5; ReleaseResource((Handle)code0); return (LMGetCurrentA5() - belowA5Size); } fprintf(stderr, "Couldn't load the jump table."); exit(-1); return 0; }
OSErr __pascal Runtime ( RTPB *prtpb ) { THUNK *pthunk; Boolean f32Bit; SLHT *pslht; // filter out invalid or trivial operations switch(prtpb->fOperation) { default: return eRTInvalidOp; break; case kRTPreLaunch: case kRTPostLaunch: // these are NOPs in our implementation return eRTNoErr; case kRTGetVersion: case kRTGetJTAddress: case kRTSetPreLoad: case kRTSetSegLoadErr: case kRTSetPostLoad: case kRTSetPreUnload: case kRTUnloadSeg: // use the current value of A5 pthunk = (THUNK *)LMGetCurrentA5(); break; case kRTGetVersionA5: case kRTGetJTAddressA5: case kRTSetPreLoadA5: case kRTSetSegLoadErrA5: case kRTSetPostLoadA5: case kRTSetPreUnloadA5: // use the value of A5 passed to us pthunk = prtpb->fA5; break; } // Determine if the app is 32-bit everything by looking for the flag entry // in the thunk table. If it's there, then also grab the pointer to the // RTI (runtime interface) used to communicate with LoadSeg. (char *)pthunk += LMGetCurJTOffset(); if (f32Bit = ((++pthunk)->op == kVersion32bit)) { // it is a 32-bit everything thunk table pslht = (SLHT *)pthunk->lOffset; } else { // kRTSet* and kRTUnloadSeg can't be used with "classic" thunks if (prtpb->fOperation >= kRTSetPreLoad) return eRTBadVersion; } // process each operation switch(prtpb->fOperation) { case kRTGetVersion: case kRTGetVersionA5: // return thunk table version prtpb->fRTParam.fVersionParam.fVersion = f32Bit ? kVersion32bit : kVersion16bit; break; case kRTGetJTAddress: case kRTGetJTAddressA5: // Return address of code pointed by the given thunk. // Thunk must be valid and in "Loaded" state. { THUNK *pthunkJT = (THUNK *) ((char *)prtpb->fRTParam.fJTAddrParam.fJTAddr - 2); if ( (pthunkJT <= ++pthunk) || (f32Bit && pthunkJT->op == opLoadSeg) || (!f32Bit && pthunkJT->op == opMoveWImm) ) return eRTInvalidJTPtr; prtpb->fRTParam.fJTAddrParam.fCodeAddr = (void *) pthunk->lOffset; } break; case kRTSetPreLoad: case kRTSetPreLoadA5: // hook segment preload handler and return old value prtpb->fRTParam.fSegLoadParam.fOldUserHdlr = (void *) pslht->pfnPreLoad; pslht->pfnPreLoad = prtpb->fRTParam.fSegLoadParam.fUserHdlr; break; case kRTSetSegLoadErr: case kRTSetSegLoadErrA5: // hook segment load error handler and return old value prtpb->fRTParam.fSegLoadParam.fOldUserHdlr = (void *) pslht->pfnSegLoadErr; pslht->pfnSegLoadErr = prtpb->fRTParam.fSegLoadParam.fUserHdlr; break; case kRTSetPostLoad: case kRTSetPostLoadA5: // hook segment postload handler and return old value prtpb->fRTParam.fSegLoadParam.fOldUserHdlr = (void *) pslht->pfnPostLoad; pslht->pfnPostLoad = prtpb->fRTParam.fSegLoadParam.fUserHdlr; break; case kRTSetPreUnload: case kRTSetPreUnloadA5: // hook segment preunload handler and return old value prtpb->fRTParam.fSegLoadParam.fOldUserHdlr = (void *) pslht->pfnPreUnload; pslht->pfnPreUnload = prtpb->fRTParam.fSegLoadParam.fUserHdlr; break; case kRTUnloadSeg: // Calls the __RTUnloadSegSn routine to unload a segment __RTUnloadSegSn(prtpb->fRTParam.fUnloadSegParam.fSegNumber, 0L); break; } // normal termination, no error return eRTNoErr; }
OSErr OpenCTBConnection(ConnHandle* connection) { Str255 toolName; Point where; Ptr configStream; Ptr tempString; EventRecord event; Rect dialogLoc; OSErr error = noErr; char* here; char* end; long baud; Boolean done; short result = noErr; if (*connection != nil) { // put our A5 value into the connection record so that the search callbacks // can get it and restore it CMSetUserData(*connection,(long) LMGetCurrentA5()); // CMChoose Dialog has to hang off this point (global coordinates) SetRect(&dialogLoc, 0, 0, 495, 285); CenterOnCurrentScreen(&dialogLoc); where.h = dialogLoc.left; where.v = dialogLoc.top; // now do CMChoose et al: done = false; do { result = CMChoose(connection, where, NULL); // MAD fprintf(mfp,"result is %d. major = %d minor = %d\n",result,chooseOKMajor,chooseOKMinor); if ((result == chooseOKMajor) || (result == chooseOKMinor)) { configStream = CMGetConfig(*connection); if (configStream == NULL) { done = true; error = -1; } else { CMGetToolName((***connection).procID, toolName); tempString = NewPtrClear(GetPtrSize(configStream) + 5); strcpy(tempString, "Baud "); here = strstr(configStream, tempString); if (here != nil) { here += strlen(tempString); baud = strtol(here, &end, 10); if (baud < 38400) { // MAD: PC seems to default to this, baud = 38400; // no matter what the user tries to set! strcpy(tempString, configStream); sprintf(tempString + (here - configStream), "%ld", baud); strcat(tempString, end); error = CMSetConfig(*connection, tempString); // Try to use the modified configuration if (error == noErr) { // It worked; save it DisposePtr(configStream); configStream = NewPtrClear(GetPtrSize(tempString)); memcpy(configStream, tempString, GetPtrSize(tempString)); DisposePtr(tempString); } } } strcpy(tempString, "CTS"); here = strstr(configStream, tempString); if (here != nil) { result = CautionAlert(CTSWarningdlog, nil); if (result == 2) { // The Continue option error = CreateConfigRes(configStream); error = CreateToolNameRes(toolName); done = true; } } else { error = CreateConfigRes(configStream); // MAD fprintf(mfp,"CreateConfigRes = %d\n",error); error = CreateToolNameRes(toolName); // MAD fprintf(mfp,"CreateToolNames = %d\n",error); done = true; } DisposePtr(configStream); } } else { //ErrorTerminate(-2, "\pее CMChoose failed. ее"); // MAD fprintf(mfp,"CMChoose failed\n"); if (*connection != nil) { CMDispose(*connection); *connection = nil; } error = -2; done = true; } } while (!done); // open the connection, send some data, and then close the connection if (error == noErr) { error = CMOpen(*connection, false, nil, 0); // MAD fprintf(mfp,"CMOpen = %d\n",error); } } return error; }
void *ottcp_new(Symbol *s, short argc, Atom *argv) { OTTCP *x; OSStatus err; // These variables will be filled with the args we parse char *inetHostName = 0; InetPort port = 0; long readbufsize = DEFAULT_BUFFER_SIZE; long writebufsize = DEFAULT_BUFFER_SIZE; EnterCallback(); if (ParseArgs(argc, argv, &inetHostName, &port, &readbufsize, &readbufsize) == 0) { ouchstring("ottcp usage: \"ottcp [<hostname> <port>] [readbufsize <nbytes>] [writebufsize <nbytes>]\""); ExitCallback(); return 0; } post("Parsed args: inetHostName %s, port %ld, readbufsize %ld, writebufsize %ld", inetHostName, port, readbufsize, writebufsize); x = newobject(ottcp_class); x->o_a5 = (long) LMGetCurrentA5(); x->o_inetHostName = inetHostName; x->o_inetPort = port; x->o_inetHost = 0; if (x->o_inetHostName != 0) { // They gave the server's IP address and port # as arguments if (LookUpInetHost(x->o_inetHostName, &(x->o_inetHost)) == 0) { post("е OTTCP: can't understand host \"%s\"; not connecting", x->o_inetHostName); } } x->o_state = SETTING_UP; x->o_datawaiting = 0; x->o_errorreporting = 1; x->o_outlet = outlet_new(x,0L); x->o_clock = clock_new(x, (method) do_output); x->o_connectedclock = clock_new(x, (method) do_output_connected); x->o_connectionSymbol = 0; OTClearLock(&(x->o_readlock)); /* Allocate buffers */ x->o_ReadBufSize = readbufsize; x->o_WriteBufSize = writebufsize; x->o_ReadBufA = NewPtr(readbufsize); x->o_ReadBufB = NewPtr(readbufsize); x->o_WriteBuf = NewPtr(writebufsize); if (x->o_ReadBufA == 0 || x->o_ReadBufB == 0 || x->o_WriteBuf == 0) { ouchstring("ottcp: not enough memory for two %ld byte read buffers and a %ld byte write buffer.", readbufsize, writebufsize); } x->o_currentReadBuf = x->o_ReadBufA; x->o_nextReadBuf = x->o_ReadBufB; x->o_bytesRead = 0; x->o_bytesReadForNextTime = 0; x->o_WBReadPos = 0; x->o_WBWritePos = 0; /* Make the endpoint */ x->o_tcp_ep = 0; // Indicates endpoint hasn't been created yet. err = OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &(x->epinfo), OTTCPNotifier, x); if (err != noErr) { ouchstring("otudp: Error %d from OTAsyncOpenEndpoint. This is bad.", err); return 0; } // This didn't actually make the endpoint; my notifier should get the T_OPENCOMPLETE // event after the endpoint is opened. ExitCallback(); return (x); }