(file) Return to Net.pm CVS log (file) (dir) Up to [RizwankCVS] / geekymedia_web / twiki / lib / TWiki

  1 rizwank 1.1 # Module of TWiki Collaboration Platform, http://TWiki.org/
  2             #
  3             # Copyright (C) 2001-2004 Peter Thoeny, peter@thoeny.com
  4             #
  5             # For licensing info read license.txt file in the TWiki root.
  6             # This program is free software; you can redistribute it and/or
  7             # modify it under the terms of the GNU General Public License
  8             # as published by the Free Software Foundation; either version 2
  9             # of the License, or (at your option) any later version.
 10             #
 11             # This program is distributed in the hope that it will be useful,
 12             # but WITHOUT ANY WARRANTY; without even the implied warranty of
 13             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14             # GNU General Public License for more details, published at 
 15             # http://www.gnu.org/copyleft/gpl.html
 16             #
 17             # Notes:
 18             # - Latest version at http://twiki.org/
 19             # - Installation instructions in $dataDir/TWiki/TWikiDocumentation.txt
 20             # - Customize variables in TWiki.cfg when installing TWiki.
 21             #
 22 rizwank 1.1 #  14-02-2001 - Nicholas Lee
 23             
 24             =begin twiki
 25             
 26             ---+ TWiki::Net Module
 27             
 28             This module handles network related functions like http access and
 29             send mail.
 30             
 31             =cut
 32             
 33             package TWiki::Net;
 34             
 35             use strict;
 36             
 37             use vars qw(
 38                     $useNetSmtp
 39                     $mailInitialized $mailHost $helloHost
 40                 );
 41             
 42             BEGIN {
 43 rizwank 1.1     $useNetSmtp = 0;
 44                 $mailInitialized = 0;
 45             }
 46             
 47             # =========================
 48             =pod
 49             
 50             ---++ sub getUrl (  $theHost, $thePort, $theUrl, $theUser, $thePass, $theHeader  )
 51             
 52             Not yet documented.
 53             
 54             =cut
 55             
 56             sub getUrl
 57             {
 58                 my ( $theHost, $thePort, $theUrl, $theUser, $thePass, $theHeader ) = @_;
 59             
 60                 # Run-time use of Socket module when needed
 61                 require Socket;
 62                 import Socket qw(:all);
 63             
 64 rizwank 1.1     if( $thePort < 1 ) {
 65                     $thePort = 80;
 66                 }
 67                 my $base64;
 68                 my $result = '';
 69                 $theUrl = "/" unless( $theUrl );
 70                 my $req = "GET $theUrl HTTP/1.0\r\n";
 71             
 72                 # RNF 22 Jan 2002 Support for vhosts and user authentication.
 73                 $req .= "Host: $theHost\r\n";
 74                 if( $theUser && $thePass ) {
 75             	# Use MIME::Base64 at run-time if using outbound proxy with 
 76             	# authentication
 77             	require MIME::Base64;
 78             	import MIME::Base64 ();
 79                     $base64 = encode_base64( "$theUser:$thePass", "\r\n" );
 80                     $req .= "Authorization: Basic $base64";
 81                 }
 82             
 83                 # RNF 19 Apr 2002 Support for outbound proxies.
 84                 my $proxyHost = &TWiki::Prefs::getPreferencesValue("PROXYHOST");
 85 rizwank 1.1     my $proxyPort = &TWiki::Prefs::getPreferencesValue("PROXYPORT");
 86                 if($proxyHost && $proxyPort) {
 87                     $req = "GET http://$theHost$theUrl HTTP/1.0\r\n";
 88                     $theHost = $proxyHost;
 89                     $thePort = $proxyPort;
 90                 }
 91             
 92                 $req .= $theHeader if( $theHeader );
 93                 $req .= "\r\n\r\n";
 94             
 95                 my ( $iaddr, $paddr, $proto );
 96                 $iaddr   = inet_aton( $theHost );
 97                 $paddr   = sockaddr_in( $thePort, $iaddr );
 98                 $proto   = getprotobyname( 'tcp' );
 99                 unless( socket( *SOCK, &PF_INET, &SOCK_STREAM, $proto ) ) {
100                     &TWiki::writeWarning( "TWiki::Net::getUrl socket: $!" );
101                     return "content-type: text/plain\n\nERROR: TWiki::Net::getUrl socket: $!.";
102                 }
103                 unless( connect( *SOCK, $paddr ) ) {
104                     &TWiki::writeWarning( "TWiki::Net::getUrl connect: $!" );
105                     return "content-type: text/plain\n\nERROR: TWiki::Net::getUrl connect: $!. \n$req";
106 rizwank 1.1     }
107                 select SOCK; $| = 1;
108                 print SOCK $req;
109                 while( <SOCK> ) { $result .= $_; }
110                 unless( close( SOCK ) ) {
111                     &TWiki::writeWarning( "TWiki::Net::getUrl close: $!" );
112                 }
113                 select STDOUT;
114                 return $result;
115             }
116             
117             # =========================
118             =pod
119             
120             ---++ sub sendEmail (  $theText  )
121             
122             Not yet documented.
123             
124             =cut
125             
126             sub sendEmail
127 rizwank 1.1 {
128                 # $theText Format: "Date: ...\nFrom: ...\nTo: ...\nCC: ...\nSubject: ...\n\nMailBody..."
129             
130                 my( $theText ) = @_;
131             
132                 # Put in a Date header, mainly for Qmail
133                 my $dateStr = &TWiki::formatTime(time, 'email');
134                 $theText = "Date: " . $dateStr . "\n" . $theText;
135             
136                 # Check if Net::SMTP is available
137                 if( ! $mailInitialized ) {
138                     $mailInitialized = 1;
139                     $mailHost  = &TWiki::Prefs::getPreferencesValue( "SMTPMAILHOST" );
140                     $helloHost = &TWiki::Prefs::getPreferencesValue( "SMTPSENDERHOST" );
141                     if( $mailHost ) {
142             	   eval {	# May fail if Net::SMTP not installed
143             	       $useNetSmtp = require Net::SMTP;
144             	   }
145                     }
146                 }
147             
148 rizwank 1.1     my $error = "";
149                 # Send the email.  Use Net::SMTP if it's installed, otherwise use a
150                 # sendmail type program.
151                 if( $useNetSmtp ) {
152                     my ( $header, $body ) = split( "\n\n", $theText, 2 );
153                     my @headerlines = split( /\n/, $header );
154                     $header =~ s/\nBCC\:[^\n]*//os;  #remove BCC line from header
155                     $header =~ s/([\n\r])(From|To|CC|BCC)(\:\s*)([^\n\r]*)/$1 . $2 . $3 . _fixLineLength( $4 )/geois;
156                     $theText = "$header\n\n$body";   # rebuild message
157             
158                     # extract 'From:'
159                     my $from = "";
160                     my @arr = grep( /^From: /i, @headerlines );
161                     if( scalar( @arr ) ) {
162                         $from = $arr[0];
163                         $from =~ s/^From:\s*//io;
164                         $from =~ s/.*<(.*?)>.*/$1/o; # extract "user@host" out of "Name <user@host>"
165                     }
166                     if( ! ( $from ) ) {
167                         return "ERROR: Can't send mail, missing 'From:'";
168                     }
169 rizwank 1.1 
170                     # extract @to from 'To:', 'CC:', 'BCC:'
171                     my @to = ();
172                     @arr = grep( /^To: /i, @headerlines );
173                     my $tmp = "";
174                     if( scalar( @arr ) ) {
175                         $tmp = $arr[0];
176                         $tmp =~ s/^To:\s*//io;
177                         @arr = split( /[,\s]+/, $tmp );
178                         push( @to, @arr );
179                     }
180                     @arr = grep( /^CC: /i, @headerlines );
181                     if( scalar( @arr ) ) {
182                         $tmp = $arr[0];
183                         $tmp =~ s/^CC:\s*//io;
184                         @arr = split( /[,\s]+/, $tmp );
185                         push( @to, @arr );
186                     }
187                     @arr = grep( /^BCC: /i, @headerlines );
188                     if( scalar( @arr ) ) {
189                         $tmp = $arr[0];
190 rizwank 1.1             $tmp =~ s/^BCC:\s*//io;
191                         @arr = split( /[,\s]+/, $tmp );
192                         push( @to, @arr );
193                     }
194             
195                     if( ! ( scalar( @to ) ) ) {
196                         return "ERROR: Can't send mail, missing receipient";
197                     }
198             
199                     $error = _sendEmailByNetSMTP( $from, \@to, $theText );
200             
201                 } else {
202                     # send with sendmail
203                     my ( $header, $body ) = split( "\n\n", $theText, 2 );
204                     $header =~ s/([\n\r])(From|To|CC|BCC)(\:\s*)([^\n\r]*)/$1 . $2 . $3 . _fixLineLength( $4 )/geois;
205                     $theText = "$header\n\n$body";   # rebuild message
206                     $error = _sendEmailBySendmail( $theText );
207                 }
208                 return $error;
209             }
210             
211 rizwank 1.1 # =========================
212             =pod
213             
214             ---++ sub _fixLineLength (  $theAddrs  )
215             
216             Not yet documented.
217             
218             =cut
219             
220             sub _fixLineLength
221             {
222                 my( $theAddrs ) = @_;
223                 # split up header lines that are too long
224                 $theAddrs =~ s/(.{60}[^,]*,\s*)/$1\n        /go;
225                 $theAddrs =~ s/\n\s*$//gos;
226                 return $theAddrs;
227             }
228             
229             # =========================
230             =pod
231             
232 rizwank 1.1 ---++ sub _sendEmailBySendmail (  $theText  )
233             
234             Not yet documented.
235             
236             =cut
237             
238             sub _sendEmailBySendmail
239             {
240                 my( $theText ) = @_;
241             
242                 if( open( MAIL, "|-" ) || exec "$TWiki::mailProgram" ) {
243                     print MAIL $theText;
244                     close( MAIL );
245                     return "";
246                 }
247                 return "ERROR: Can't send mail using TWiki::mailProgram";
248             }
249             
250             # =========================
251             =pod
252             
253 rizwank 1.1 ---++ sub _sendEmailByNetSMTP (  $from, $toref, $data  )
254             
255             Not yet documented.
256             
257             =cut
258             
259             sub _sendEmailByNetSMTP
260             {
261                 my( $from, $toref, $data ) = @_;
262             
263                 my @to;
264                 # $to is not a reference then it must be a single email address
265                 @to = ($toref) unless ref( $toref ); 
266                 if ( ref( $toref ) =~ /ARRAY/ ) {
267             	@to = @{$toref};
268                 }
269                 return undef unless( scalar @to );
270                 
271                 my $smtp = 0;
272                 if( $helloHost ) {
273                     $smtp = Net::SMTP->new( $mailHost, Hello => $helloHost );
274 rizwank 1.1     } else {
275                     $smtp = Net::SMTP->new( $mailHost );
276                 }
277                 my $status = "";
278                 if ($smtp) {
279                     {
280                         $smtp->mail( $from ) or last;
281                         $smtp->to( @to, { SkipBad => 1 } ) or last;
282                         $smtp->data( $data ) or last;
283                         $smtp->dataend() or last;
284             	}
285             	$status = ($smtp->ok() ? "" : "ERROR: Can't send mail using Net::SMTP. " . $smtp->message );
286             	$smtp->quit();
287             
288                 } else {
289             	$status = "ERROR: Can't send mail using Net::SMTP (can't connect to '$mailHost')";
290                 }
291                 return $status;    
292             }
293             
294             # =========================
295 rizwank 1.1 
296             1;
297             
298             # EOF

Rizwan Kassim
Powered by
ViewCVS 0.9.2