home *** CD-ROM | disk | FTP | other *** search
- /*
- ToolServer.c
-
- This function is sort of like a traditional Unix `system' command.
- The command is executed via ToolServer, which must be available on the
- current computer or through a network connection.
-
- Copyright (c) 1993 Anthony C. Ard.
-
- This program is free software; you can redistribute it and/or
- modifiy it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <Quickdraw.h>
- #include <Fonts.h>
- #include <Processes.h>
- #include <AppleEvents.h>
- #include <Errors.h>
- #include <CursorCtl.h>
- #include <StdIO.h>
- #include <StdLib.h>
- #include <String.h>
- #include <Strings.h>
- #include <Files.h>
- #include <PLStringFuncs.h>
-
- #define kMesgClass 'misc' /* 'Do Script' Apple Event. */
- #define kMesgID 'dosc'
-
- OSErr PathNameFromDirID( long dirID, short vRefNum, char *fullPathName )
- {
- Str255 dirName = "\p", fullName = "\p", tmpString;
- CInfoPBRec myCInfo;
- OSErr err = noErr;
-
- myCInfo.dirInfo.ioNamePtr = dirName;
- myCInfo.dirInfo.ioDrParID = dirID;
-
- do {
- myCInfo.dirInfo.ioVRefNum = vRefNum;
- myCInfo.dirInfo.ioFDirIndex = -1;
- myCInfo.dirInfo.ioDrDirID = myCInfo.dirInfo.ioDrParID;
-
- err = PBGetCatInfo( &myCInfo, false );
-
- if( err == noErr ) {
- PLstrcat( &dirName, "\p:" );
- if( (PLstrlen( &dirName ) + PLstrlen( &fullName )) > 255 ) err = bdNamErr;
- else {
- PLstrcpy( &tmpString, dirName );
- PLstrcat( &tmpString, fullName );
- PLstrcpy( &fullName, tmpString );
- }
- }
- } while( (myCInfo.dirInfo.ioDrDirID != fsRtDirID) && (err == noErr) );
- p2cstr( &fullName );
- strcpy( fullPathName, fullName );
- return err;
- }
-
- OSErr PathNameFromWD( int wdRefNum, char *pathName )
- {
- int dirID, procID;
- short vRefNum;
- OSErr err;
-
- err = GetWDInfo( wdRefNum, &vRefNum, &dirID, &procID );
-
- if( err == noErr ) err = PathNameFromDirID( dirID, vRefNum, pathName );
-
- return err;
- }
-
- OSErr GetCurrentDirectory( char *pathName )
- {
- return (PathNameFromDirID( 0, 0, pathName ));
- }
-
- static OSErr LaunchToolServer( ProcessSerialNumber *tsPSN )
- {
- char tsPath[256];
- FSSpec tsSpec;
- OSErr myErr;
- LaunchParamBlockRec myLaunchParams;
-
- strcpy( &tsPath, getenv( "ToolServerPath" ) );
-
- myErr = FSMakeFSSpec( 0, 0, (StringPtr)c2pstr( &tsPath ), (FSSpecPtr)&tsSpec );
- if( myErr == noErr ) {
- myLaunchParams.launchBlockID = extendedBlock;
- myLaunchParams.launchEPBLength = extendedBlockLen;
- myLaunchParams.launchFileFlags = 0;
- myLaunchParams.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- myLaunchParams.launchAppSpec = &tsSpec;
- myLaunchParams.launchAppParameters = nil;
-
- myErr = LaunchApplication( &myLaunchParams );
- if( myErr == noErr )
- memcpy( (char *)tsPSN, (char *)&myLaunchParams.launchProcessSN,
- sizeof( ProcessSerialNumber ) );
- /* Cause process manager to actually launch the application at the next
- WaitNextEvent call. */
- SpinCursor( 0 );
- }
- return myErr;
- }
-
- OSErr SendScriptEvent( AEAddressDesc *serverAddress, const char *command )
- {
- AppleEvent theAppleEvent, reply;
- DescType returnedType;
- long actualSize;
- OSErr myErr;
- char *scriptResult;
-
- myErr = AECreateAppleEvent( kMesgClass, kMesgID, serverAddress, kAutoGenerateReturnID,
- kAnyTransactionID, &theAppleEvent );
- if( myErr == noErr ) {
- myErr = AEPutParamPtr( &theAppleEvent, '----', 'TEXT', command,
- strlen( command ) * sizeof( char ) );
- if( myErr == noErr ) {
- myErr = AESend( &theAppleEvent, &reply, kAEWaitReply + kAENeverInteract,
- kAENormalPriority, kNoTimeOut, nil, nil );
- if( myErr == noErr ) {
- myErr = AESizeOfParam( &reply, keyDirectObject, &returnedType, &actualSize );
- if( myErr == noErr ) {
- scriptResult = (char *) malloc( actualSize + sizeof( char ) );
- if( scriptResult ) {
- myErr = AEGetParamPtr( &reply, keyDirectObject, typeChar, &returnedType,
- (Ptr) scriptResult, actualSize, &actualSize );
- if( myErr == noErr ) {
- scriptResult[actualSize] = '\0';
- fprintf( stdout, "%s\n", scriptResult );
- free( scriptResult );
- }
- } else myErr = memFullErr;
- } else if( myErr == errAEDescNotFound ) myErr = noErr; /* ToolServer had no output. */
- } else {
- /* The Apple Event wasn't successfully dispatched, the request timed out,
- the user canceled, or other error. */
- }
- }
- }
- AEDisposeDesc( &theAppleEvent ); AEDisposeDesc( &reply );
- return myErr;
- }
-
- int ToolServer( const char *command )
- {
- OSErr myErr;
- AEDesc tsAddress;
- char pathName[256];
- char tempString[256] = "SetDirectory '";
- static Boolean firstTime = true;
- static ProcessSerialNumber tsPSN;
-
- if( firstTime ) {
- myErr = LaunchToolServer( &tsPSN );
- if( myErr == noErr ) {
- myErr = AECreateDesc( typeProcessSerialNumber, (Ptr) &tsPSN, sizeof( tsPSN ), &tsAddress );
- if( myErr == noErr ) {
- firstTime = false;
-
- /* Get pathname of current working directory. */
- GetCurrentDirectory( &pathName );
- strcat( &tempString, pathName );
- strcat( &tempString, "'" );
-
- /* Sync ToolServer's directory with MPW Shell's */
- myErr = SendScriptEvent( &tsAddress, &tempString );
-
- /* Send the command */
- if( myErr == noErr ) myErr = SendScriptEvent( &tsAddress, command );
- }
- }
- } else {
- myErr = AECreateDesc( typeProcessSerialNumber, (Ptr) &tsPSN, sizeof( tsPSN ), &tsAddress );
- if( myErr == noErr ) myErr = SendScriptEvent( &tsAddress, command );
- }
- AEDisposeDesc( &tsAddress );
- return ((int) myErr);
- }
-
- #ifdef TEST
- int main()
- {
- int err;
-
- InitGraf( &qd.thePort );
- SetFScaleDisable( true );
- InitCursorCtl( nil );
- SpinCursor( 0 );
-
- err = ToolServer( "Files -l" );
- printf( "\n### ToolServer result: %d\n", err );
-
- return 0;
- }
- #endif /* TEST */
-