home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / mega src / Source / launch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-17  |  8.4 KB  |  343 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     launch.c
  4.         
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #include <Aliases.h>
  16. #include <appleevents.h>
  17. #include <GestaltEqu.h>
  18. #include <processes.h>
  19.  
  20. #include "nshc.h"
  21.  
  22. #include "arg_utl.proto.h"
  23. #include "fss_utl.proto.h"
  24. #include "nshc_utl.proto.h"
  25. #include "str_utl.proto.h"
  26.  
  27. /* ======================================== */
  28.  
  29. // prototypes
  30.  
  31. int        Pre7( void );
  32. int        is_it_running( OSType targetSignature );
  33. int        launch( int gotFSSpec, FSSpec *launchApp, FSSpec *launchDoc, t_nshc_calls *nshc_calls );
  34. OSErr    odoc( int gotFSSpec, FSSpec *doc_fss, OSType app_sig, t_nshc_calls *nshc_calls );
  35.  
  36. /* ======================================== */
  37.  
  38. // return true if 'sysv' is previous to 7.0
  39.  
  40. int    Pre7( void )
  41. {
  42.     OSErr    error;
  43.     long    response;
  44.     
  45.     if ( error = Gestalt( 'sysv', &response ) )
  46.         return(true);
  47.         
  48.     if ( response < 0x700 )
  49.         return(true);
  50.     else
  51.         return(false);
  52. }
  53.  
  54. /* ======================================== */
  55.  
  56. int    is_it_running( OSType targetSignature )
  57. {
  58.     Str255                    name;
  59.     ProcessSerialNumber        psn_p;
  60.     ProcessInfoRec          pi;
  61.             
  62.     pi.processName       = name;
  63.     pi.processInfoLength = sizeof(pi);
  64.     pi.processAppSpec    = NULL;
  65.     
  66.     psn_p.highLongOfPSN = 0;
  67.     psn_p.lowLongOfPSN  = kNoProcess;
  68.         
  69.     while(!GetNextProcess(&psn_p))
  70.         if(!GetProcessInformation(&psn_p,&pi))
  71.             if ( pi.processSignature == targetSignature )
  72.                 return( 1 );
  73.  
  74.     return( 0 );
  75. }
  76.  
  77. /* ======================================== */
  78.  
  79. int launch( int gotFSSpec, FSSpec *launchApp, FSSpec *launchDoc, t_nshc_calls *nshc_calls )
  80. {    
  81.     AEDesc                docDesc;
  82.     AEDesc                parmDesc;
  83.     AEDesc                adrDesc;
  84.     AEDescList            docList;
  85.     AliasHandle            docAlias;
  86.     AppleEvent            fakeEvent;
  87.     AppParametersPtr    docParm;
  88.     LaunchParamBlockRec    launchThis;
  89.     OSErr                myErr;
  90.     ProcessSerialNumber myPSN;
  91.     
  92.     // initialize
  93.     
  94.     docDesc.dataHandle = nil;
  95.     parmDesc.dataHandle = nil;
  96.     adrDesc.dataHandle = nil;
  97.     docList.dataHandle = nil;
  98.     docAlias = nil;
  99.     fakeEvent.dataHandle = nil;
  100.  
  101.     GetCurrentProcess(&myPSN);        // used to initialize new AE things
  102.     
  103.     // create the address desc for the event
  104.     
  105.     myErr = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN, sizeof(ProcessSerialNumber), &adrDesc);
  106.     if (myErr) goto Cleanup;
  107.  
  108.     // stuff it in my launch parameter block
  109.     
  110.     launchThis.launchAppSpec = launchApp;
  111.     
  112.     if (launchDoc) {
  113.         
  114.         // create an apple event for "open doc"
  115.         myErr = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &adrDesc, kAutoGenerateReturnID, kAnyTransactionID, &fakeEvent);
  116.         if (myErr) goto Cleanup;
  117.  
  118.         // create a list to hold the doc alias
  119.         myErr = AECreateList(nil, 0, false, &docList);
  120.         if (myErr) goto Cleanup;
  121.     
  122.         // ae needs an alias to the doc
  123.         myErr = NewAlias(nil, launchDoc, &docAlias);
  124.         if (myErr) goto Cleanup;
  125.  
  126.         // and a descriptor for the alias
  127.         HLock((Handle)docAlias);
  128.         myErr = AECreateDesc(typeAlias, (Ptr)*docAlias, GetHandleSize((Handle)docAlias), &docDesc);
  129.         HUnlock((Handle)docAlias);
  130.         if (myErr) goto Cleanup;
  131.     
  132.         // the descriptor goes in the list
  133.         myErr = AEPutDesc(&docList, 0, &docDesc);
  134.         if (myErr) goto Cleanup;
  135.         
  136.         // and the list goes into the event
  137.         myErr = AEPutParamDesc(&fakeEvent, keyDirectObject, &docList);
  138.         if (myErr) goto Cleanup;
  139.     
  140.         // but the fake event is REALLY a parameter!
  141.         myErr = AECoerceDesc(&fakeEvent, typeAppParameters, &parmDesc);
  142.         if (myErr) goto Cleanup;
  143.         
  144.         docParm = (AppParametersPtr)*(parmDesc.dataHandle);
  145.         }
  146.     else
  147.         docParm = nil;
  148.     
  149.     // stuff the LaunchParamBlockRec and send it
  150.     
  151.     HLock((Handle)fakeEvent.dataHandle);
  152.     
  153.     launchThis.launchAppParameters = docParm;
  154.     launchThis.launchBlockID = extendedBlock;
  155.     launchThis.launchEPBLength = extendedBlockLen;
  156.     launchThis.launchFileFlags = 0;
  157.     launchThis.launchControlFlags = launchContinue + launchNoFileFlags;
  158.     
  159.     myErr = LaunchApplication(&launchThis);
  160.     
  161.     HUnlock((Handle)fakeEvent.dataHandle);
  162.     
  163. Cleanup:
  164.  
  165.     if (myErr) nshc_calls->NSH_putStr_err("\plaunch: Message could not be sent.\r");
  166.     
  167.     if ( docDesc.dataHandle ) AEDisposeDesc(&docDesc);
  168.     if ( parmDesc.dataHandle ) AEDisposeDesc(&parmDesc);
  169.     if ( adrDesc.dataHandle ) AEDisposeDesc(&adrDesc);
  170.     if ( docList.dataHandle ) AEDisposeDesc(&docDesc);
  171.     if ( fakeEvent.dataHandle )AEDisposeDesc(&fakeEvent);
  172.  
  173.     if ( docAlias ) DisposeHandle((Handle)docAlias);
  174.  
  175.     return(myErr);
  176. }
  177.  
  178. /* ======================================== */
  179.  
  180. OSErr odoc( int gotFSSpec, FSSpec *doc_fss, OSType app_sig, t_nshc_calls *nshc_calls )
  181. {
  182.     OSErr            myErr;
  183.     FInfo            finfo;
  184.     int                appRunning;
  185.     AEDesc            appDesc;
  186.     AliasHandle        docAlias;
  187.     AppleEvent        openAE;
  188.     AppleEvent        replyAE;
  189.     AEDescList        docList;
  190.     
  191.     // initialize
  192.     
  193.     openAE.dataHandle = nil;
  194.     replyAE.dataHandle = nil;
  195.     appDesc.dataHandle = nil;
  196.     docList.dataHandle = nil;
  197.     
  198.     docAlias = nil;
  199.             
  200.     // see if the app is running
  201.     
  202.     appRunning = is_it_running( app_sig );
  203.     
  204.     if (!appRunning) {
  205.         nshc_calls->NSH_putStr_err("\podoc: Target process is not running\r");
  206.         return(1);
  207.         }
  208.  
  209.     myErr = AECreateDesc(typeApplSignature,
  210.                          (Ptr)&app_sig,
  211.                          sizeof(app_sig),
  212.                          &appDesc);
  213.     if (myErr) goto Cleanup;    
  214.                          
  215.     myErr = NewAlias(nil,doc_fss,&docAlias);
  216.     if (myErr) goto Cleanup;    
  217.  
  218.     myErr = AECreateAppleEvent(kCoreEventClass,
  219.                                kAEOpenDocuments,
  220.                                &appDesc,
  221.                                kAutoGenerateReturnID,
  222.                                kAnyTransactionID,
  223.                                &openAE);
  224.     if (myErr) goto Cleanup;    
  225.  
  226.     myErr = AECreateList(nil,0,false,&docList);
  227.     if (myErr) goto Cleanup;    
  228.  
  229.     HLock(docAlias);
  230.     myErr = AEPutPtr(&docList,
  231.                      0,
  232.                      typeAlias,
  233.                      (Ptr)*docAlias,
  234.                      sizeof(AliasHandle)+(**docAlias).aliasSize);
  235.     HUnlock(docAlias);
  236.     if (myErr) goto Cleanup;    
  237.  
  238.     myErr = AEPutParamDesc(&openAE,keyDirectObject,&docList);
  239.     if (myErr) goto Cleanup;
  240.     
  241.     myErr = AESend(&openAE,&replyAE,kAENoReply,kAENormalPriority,kAEDefaultTimeout,nil,nil);
  242.         
  243. Cleanup:
  244.  
  245.     if (myErr) nshc_calls->NSH_putStr_err("\podoc: Message could not be sent.\r");
  246.     
  247.     if (docList.dataHandle) AEDisposeDesc(&docList);
  248.     if (openAE.dataHandle) AEDisposeDesc(&openAE);
  249.     if (replyAE.dataHandle) AEDisposeDesc(&replyAE);
  250.     if (appDesc.dataHandle) AEDisposeDesc(&appDesc);
  251.     
  252.     if (docAlias) DisposHandle(docAlias);
  253.     
  254.     return(myErr);
  255. }
  256.  
  257. /* ======================================== */
  258.  
  259. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  260. {
  261.     FInfo    finfo;
  262.     FSSpec    app_fss;
  263.     FSSpec    doc_fss;
  264.     int        gotFSSpec;
  265.     int        result;
  266.     
  267.     nshc_parms->action = nsh_idle;        // always one pass to this command
  268.     gotFSSpec = fss_test();                // find out if fss is there
  269.     
  270.     // *** reason not to run 1 - bad included version
  271.     
  272.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION )) return;
  273.     
  274.     // *** reason not to run 2 - bad os version
  275.     
  276.     if ( Pre7() ) {
  277.         nshc_calls->NSH_putStr_err("\plaunch: This command requires System 7.\r");
  278.         nshc_parms->result = NSHC_ERR_GENERAL;
  279.         return;
  280.         }
  281.         
  282.     // *** reason not to run 3 - bad parameters
  283.     
  284.     if (( nshc_parms->argc < 2 ) || ( nshc_parms->argc > 3 )) {
  285.         nshc_calls->NSH_putStr_err("\pUsage: launch app_path [doc_path]\r");
  286.         nshc_parms->result = NSHC_ERR_PARMS;
  287.         return;
  288.         }
  289.         
  290.     // *** reason not to run 4 - can't find doc
  291.     
  292.     if ( nshc_parms->argc > 2 ) {
  293.     
  294.         result = arg_to_fss( nshc_parms, nshc_calls, 2, &doc_fss );
  295.     
  296.         if (!result)
  297.             result = fss_GetFInfo( gotFSSpec, &doc_fss, &finfo );
  298.     
  299.         if (result) {
  300.             nshc_calls->NSH_putStr_err("\plaunch: Document not found.\r");
  301.             nshc_parms->result = NSHC_ERR_PARMS;
  302.             return;
  303.             }
  304.             
  305.         }
  306.         
  307.     // *** reason not to run 5 - can't find app
  308.     
  309.     result = arg_to_fss( nshc_parms, nshc_calls, 1, &app_fss );
  310.     
  311.     if (!result)
  312.         result = fss_GetFInfo( gotFSSpec, &app_fss, &finfo );
  313.  
  314.     if (result || (finfo.fdType != 'APPL') ) {
  315.         nshc_calls->NSH_putStr_err("\plaunch: Application not found.\r");
  316.         nshc_parms->result = NSHC_ERR_PARMS;
  317.         return;
  318.         }
  319.         
  320.     // *** finally try to launch the thing
  321.     
  322.     if ( is_it_running( finfo.fdCreator ) ) {
  323.     
  324.         // if it is running but there is no doc ... don't worry
  325.     
  326.         if ( nshc_parms->argc > 2 )
  327.             result = odoc( gotFSSpec, &doc_fss, finfo.fdCreator, nshc_calls );
  328.     
  329.         }
  330.     else {
  331.         
  332.         if ( nshc_parms->argc > 2 )
  333.             result = launch( gotFSSpec, &app_fss, &doc_fss, nshc_calls );
  334.         else
  335.             result = launch( gotFSSpec, &app_fss, nil, nshc_calls );
  336.         
  337.         }
  338.     
  339.     // *** log the result and return
  340.             
  341.     nshc_parms->result = result;
  342. }
  343.