[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [MacPerl] AppleEvents with remote addresses



Thanks for getting back to me, Chris.  I'm getting up to speed on MacPerl as  
quickly as I can, and your help is very much appreciated.  Hopefully, I'll  
have something to contribute to the community before this is over.

> At 17.41 -0400 1999.07.26, Cameron Ashby wrote:
> >I'm writing an special purpose application to remote control an
> >installation of a large number of Macs from a single administrative Mac
> >running MacPerl. I'd prefer to avoid installing MacPerl on all of the
> >clients.
> >
> >I have a prototype that works using MacPerl::doAppleScript, but is,
> >unsurprisingly, quite slow.  I would like to generate AppleEvents from
> >perl, but will use precompiled AppleScript through OSA if AppleEvents
> >are going to be a tremendously difficult thing to do.

On Mon, 26 Jul 1999, Chris Nandor <pudge@pobox.com> wrote:
>
> Apple events and OSA stuff are becoming quite easy to use in many cases
> (see Mac::Glue, Mac::AppleEvents::Simple, Mac::OSA::Simple, macperlcat,
> all on <URL:http://pudge.net/macperl/>).
>

I've been working with the various Mac packages with mostly good results.   
I've had good success using Mac::OSA to precompile scripts, which is a nice  
performance boost over doAppleScript.  Unless I have a breakthrough (very)  
soon, that's the version that's going to my client.

> However, I have not found any way of reliably (manually) packing a PPC
> address.  I have been successful in packing one with the use of the PPC
> Chooser, though.  So if you want to get a dialog box every time you
> connect to another machine (which you often need to do anyway, since you
> need to log in to the other machine), then it might be a sufficient
> solution.
>

One of my requirements is no user interaction, so the chooser isn't really  
going to work.  I have an OSAX that has let me work around the login issue so  
far.

I'm able to pack a PPC address in such a way that it no longer complains of  
"malformed PPCPortRec", but now it's angry about my LocationKindSelector.   
I'm assuming that the data structure is misaligned somehow.  I've included  
some code below.  What It produces doesn't look like what the chooser returns  
in Perl, but does look like what it returns in C.  Suggestions would be  
appreciated.

I'm also thinking about starting work on an interface to PPCToolbox.h, where  
the issue would get taken care of using typemaps.  That would be totally new  
ground for me, and probably not a small job.  Can anyone guess at the time  
investment to within an order of magnitude?  Is it possible/reasonable to do  
it with nothing but MPW, or do I need to pay for an environment?

> Now, PPC addresses don't work with Mac::Glue or
> Mac::AppleEvents::Simple (yet, it is on my TODO list), but they work
> fine with Mac::AppleEvents, once you get them.
>

I browsed through Mac::AppleEvents::Simple, and found a dependancy on  
typeApplSignature, so I had been using Mac::AppleEvents anyway.  I had no  
trouble getting it to work locally.

> Here is the basic gist of getting such an address (the syso\ppcb event
> will present the PPC Chooser):
>
>    use Mac::AppleEvents::Simple;
>    do_event(qw(misc actv MACS));                             # activate
> Finder
>    my $app = do_event(qw(syso ppcb MACS))->data->data->get;  # get
> address
>
> Now use it:
>
>    my $evt = AEBuildAppleEvent(qw(clas evid), typeTargetID, $app,
>        kAutoGenerateReturnID, kAnyTransactionID, $parameters)
>        or die $^E;
>
> I don't know if proper packing of PPC addresses is being worked on in
> the next socket code, perhaps Matthias can answer that.  It is
> certainly something that is needed.

Do the do_event and  AEBuildAppleEvent calls flatten and unflatten the data  
structure behind the scenes somehow?  It looks like that's what's going on.

Well, now that I'm working on it, I intend to figure it out eventually...

Thanks again for your help,

Cameron Ashby
Evolution Online Systems

+---------------------+
#!perl
use Mac::AppleEvents;

$sessionid = 0;                   #  safe to leave 0?
$scriptcode = 0;                  #  May or may not be safe to leave 0
$porttypesel = 1;                 #  PPCPortKinds : ppcByCreatorAndType
$creatortype = "ep01";            #  from empirical observation
$locationtypesel = 1;             #  PPCLocationKind : ppcNBPLocation
#$appname = "Internet Explorer";
#$appsign = "MSIE";
$appname = "Netscape Navigator";
$appsign = "MOSS";
$machine = "Mac of an unsuspecting friend";
$porttype = "PPCToolbox";
$zone = "*";  # your zone may vary

$url = "www.slashdot.org";

# Pascal style strings of type Str32Field
# (which is 34 bytes long for alignment)
$sappname = pack("ca33", length($appname), $appname);
$smachine = pack("ca33", length($machine), $machine);
$sporttype = pack("ca33", length($porttype), $porttype);
$szone = pack("ca33", length($zone), $zone);
print $sappname, "\n";
# pack a struct targetID - sessionid, PPCPortRec, LocationNameRec
# significant changes to the format will generate the error:
# "PPCPortRec malformed (OS error -919)."
# perhaps there's an alignment issue somewhere?
$foo = pack("lsP34sa4a4sP34P34P34",
			$sessionid,
			$scriptcode,
			$sappname,
			$porttypesel,
			$appsign,
			$creatortype,
			$locationtypesel,
			$smachine,
			$sporttype,
			$szone
			);
			
$bar = new AEDesc('targ', $foo) or die $^E;

$evt = AECreateAppleEvent("WWW!", "OURL", $bar) or die $^E;
AEPutParamDesc($evt, '----', (AEBuild('TEXT(@)', $url))) or die $^E;

# Here we get:
# "Invalid or inappropriate locationKindSelector in location name
# (OS error -902)."
$rep = AESend($evt, kAEWaitReply()) or die $^E;

AEDisposeDesc($rep);
AEDisposeDesc($evt);
AEDisposeDesc($bar);

### DON'T TRY THIS AT HOME KIDS!
### Trying to unpack the address generates application error type 2
# $foo = do_event(qw(syso ppcb MACS))->data->data->get;
# (	$sessionid,
# 	$scriptcode,
# 	$sappname,
# 	$porttypesel,
# 	$appsign,
# 	$creatortype,
# 	$locationtypesel,
# 	$smachine,
# 	$sporttype,
# 	$szone
# ) = unpack("lsP34sa4a4sP34P34P34", $foo);


#  Apendix A:  data structures of interest...
#
#  struct TargetID {
#  	long	sessionID;
#  	PPCPortRec	name;
#  	LocationNameRec	location;
#  	PPCPortRec	recvrName;	/* This field is reserved */
#  };
#  typedef struct TargetID	TargetID;
#
#  struct PPCPortRec {
#  	ScriptCode	nameScript;	/* script of name */
#  	Str32Field	name;	/* name of port as seen in browser */
#  	PPCPortKinds	portKindSelector;	/* which variant */
#  	union {
#  		Str32	portTypeStr;		* pascal type string */
#  		struct {
#  			OSType	portCreator;
#  			OSType	portType;
#  		}	port;
#  	}	u;
#  };
#  typedef struct PPCPortRec	PPCPortRec;
#
#  struct LocationNameRec {
#  	PPCLocationKind	locationKindSelector;	/* which variant */
#  	union {
#  		EntityName nbpEntity;	/* NBP name entity */
#  		Str32	 nbpType; /* just the NBP type string, for PPCOpen */
#  	}	u;
#  };
#  typedef struct LocationNameRec	LocationNameRec;
#
#  struct EntityName {
#  	Str32Field	objStr;
#  	Str32Field	typeStr;
#  	Str32Field	zoneStr;
#  };
#  typedef struct EntityName	EntityName;

===== Want to unsubscribe from this list?
===== Send mail with body "unsubscribe" to macperl-request@macperl.org