From VisualWorks®, 7.6 of February 1, 2008 on February 1, 2008 at 12:34:09 pm (Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned. Choose terminate or close.'] <class> <name>SMTPState</name> <environment>Net</environment> <super>Net.NetClientState</super> <private>false</private> none <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPState
SMTPState is superclass for all SMTP states. Publishes command signatures, implements them all as invalid for the state
</comment> <class> <name>SMTPNotConnectedState</name> <environment>Net</environment> <super>Net.SMTPState</super> <private>false</private> none <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPNotConnectedState
SMTPNotConnectedState is set when the client is not connected to a server
</comment> <class> <name>SMTPProtocolInterpreter</name> <environment>Net</environment> <super>Net.NetProtocolInterpreter</super> <private>false</private> none <imports></imports> <category>SMTP</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPProtocolInterpreter
SMTPProtocolInterpreter manages SMTP server connection and provides interface for sending SMTP commands and handling SMTP responses.
</comment> <class> <name>SMTPQuitFailure</name> <environment>Net</environment> <super>Core.Warning</super> <private>false</private> none <imports></imports> <category>SMTP</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPQuitFailure
The SMTPQuitFailure is raised when the client sent the #QUIT command but a server closed the connection without any reply for #QUIT. We observed this behavior with the gmail server for SSL connection. Usually the server finishes all transactions anyway
</comment> <class> <name>SMTPConnectedState</name> <environment>Net</environment> <super>Net.SMTPState</super> <private>false</private> none <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPConnectedState
SMTPConnectedState state is used when the client is connected and the user has to be authorized to SMTP server. Only authorization commands are valid
</comment> <class> <name>SMTPAuthentication</name> <environment>Net</environment> <super>Core.Object</super> <private>false</private> none client <imports></imports> <category>SMTPAUTH</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPAuthentication
SMTPAuthentication is an abstract class that implements authentication mechanism for SMTP commands. Subclasses must implement the following messages: authenticate authenticate Instance Variables: client <SMTPClient> SMTP client
</comment> <class> <name>SMTPAuthenticatedState</name> <environment>Net</environment> <super>Net.SMTPState</super> <private>false</private> none <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPAuthenticatedState
SMTPAuthenticatedState is set when the user has connected in and authorized himself to an SMTP server. Messages can be sent now
</comment> <class> <name>SMTPConnection</name> <environment>Net</environment> <super>Net.NetConnection</super> <private>false</private> none <imports> private OS.IOConstants.* </imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPConnection
SMTPConnection is the SMTP connection stream wrapper
</comment> <class> <name>PlainAuthentication</name> <environment>Net</environment> <super>Net.SMTPAuthentication</super> <private>false</private> none <imports></imports> <category>SMTPAUTH</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.PlainAuthentication
PlainAuthentication implements 'AUTH PLAIN' authentication
</comment> <class> <name>SMTPClient</name> <environment>Net</environment> <super>Net.NetClient</super> <private>false</private> none serverResponses useAuthentication useAuthentication <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPClient
SMPT Client sends rfc822 messages to SMTP server. SMTPClient uses state objects to validate if a request is valid in a given state and to handle state transitions. Instance Variables: useAuthentication <Boolean> the option specifies whether or not the sending utilities will use EHLO command and authentication scheme if the server has one. The defaut is true. If the the option is set to false the client starts the session with the HELO command. serverResponses <OrderedCollection> server responses Class Variables: useAuthentication <Boolean> default option
</comment> <class> <name>SMTPStateError</name> <environment>Net</environment> <super>Net.NetClientError</super> <private>false</private> none <imports></imports> <category>SMTP</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPStateError
SMTPStateError signals the error for commands that are invalid in the current state
</comment> <class> <name>SMTPTransactionState</name> <environment>Net</environment> <super>Net.SMTPState</super> <private>false</private> none <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPTransactionState
The SMTPTransactionState starts when the SMTP client initiates a mail transaction in which the mail data will be delivered to an SMTP server. The transaction state starts with the "MAIL" command
</comment> <class> <name>SMTPWriteHandler</name> <environment>Net</environment> <super>Net.MimeWriteHandler</super> <private>false</private> none blindRecipients <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SMTPWriteHandler
This writer is used to write rfc822 messages on an SMTP stream. If the rfc822 message contains "bcc:" fields, the "bcc:" lines will be removed even though all of the recipients (including those specified in the "bcc:" field) are sent a copy of the message. The 'Bcc:' field (where the 'Bcc' means 'Blind Carbon Copy') contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message. Instance Variables: blindRecipients <Collection of (String)> default: #('bcc' 'resent-bcc')
</comment> <class> <name>SimpleSMTPClient</name> <environment>Net</environment> <super>Net.NetClient</super> <private>false</private> none stream serverResponse connection <imports></imports> <category>Net-SMTP-Support</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.SimpleSMTPClient
The class is obsolete and will be removed eventually. Use SMTPClient instead of it.
</comment> <class> <name>LoginAuthentication</name> <environment>Net</environment> <super>Net.SMTPAuthentication</super> <private>false</private> none <imports></imports> <category>SMTPAUTH</category> <attributes> <package>SMTP</package> </attributes> </class> <comment> Net.LoginAuthentication
LoginAuthentication implements 'AUTH LOGIN' authentication
</comment> <name>CRLF</name> <environment>Net.SimpleSMTPClient</environment> <private>false</private> <constant>true</constant> <category>constants</category> <initializer>Core.String with: (Core.Character cr) with: (Core.Character lf)</initializer> <attributes> <package>SMTP</package> </attributes> <methods> Net.SMTPState <category>commands</category>
authenticateLogin self signalError
authenticatePlain self signalError
data self signalError
ehlo self signalError
ehloDo: aBlock self signalError
expand "The case of expanding a mailbox list requires a multiline reply, such as: C: EXPN Example-People S: 250-Jon Postel <Postel@isi.edu> S: 250-Fred Fonebone <Fonebone@physics.foo-u.edu> S: 250 Sam Q. Smith <SQSmith@specific.generic.com> or C: EXPN Executive-Washroom-List S: 550 Access Denied to You." self client sendCommand: 'EXPN'. self client readResponses. ^self client serverResponses
hello self signalError
help ^self client executeCommand: 'HELP'.
login self signalError
mailFrom: aMailMessage self signalError
noop ^self client executeCommand: 'NOOP'.
quit ^self client executeCommand: 'QUIT'.
recipients: aCollection self signalError
reset " This command specifies that the current mail transaction will be aborted. Any stored sender, recipients, and mail data MUST be discarded, and all buffers and state tables cleared. " self client executeCommand: 'RSET'. ^self client serverResponses
verify: aString "3.5.2 VRFY Normal Response When normal (2yz or 551) responses are returned from a VRFY or EXPN the following are legitimate response to VRFY: 553 User ambiguous or 553- Ambiguous; Possibilities are 553-Harry Smith <hsmith@foo.com> 553 Melvin Smith <dweep@foo.com> 3.5.3 Meaning of VRFY or EXPN Success Response A server MUST NOT return a 250 code in response to a VRFY or EXPN command unless it has actually verified the address. In particular, a server MUST NOT return 250 if all it has done is to verify that the syntax given is valid. In that case, 502 (Command not implemented) or 500 (Syntax error, command unrecognized) SHOULD be returned. As stated elsewhere, implementation (in the sense of actually validating addresses and returning information) of VRFY and EXPN are strongly recommended. " self client clientPI sendCommand: 'VRFY ', aString. ^self client clientPI readResponses.
writeMessage: mailMessage self signalError
</methods> <methods> Net.SMTPState <category>accessing</category>
stateErrorClass ^SMTPStateError
</methods> <methods> Net.SMTPProtocolInterpreter <category>responses</category>
readResponses | result replyStream serverResponses | serverResponses := OrderedCollection new. replyStream := self connection getResponseStream. [result := replyStream throughAll: CRLF. self log: [ ('S: <1s>' expandMacrosWith: result) ] level: #SMTPServer. serverResponses add: result. result size > 4 and: [(result at: 4)= $-]] whileTrue. ^serverResponses
serverErrorCheck: aCollection "Raise an error if the last response from the SMTP server has an error." | str code | code := (aCollection first copyFrom: 1 to: 3 ) asNumber. code >= 400 ifTrue: [str := String new writeStream. aCollection do: [ :each | str nextPutAll: each ]. NetClientError signalWith: self message: 'SMTPClient: ',str contents. ]
waitForResponses | serverResponses | serverResponses:= self readResponses. serverResponses first notEmpty ifTrue: [self serverErrorCheck: serverResponses]. ^serverResponses
</methods> <methods> Net.SMTPProtocolInterpreter <category>public</category>
executeCommand: aString self sendCommand: aString. ^self waitForResponses.
sendCommand: string "Will CRLF terminate" self isConnected ifFalse: [NetClientError signalWith: #SMTPClient message: (#SMTPClientConnectionIsClosed << #net >>'SMTPClient: Connection is closed') asString.]. self log: [ ('C: <1s>' expandMacrosWith: string) ] level: #SMTPClient. MailIncrementNotification signalWith: string size. self stream nextPutAll: string; nextPutAll: CRLF; commit
</methods> <methods> Net.SMTPProtocolInterpreter <category>ssl connection</category>
sslConnectionClass ^#{Net.SMTPSSLConnection} value
</methods> <methods> Net.SMTPProtocolInterpreter <category>private</category>
writeMessage: mailMessage [ self stream lineEndCRLF. self log: [ | str | str := String new writeStream. SMTPWriteHandler writeMessage: mailMessage on: str. ('C: <1s>' expandMacrosWith: str contents) ] level: #SMTPClient. SMTPWriteHandler writeMessage: mailMessage on: self stream] ensure: [ self stream lineEndTransparent]. self executeCommand: CRLF, '.'.
</methods> <methods> Net.SMTPProtocolInterpreter class <category>debugging</category>
debugLabelsAndValues ^OrderedCollection new add: ((#SMTPClientMessages << #net >> 'SMTP Client Messages')->#SMTPClient); add: ((#SMTPServerMessages << #net >> 'SMTP Server Messages')->#SMTPServer); yourself
menuItemName ^(#SMTPClientMessages << #net >> 'SMTP Client Messages')
</methods> <methods> Net.SMTPProtocolInterpreter class <category>class initialization</category>
initialize "self initialize." self registerToDebug.
</methods> <methods> Net.SMTPProtocolInterpreter class <category>default values</category>
defaultNetConnectionValue ^SMTPConnection
</methods> <methods> Net.SMTPConnectedState <category>commands</category>
authenticateLogin ^self client executeCommand: 'AUTH LOGIN'.
authenticatePlain ^self client executeCommand: 'AUTH PLAIN'.
ehlo ^self ehloDo: []
ehloDo: aBlock self client executeCommand: ('EHLO ', self client hostName). aBlock value. self client state: SMTPAuthenticatedState new. ^self client serverResponses
handShakeServer (self client user isNil or: [self client username isNil or: [ self client password isNil]]) ifTrue: [NetClientError signalWith: #authenticate message: (#CanNotAuthenticateTheUser << #net >> 'Can not authenticate the user. There is no user name or password provided.')]. self ehloDo: [ (SMTPAuthentication for: self client ) authenticate].
hello self client executeCommand: ('HELO ', self client hostName). self client state: SMTPAuthenticatedState new. ^self client serverResponses
login self client useAuthentication ifTrue: [self handShakeServer ] ifFalse: [self hello ].
startTLS ^self client executeCommand: 'STARTTLS'.
</methods> <methods> Net.SMTPAuthentication <category>accessing</category>
client ^client
client: smtpClient client := smtpClient
</methods> <methods> Net.SMTPAuthentication <category>authenticate</category>
authenticate
</methods> <methods> Net.SMTPAuthentication class <category>instance creation</category>
for: smtpClient | auth policies | auth := smtpClient serverResponses detect: [:each | (each indexOfSubCollection: 'AUTH ' startingAt: 1) ~= 0] ifNone: [nil]. policies := OrderedCollection new. auth notNil ifTrue: [ (auth indexOfSubCollection: 'LOGIN' startingAt: 1) ~= 0 ifTrue: [ policies add: LoginAuthentication ]. (auth indexOfSubCollection: 'PLAIN' startingAt: 1) ~= 0 ifTrue: [ policies add: PlainAuthentication ]]. ^(policies isEmpty ifTrue: [ auth := smtpClient serverResponses detect: [:each | (each indexOfSubCollection: 'STARTTLS' startingAt: 1) ~= 0] ifNone: [nil]. auth ifNotNil: [^NetClientError signalWith: smtpClient message: 'STARTTLS has not yet implemented']. self ] ifFalse: [ policies first ]) new client: smtpClient; yourself
</methods> <methods> Net.SMTPAuthenticatedState <category>commands</category>
mailFrom: aString | from resp | from := (self client user notNil and: [self client user mailAddress notNil ]) ifTrue: [self client user mailAddress ] ifFalse: [aString ]. resp := self client executeCommand: ('MAIL FROM:%<<1s>%>' expandMacrosWith: from). self client state: SMTPTransactionState new. ^resp
</methods> <methods> Net.SMTPConnection <category>private</category>
privateQuitDo: aBlock aBlock value
</methods> <methods> Net.SMTPConnection class <category>default values</category>
defaultLineEndConvention ^LineEndTransparent
defaultPortNumber ^SocketAccessor IPPORT_SMTP
</methods> <methods> Net.PlainAuthentication <category>authenticate</category>
authenticate self client authenticatePlain. self client executeCommand: (self encodeLoginPassword: self client user).
encodeLoginPassword: netUser " Encoding string as base64 " | stream | stream := (ByteArray new withEncoding: #BASE64) writeStream. stream nextPut: (Character value: 0). stream nextPutAll: netUser username. stream nextPut: (Character value: 0). stream nextPutAll: netUser password. stream close. ^(stream encodedContents withEncoding: #ASCII) readStream contents
</methods> <methods> Net.SMTPClient <category>commands</category>
authenticateLogin ^self state authenticateLogin
authenticatePlain ^self state authenticatePlain
data ^self state data
ehlo ^self state ehlo
ehloDo: aBlock ^self state ehloDo: aBlock
expand ^self state expand
hello ^self state hello
help ^self state help
login self state login
mailFrom: aString "This command is used to initiate a mail transaction in which the mail data is delivered to an SMTP server which may, in turn, deliver it to one or more mailboxes or pass it on to another system (possibly using SMTP). The argument field contains a reverse-path and may contain optional parameters. In general, the MAIL command may be sent only when no mail transaction is in progress" ^self state mailFrom: aString
noop ^self state noop
quit " This command specifies that the receiver MUST send an OK reply, and then close the transmission channel." [self connection privateQuitDo: [self state quit.] ] ensure: [ self disconnect ].
recipients: aCollection ^self state recipients: aCollection
reset ^self state reset
senderAddressFrom: mailMessage ^(self user notNil and: [self user mailAddress notNil ]) ifTrue: [self user mailAddress ] ifFalse: [mailMessage smtpFromSendStrings ].
startTLS ^self state startTLS
verify: aString ^self state verify: aString
</methods> <methods> Net.SMTPClient <category>accessing</category>
serverResponses ^serverResponses isNil ifTrue: [serverResponses := OrderedCollection new] ifFalse: [serverResponses]
useAuthentication ^useAuthentication ifNil: [useAuthentication := self class useAuthentication]
useAuthentication: aBoolean useAuthentication := aBoolean
</methods> <methods> Net.SMTPClient <category>low-level command interface</category>
executeCommand: aString serverResponses := self clientPI executeCommand: aString. ^serverResponses
writeMessage: mailMessage self state writeMessage: mailMessage.
</methods> <methods> Net.SMTPClient <category>connection management</category>
close self quit
connect super connect. self state: SMTPConnectedState new. ^self clientPI waitForResponses.
disconnect "Disconnect from the host" super disconnect. self state: SMTPNotConnectedState new.
</methods> <methods> Net.SMTPClient <category>initialize-release</category>
initialize super initialize. self state: SMTPNotConnectedState new.
</methods> <methods> Net.SMTPClient <category>utilities</category>
send: mailMessage self connectIfClosed. [self login. self sendMessage: mailMessage ] ensure: [ self quit ]
sendMessage: mailMessage self mailFrom: (self senderAddressFrom: mailMessage). self recipients: mailMessage smtpDestinationAddresses. self writeMessage: mailMessage
</methods> <methods> Net.SMTPClient class <category>constants</category>
description ^(#outgoingMailServer << #net >> 'outgoing mail server') asString
serverType ^#SMTP
</methods> <methods> Net.SMTPClient class <category>testing</category>
isIncomingMailClient ^false
isMailClient ^true
isOutgoingMailClient ^true
</methods> <methods> Net.SMTPClient class <category>private</category>
update: anAspect with: arguments from: anObject
</methods> <methods> Net.SMTPClient class <category>class initialization</category>
initialize "self initialize." super initialize. self registerToDebug.
registerClass self mailRegistry at: self serverType put: self name
</methods> <methods> Net.SMTPClient class <category>default values</category>
defaultProtocolInterpreterClassValue ^SMTPProtocolInterpreter
useAuthenticationValue ^true
</methods> <methods> Net.SMTPClient class <category>defaults</category>
useAuthentication ^useAuthentication ifNil: [useAuthentication := self useAuthenticationValue]
useAuthentication: aBoolean useAuthentication := aBoolean
</methods> <methods> Net.SMTPTransactionState <category>commands</category>
data ^self client executeCommand: 'DATA'.
recipients: aCollection aCollection do: [ :receiver | self client executeCommand: ('RCPT TO:%<<1s>%>' expandMacrosWith: receiver)]. ^self client serverResponses
reset | resp | resp := super reset. self client state: SMTPAuthenticatedState new. ^resp
writeMessage: mailMessage self data. self client clientPI writeMessage: mailMessage. self client state: SMTPAuthenticatedState new
</methods> <methods> Net.SMTPWriteHandler <category>defaults</category>
defaultBlindRecipients ^#('bcc' 'resent-bcc')
</methods> <methods> Net.SMTPWriteHandler <category>private</category>
selectFieldsFrom: aMessageHeader | fields finalFields | fields := super selectFieldsFrom: aMessageHeader. finalFields := OrderedCollection new: fields size. finalFields addAll: ( fields reject: [ :fieldx | self blindRecipients includes: fieldx name]). ^finalFields
</methods> <methods> Net.SMTPWriteHandler <category>accessing</category>
blindRecipients ^blindRecipients ifNil: [ self defaultBlindRecipients ]
blindRecipients: aCollection blindRecipients := aCollection
</methods> <methods> Net.SimpleSMTPClient <category>accessing</category>
portNumber portNumber ifNil: [ portNumber := self class defaultPortNumber ]. ^portNumber
serverResponse ^serverResponse isNil ifTrue: [serverResponse := String new] ifFalse: [serverResponse]
serverResponse: aString self class log: [ ('R: <1s>' expandMacrosWith: aString) ] level: #SMTPServer. serverResponse := aString. self serverErrorCheck
username: aString self user isNil ifTrue: [ self user: (NetUser new username: aString; yourself)] ifFalse: [ self user username: aString]
</methods> <methods> Net.SimpleSMTPClient <category>private</category>
closeConnection stream ~~ nil ifTrue: [stream close]
createConnection | socket | socket := SocketAccessor newTCPclientToHost: self hostName port: self portNumber. connection := ExternalConnection new. connection input: socket; output: socket. stream := connection readAppendStream. stream lineEndTransparent. self waitForResponse.
sendLine: string "Will CRLF terminate" self class log: [ ('S: <1s>' expandMacrosWith: string) ] level: #SMTPClient. MailIncrementNotification signalWith: string size. stream nextPutAll: string; nextPutAll: CRLF; commit
serverErrorCheck "Raise an error if the last response from the SMTP server has an error." | replyCode | replyCode := (self serverResponse copyUpTo: Character space) asNumber. replyCode >= 400 ifTrue: [^self error: ((#SMTPError1s << #net >> 'SMTP Error <1s>') expandMacrosWith: self serverResponse)].
waitForResponse | result | result := stream throughAll: CRLF. self serverResponse: result
</methods> <methods> Net.SimpleSMTPClient <category>connection</category>
isConnected ^connection notNil
</methods> <methods> Net.SimpleSMTPClient <category>sending</category>
sendMessage: mailMessage ^self sendMessage: mailMessage toAll: mailMessage smtpDestinationAddresses
sendMessage: mailMessage toAll: receivers | from | self createConnection. [self sendLine: ('HELO <1s>' expandMacrosWith: self hostName). self waitForResponse. from := (self user notNil and: [self user mailAddress notNil ]) ifTrue: [self user mailAddress ] ifFalse: [mailMessage smtpFromSendStrings ]. self sendLine: ('MAIL FROM:%<<1s>%>' expandMacrosWith: from). self waitForResponse. receivers do: [:receiver | self sendLine: ('RCPT TO:%<<1s>%>' expandMacrosWith: receiver). self waitForResponse]. self sendLine: 'DATA'. self waitForResponse. [stream lineEndCRLF. SMTPWriteHandler writeMessage: mailMessage on: stream] ensure: [stream lineEndTransparent]. self sendLine: CRLF , '.'. self waitForResponse. self sendLine: 'QUIT'. self waitForResponse] ensure: [self closeConnection]
</methods> <methods> Net.SimpleSMTPClient class <category>testing</category>
isIncomingMailClient ^false
isMailClient ^true
isOutgoingMailClient ^true
</methods> <methods> Net.SimpleSMTPClient class <category>private</category>
update: anAspect with: arguments from: anObject
</methods> <methods> Net.SimpleSMTPClient class <category>constants</category>
description ^(#outgoingMailServer << #net >> 'outgoing mail server') asString
serverType ^#SMTP
</methods> <methods> Net.SimpleSMTPClient class <category>class initialization</category>
initialize "self initialize." super initialize. self registerToDebug.
registerClass
</methods> <methods> Net.SimpleSMTPClient class <category>debugging</category>
debugLabelsAndValues ^OrderedCollection new add: ((#SMTPClientMessages << #net >> 'SMTP Client Messages')->#SMTPClient); add: ((#SMTPServerMessages << #net >> 'SMTP Server Messages')->#SMTPServer); yourself
menuItemName ^(#SMTPClientMessages << #net >> 'SMTP Client Messages')
</methods> <methods> Net.SimpleSMTPClient class <category>defaults</category>
defaultPortNumber ^SocketAccessor IPPORT_SMTP
</methods> <methods> Net.LoginAuthentication <category>authenticate</category>
authenticate self client authenticateLogin. self client executeCommand: (self encodeLogin: self client user). self client executeCommand: (self encodePassword: self client user).
encodeLogin: netUser " Encoding string as base64 " | stream | stream := (ByteArray new withEncoding: #BASE64) writeStream. stream nextPutAll: netUser username. stream close. ^(stream encodedContents withEncoding: #ASCII) readStream contents
encodePassword: netUser " Encoding string as base64 " | stream | stream := (ByteArray new withEncoding: #BASE64) writeStream. stream nextPutAll: netUser password. stream close. ^(stream encodedContents withEncoding: #ASCII) readStream contents
</methods> <methods> Net.MailMessage <category>accessing</category>
smtpDestinationAddresses " Answer collection of destination addresses. These addresses have been preprocessed to make them good for SMTP transport. This means removing everything but address-spec " | coll f | coll := OrderedCollection new. self destinationFields do: [ :fn | (f := self fieldAt: fn ifAbsent: [nil]) ifNotNil: [coll addAll: ( f addresses collect: [ :addressDesc | addressDesc addressSpecString])]]. ^coll
smtpFromSendStrings | str | (self getFieldAt: 'from') addresses do: [ :adx | (str := adx addressSpecString) notEmpty ifTrue: [ ^str]]. ^String new
</methods> <initialize> Net.SMTPProtocolInterpreter </initialize> <initialize> Net.SMTPClient </initialize> <initialize> Net.SimpleSMTPClient </initialize> "Imported Classes:" self error: 'Attempting to file-in parcel imports. Choose terminate or close' <class> <name>Object</name> <environment>Core</environment> <super></super> <private>false</private> none <imports></imports> <category>Kernel-Objects</category> <attributes> <package>Kernel-Objects</package> </attributes> </class> <class> <name>NetProtocolInterpreter</name> <environment>Net</environment> <super>Core.Object</super> <private>false</private> none connection defaultNetConnection <imports></imports> <category>Net-Clients</category> <attributes> <package>NetClientBase</package> </attributes> </class> <class> <name>Warning</name> <environment>Core</environment> <super>Core.Exception</super> <private>false</private> none <imports></imports> <category>Kernel-Exception Handling</category> <attributes> <package>Kernel-Exception Handling</package> </attributes> </class> <class> <name>NetConnection</name> <environment>Net</environment> <super>Core.Object</super> <private>false</private> none stream encoding <imports> private OS.IOConstants.* </imports> <category>Net-Clients</category> <attributes> <package>NetClientBase</package> </attributes> </class> <class> <name>NetClientError</name> <environment>Net</environment> <super>Net.NetError</super> <private>false</private> none <imports></imports> <category>Net-Clients</category> <attributes> <package>NetClientBase</package> </attributes> </class> <class> <name>MailMessage</name> <environment>Net</environment> <super>Net.RFC822Message</super> <private>false</private> none <imports></imports> <category>Net-MIME-Support</category> <attributes> <package>Mail</package> </attributes> </class> <class> <name>NetClient</name> <environment>Net</environment> <super>Core.Object</super> <private>false</private> none user hostName portNumber clientPI retries timeout delaySeconds state defaultProtocolInterpreterClass <imports></imports> <category>Net-Clients</category> <attributes> <package>NetClientBase</package> </attributes> </class> <class> <name>MimeWriteHandler</name> <environment>Net</environment> <super>Net.MimeOutputHandler</super> <private>false</private> none preferFieldSource originalStream binaryMode applyTransferEncoding applyTransferEncoding <imports></imports> <category>Net-MIME-Support</category> <attributes> <package>MIME</package> </attributes> </class> <class> <name>NetClientState</name> <environment>Net</environment> <super>Core.Object</super> <private>false</private> none client <imports></imports> <category>Net-Clients</category> <attributes> <package>NetClientBase</package> </attributes> </class>