{\rtf0\ansi{\fonttbl\f0\fmodern Courier;\f1\ftech Symbol;\f3\fnil Times-Roman;\f2\fmodern Ohlfs;}
\margl40
\margr40
{\colortbl;\red0\green0\blue0;}
\pard\tx520\tx1060\tx1600\tx2120\tx2660\tx3200\tx3720\tx4260\tx4800\tx5320\f0\b0\i0\ulnone\fs24\fc0\cf0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//
\i 	
\b FILENAME
\b0 :	
\b\i0 Router.m\

\b0 //
\i 	
\b SUMMARY
\b0 :	
\b\i0 Implementation of Router, which adds various services to NXApp
\b0 \
//	
\b\i SUPERCLASS
\b0 :
\i0 	
\b Application(Router)	
\b0 \
//	
\b\i PROTOCOLS
\b0 :
\i0 	
\b <MailListener>
\b0 \
//	
\b\i INTERFACE
\b0 :
\i0 	
\b None
\b0 \
//	
\b\i AUTHOR
\b0 :		
\b\i0 Rohit Khare
\b0 \
//	
\b\i COPYRIGHT
\b0 :	
\f1\i0 с
\f0\b 1993,94 California Institure of Technology, eText Project\

\b0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b\i Implementation Comments
\b0\i0 \
//		The savePanel accessory and ID routines are interesting.\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b\i HISTORY
\b0\i0 \
//	10/22/94:	
\b Added GLOBAL/Mailer support as per Greg Anderson's post.
\b0 \
//	09/27/94:	
\b Revamped for eText5
\b0 \
//	07/06/94:	
\b Added kernel-wide mail-messaging support.
\b0 \
//	01/10/94:	
\b Added sharedText
\b0 \
//	01/05/94:	
\b Created.
\b0 \
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Imported Interfaces
\b0 \
//\
	#import "
\b Router.h
\b0 "\
\

\i @implementation Application (Router)\

\i0 //ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Public Services
\b0 \
//\
- (long) 
\b uniqueID
\b0  \{\
	
\b static 
\b0 BOOL
\b  seeded
\b0 =
\b NO
\b0 ;\
	\

\i 	// Strategy: We have 24 sigbits of epoch in the one year.\
	// Epoch-count is not unique, since the odds of epoch-collision is\
	// a fucntion of users and activity rate. By shoehorning into a 32bit\
	// int, we are forced to support, at best, 2^8 transactions per second,\
	// where a transaction is any call to uniqueID anywhere in the world!\
	// Thus, we must migrate to 64bits...\
	// The pattern is:\
	// |....epoch(32)....|...pid(8) |...counter(8)...|...millisec(16)...| \
	\
	// However, this scheme is foolish, since it wastes an extreme number of\
	// bits for the sake of monotonicity. Instead, we will rely on BSD's random\
	// call, for which we offer a large amount of custom state, namely, the\
	// user's encrypted login password, pid, and millisecond.\

\i0 	\
	if (
\b !seeded
\b0 ) \{\
		
\b char
\b0  
\b state
\b0 [
\b 17
\b0 ];\
		struct timeval t;		\
		\
		
\b strncpy
\b0 (
\b state+2
\b0 , 
\b NXUserName
\b0 (), 14);\
		
\b gettimeofday
\b0 (&
\b t
\b0 , NULL);\
		
\b state
\b0 [
\b 0
\b0 ] = t.
\b tv_usec
\b0  & 
\b MAXINT
\b0 ;\
		state[
\b 16
\b0 ] = 
\b 0
\b0 ;\
		
\b initstate
\b0 (t.
\b tv_sec
\b0 , 
\b crypt
\b0 (
\b state
\b0 , "
\b Rk
\b0 ")+
\b 2
\b0 , 
\b 8
\b0 );\
		
\b seeded
\b0  = 
\b YES
\b0 ;\
	\}\
	return 
\b random()
\b0 ;\
\}\
- (const char *) 
\b versionStr\

\b0 	\{return (const char *)NXUniqueString("
\b 0.93
\b0 ");\}\
	\
- (const char *)
\b date
\b0  \{\
    
\b static
\b0  char		
\b buffer
\b0 [
\b 64
\b0 ];\
    struct tm			*timeptr;\
    time_t				timer;\
\
    
\b time
\b0 (&
\b timer
\b0 );\
    
\b timeptr
\b0  = 
\b localtime
\b0 (&
\b timer
\b0 );\
    
\b strftime
\b0 (buffer, sizeof(buffer), "
\b %c
\b0 ", 
\b timeptr
\b0 );\
    return 
\b buffer
\b0 ;\
\}\
- 
\b sendMailTo
\b0 :(const char *)to 
\b cc
\b0 :(const char *)cc 
\b subject
\b0 :(const char *)subject\
        
\b body
\b0 :(const char*)body 
\b deliver
\b0 :(BOOL)deliver \{\
    Speaker     *
\b speaker
\b0 ;\
    port_t      portSend = PORT_NULL;\
    int         window = 0;\
    BOOL        success = NO;\
\

\i 	// Stock a new Compose window in Mail.app and optionally deliver it.\
	// Any char* args may be NULL.\
	// By Hugh Secker-Walker, based on code by Simson Garfinkel.\

\i0     if ((
\b speaker
\b0  = [[
\b Speaker
\b0  alloc] 
\b init
\b0 ]) == nil)  return nil;\

\i     // make sure Mail.app is launched\

\i0\fc1\cf1 	
\b\fc0\cf0 portSend
\b0\fc1\cf1  = 
\b NXPortFromName
\b0 ("
\b MailSendDemo
\b0 ", 0);\
	if (
\fc0\cf0 portSend
\fc1\cf1 ==
\b PORT_NULL
\b0 ) \{\
		const char *
\b mailer
\b0  = 
\b NXGetDefaultValue
\b0 ("
\b GLOBAL
\b0 ", "
\b Mailer
\b0 ");\
		port_t portmail = 
\b NXPortFromName
\b0 (mailer ? 
\b mailer
\b0  : "
\b Mail
\b0 ", 0); \
		
\b port_deallocate
\b0 (
\b task_self
\b0 (), 
\b portmail
\b0 );\
	\}\
	
\fc0\cf0 portSend
\fc1\cf1  = 
\b NXPortFromName
\b0 ("
\b MailSendDemo
\b0 ", 0);\
	if (
\fc0\cf0 portSend
\fc1\cf1 ==
\b PORT_NULL
\b0 ) return 
\b nil
\b0 ;\

\i\fc0\cf0     // make speaker use the port\

\i0     [
\b speaker
\b0  
\b setSendPort
\b0 :
\b portSend
\b0 ];\

\i     // open a new compose window in Mail, get window number\

\i0     if ([
\b speaker
\b0  selectorRPC:"
\b openSend:
\b0 " paramTypes:"
\b I
\b0 ", &
\b window
\b0 ])  \
        goto 
\b tidy
\b0 ;\

\i     // send the fields to the window\

\i0     if (
\b to
\b0  && [
\b speaker
\b0  selectorRPC:"
\b setTo:inWindow:
\b0 " paramTypes:"
\b ci
\b0 ",\
               to, window] )  goto 
\b tidy
\b0 ;\
    if (
\b cc
\b0  && [
\b speaker
\b0  selectorRPC:"
\b setCc:inWindow:
\b0 " paramTypes:"
\b ci
\b0 ",\
               cc, window] )  goto 
\b tidy
\b0 ;\
    if (
\b subject
\b0  && [
\b speaker
\b0  selectorRPC:"
\b setSubject:inWindow:
\b0 " paramTypes:"
\b ci
\b0 ",\
                    subject, window] )  goto 
\b tidy
\b0 ;\
    if (
\b body
\b0  && [
\b speaker
\b0  selectorRPC:"
\b setBody:inWindow:
\b0 " paramTypes:"
\b ci
\b0 ",\
                 body, window] )  goto 
\b tidy
\b0 ;\
    if (
\b deliver
\b0  && [
\b speaker
\b0  selectorRPC:"
\b deliver:
\b0 " paramTypes:"
\b i
\b0 ", window] )\
		goto 
\b tidy
\b0 ;\
    
\b success
\b0  = 
\b YES
\b0 ;\
\
 
\b tidy
\b0 :\
    speaker = [
\b speaker
\b0  
\b free
\b0 ];\
    
\b port_deallocate
\b0 (task_self(), 
\b portSend
\b0 );\
\
    
\b return
\b0  (
\b success
\b0  ? self : nil);\
\}\
\
//ппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппппп\
//	
\b Public Objects
\b0 \
//\
- 
\b etApp\

\b0 	\{return 
\b etApp
\b0 ;\}\
- 
\b etAppUI\

\b0 	\{return 
\b etAppUI
\b0 ;\}\
- 
\b userModel\

\b0 	\{return 
\b userModel
\b0 ;\}\
- 
\b navigator\

\b0 	\{return 
\b navigator
\b0 ;\}\
- 
\b inspector\

\b0 	\{return 
\b inspector
\b0 ;\}\
- 
\b sharedText
\b0  \{\
	
\b static
\b0  
\b id theText
\b0  = nil;\
	NXSize	s = \{
\b MAXFLOAT
\b0 , 
\b MAXFLOAT
\b0 \};\
	\
	if (
\b !theText
\b0 ) \{\
		
\b theText
\b0  = [[Text alloc] 
\b init
\b0 ];\
		[theText 
\b setVertResizable
\b0 :
\b YES
\b0 ];\
		[theText 
\b setHorizResizable
\b0 :
\b NO
\b0 ];\
		[theText 
\b setMaxSize
\b0 :&s];\
	\}\
	return 
\b theText
\b0 ;\
\}\
\

\i @end\

\i0 \
/*\

\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\f3\fs28\fc1\cf1 Yes there is a simple answer, and I'll volunteer the scant lines of code \
required to do it properly. The following code snippet looks to see if any \
running app is offering a "MailSendDemo" port. If not, it looks at the user's \
defaults database for an app designated as the preferred mailer. (You can \
specify that by typing "dwrite GLOBAL Mailer MyPreferredMailer" in a Terminal \
window.) Failing that, it drops back to Mail.app.\

\pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\fc1\cf1 */
}
