1 |
#!/usr/local/bin/perl |
2 |
|
3 |
BEGIN { $APP_PATH="/home/httpd/html/webmail/cgi-bin/"; } |
4 |
|
5 |
# @ ---------------------------------------------------------------------------------------------------------- |
6 |
# @ This code is (c) 1999 Alexandre Aufrere and NikoSoft. |
7 |
# @ Published under NPL rights, meaning you have the right |
8 |
# @ to use and modify this code freely, provided it |
9 |
# @ remains available and free. Any modified code should be |
10 |
# @ submitted to Nikopol Software Corp. or Alexandre Aufrere. |
11 |
# @ This code is protected by the French laws on Copyright. |
12 |
# @ Please note that there it comes with NO WARRANTY of any kind, |
13 |
# @ and especially for any damagbe it could cause to your computer |
14 |
# @ or network. |
15 |
# @ Using this code means you agree to this license agreement. |
16 |
# @ Further information at http://aufrere.citeweb.net/nsc/ |
17 |
# @ ---------------------------------------------------------------------------------------------------------- |
18 |
# @ |
19 |
# @ Project NS WebMail |
20 |
# @ |
21 |
# @ Filename inbox.pl |
22 |
# @ |
23 |
# @ Description inbox manager for NS WebMail |
24 |
# @ |
25 |
# @ Version 1.0 |
26 |
# @ |
27 |
# @ ---------------------------------------------------------------------------------------------------------- |
28 |
|
29 |
use Mail::POP3Client; |
30 |
require $APP_PATH."config.pl"; |
31 |
|
32 |
#use the $cgi object method param() to |
33 |
#acquire the FORM variables passed by |
34 |
#the client browser. |
35 |
&ReadParse; |
36 |
$loginname = $in{'loginname'}; |
37 |
$password = $in{'password'}; |
38 |
$POPserver = $in{'POPserver'}; |
39 |
$lastMsg = $in{'lastMsg'}; |
40 |
$deleteMsg = $in{'deleteMsg'}; |
41 |
$cache = $in{'cache'}; |
42 |
$status = $in{'status'}; |
43 |
|
44 |
#if deleteMsg is not null, then this script has been called by the |
45 |
#Delete Message button. We will open a POP client object, delete |
46 |
#the indicated message, then close the POP object to actually force |
47 |
#the POP server to make the deletion. The rest of the script will |
48 |
#then play out and re-open the POP object. By closing and reopening |
49 |
#we will obtain an updated count that correctly does not include the |
50 |
#recently deleted message. |
51 |
|
52 |
if ($deleteMsg) { |
53 |
$pop = new Mail::POP3Client($loginname, $password, $POPserver); |
54 |
$pop->Delete($deleteMsg); |
55 |
$pop->Close(); |
56 |
$deleteMsg = ""; |
57 |
$pop = ""; |
58 |
sleep(1); # Gives the POP time to close and be ready for another |
59 |
# open attempt. |
60 |
} |
61 |
|
62 |
|
63 |
|
64 |
#Begin production of HTML code. |
65 |
print "Content-type: text/html\n\n"; |
66 |
print "<HTML><HEAD><TITLE>NS WM Message Retrieval</TITLE>"; |
67 |
|
68 |
print "<SCRIPT LANGUAGE='JavaScript'>\n"; |
69 |
print "function closeThisWindow() { \n"; |
70 |
print "window.close()\n"; |
71 |
print "}\n"; |
72 |
print "</SCRIPT>\n"; |
73 |
|
74 |
$onloadcode=""; |
75 |
if ($status eq "firstlogin") { $onloadcode="parent.menu.location='$PATH_NSWM/menu.htm';"; } |
76 |
if ($cache eq "No") { print "<META HTTP-EQUIV='Pragma' CONTENT='no-cache'>"; |
77 |
print "</HEAD>\n<BODY BGCOLOR='#FFFFFF' OnLoad=\"$onloadcode\">"; |
78 |
} |
79 |
else { print "</HEAD>\n<BODY BGCOLOR='FF8F8F'>"; |
80 |
} |
81 |
|
82 |
#print "<b><font size='+2'>NikoSoft WebMail</font></b><hr>"; |
83 |
print "<center>\n"; |
84 |
|
85 |
|
86 |
#Create a (possibly new) POP connection with the POP3Client object. |
87 |
$pop = new Mail::POP3Client($loginname, $password, $POPserver); |
88 |
|
89 |
#How many messages are there in the inbox provided by the $pop object? |
90 |
$MessageCount = $pop->Count; |
91 |
|
92 |
#gather additional size info |
93 |
@MessageSize = $pop->ListArray; |
94 |
|
95 |
print "<table><tr><td>"; |
96 |
#if $pop->count is -1, then the POP connection failed. |
97 |
if ($MessageCount == -1) { |
98 |
print "</table><font size=+1>$POPserver: $loginname, $incorrectlogin"; |
99 |
print "</body></html>"; |
100 |
exit; |
101 |
} |
102 |
#if $pop->count is 0, there are no messages in the POP account |
103 |
elsif ($MessageCount == 0) { |
104 |
print "<b> $nomailon <i>$POPserver</i></b>"; |
105 |
} |
106 |
#if $pop->count is >0, then that is the number of messages in the |
107 |
#POP account inbox. |
108 |
else { print "<img src=$MAIL_IMG valign=middle> "; |
109 |
print "<b>$MessageCount $messagesininbox (",$pop->Size," $bytestotaltext).</b>\n"; |
110 |
} |
111 |
|
112 |
#print "</td><td width=300 align=center>\n"; |
113 |
|
114 |
if ($MessageCount != -1) { #equivalent to knowing a valid POP account was used... |
115 |
#place a button that will allow the user to create a new mail message |
116 |
#without having to "reply" to a previously received one. This also |
117 |
#permits people to don't get much mail to be able to send something. |
118 |
print "<FORM METHOD='POST' ACTION='".$CGI_PATH_NSWM."sendform.pl' name=newMailForm>\n"; |
119 |
print "<INPUT TYPE='hidden' NAME='loginname' VALUE=$loginname>\n"; |
120 |
print "<INPUT TYPE='hidden' NAME='password' VALUE=$password>\n"; |
121 |
print "<INPUT TYPE='hidden' NAME='POPserver' VALUE=$POPserver>\n"; |
122 |
print "<INPUT TYPE='hidden' NAME='cache' VALUE=$cache>\n"; |
123 |
print "<INPUT TYPE='hidden' NAME='to' VALUE=''>\n"; |
124 |
print "<INPUT TYPE='hidden' NAME='subject' VALUE=''>\n"; |
125 |
print "</FORM>"; |
126 |
print "<FORM METHOD='POST' ACTION='".$CGI_PATH_NSWM."sentmail.pl' name=sentForm>\n"; |
127 |
print "<INPUT TYPE='hidden' NAME='loginname' VALUE=$loginname>\n"; |
128 |
print "<INPUT TYPE='hidden' NAME='password' VALUE=$password>\n"; |
129 |
print "<INPUT TYPE='hidden' NAME='POPserver' VALUE=$POPserver>\n"; |
130 |
print "<INPUT TYPE='hidden' NAME='cache' VALUE=$cache>\n"; |
131 |
print "</FORM>"; |
132 |
} |
133 |
print "</td></tr></table><br>\n"; |
134 |
|
135 |
|
136 |
#Parse the message headers to output a list of message |
137 |
#header info including SUBJECT,FROM,DATE,and TO. |
138 |
#each message will have a read & delete button as well |
139 |
#and these three elements will be organized in a table |
140 |
|
141 |
if ($MessageCount > 0) { |
142 |
print "<table border=0 cellpadding=2 cellspacing=0 width=90% align=center>"; |
143 |
print "<tr bgcolor=darkblue><td><b><font color=white>$fromtext</b></td><td><b><font color=white>$subjecttext</b></td><td><b><font color=white>$datetext</b></td><td colspan=2><font color=white><b>$sizetext </b></td>"; |
144 |
&ParseHeaders(); |
145 |
print "</table>"; |
146 |
} |
147 |
|
148 |
# At the end of the form, we will place a button which can obtain |
149 |
# more 'n' more mail messages. Note that the button makes a "recursive" |
150 |
# call. (In other words, it represents a perl script calling itself, |
151 |
# but with different variable values.) |
152 |
# |
153 |
# The only value that is different is the 'lastMsg' variable |
154 |
# which is Null in the posting from the "Check Your Mail" button, but is |
155 |
# set to a non-null value on posting from this ("Get More Messages") button. |
156 |
print "<FORM METHOD='POST' ACTION='".$CGI_PATH_NSWM."inbox.pl' name=inboxForm>\n"; |
157 |
print "<INPUT TYPE='hidden' NAME='loginname' VALUE=$loginname >\n"; |
158 |
print "<INPUT TYPE='hidden' NAME='POPserver' VALUE=$POPserver >\n"; |
159 |
print "<INPUT TYPE='hidden' NAME='password' VALUE=$password >\n"; |
160 |
print "<INPUT TYPE='hidden' NAME='cache' VALUE=$cache >\n"; |
161 |
print "</FORM></center>"; |
162 |
|
163 |
|
164 |
# Lastly, provide a button which will let the user 'Logout'. This |
165 |
# actually closes the window in use in order to destroy the history log |
166 |
# which contains the all previously viewed email, plus the clear text |
167 |
# login/password/host information that would allow an intruder access |
168 |
# to the account in the future. |
169 |
#print "<FORM METHOD='Post'>"; |
170 |
#print "<INPUT TYPE='button' VALUE='Quitter' onClick='closeThisWindow()'>"; |
171 |
#print "</FORM>\n"; |
172 |
|
173 |
|
174 |
#close the POP connection smoothly. |
175 |
$pop->Close; |
176 |
|
177 |
#send the ending html code (/body and /head tags) |
178 |
print "</BODY></HTML>"; |
179 |
exit; |
180 |
|
181 |
#----------------------------------SUBROUTINES------------------------- |
182 |
|
183 |
# Decode quoted strings (in From: and Subject) |
184 |
|
185 |
sub DecodeQuoted { |
186 |
my $tmp = $_[0]; |
187 |
if ($tmp =~ /=?ISO-8859-[1-2]?(.)?/i) { |
188 |
$tmp =~ s/=([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; |
189 |
$tmp =~ s/=\?ISO-8859-[1-2]\?.\?(.*)\?=/$1/i; |
190 |
} |
191 |
return $tmp; |
192 |
} |
193 |
|
194 |
#-----------------------------Sub ParseHeaders----------------------------- |
195 |
#Subroutine to parse the headers on each message to exctract the TO:, FROM:, |
196 |
# DATE:, and SUBJECT: information. |
197 |
#-------------------------------------------------------------------------- |
198 |
sub ParseHeaders { |
199 |
#loop through the messages in the POP account space |
200 |
|
201 |
#loop backwards, displaying most recent messages first |
202 |
#Also note that only the most recent 100 messages will be displayed from |
203 |
# |
204 |
|
205 |
if ($lastMsg == "") { $lastMsg = $MessageCount }; |
206 |
|
207 |
for ($i=$lastMsg; $i >= 1 && $i> $lastMsg-100; $i--) { |
208 |
|
209 |
|
210 |
#for each message header, provide a FORM button to |
211 |
#invoke getmessage.pl and hand that routine the message |
212 |
#number. Pass the login,pass,server info again since |
213 |
#the web protocol does not provide for continued connections. |
214 |
if ( (($i)/2) == int(($i)/2) ) { |
215 |
print "<tr>\n"; |
216 |
} else { |
217 |
print "<tr bgcolor=lightblue>\n"; |
218 |
} |
219 |
print "<FORM METHOD='POST' ACTION='".$CGI_PATH_NSWM."getmsg.pl' NAME='lire$i'>\n"; |
220 |
print "<INPUT TYPE='hidden' NAME='id' VALUE=$i >\n"; |
221 |
print "<INPUT TYPE='hidden' NAME='loginname' VALUE=$loginname >\n"; |
222 |
print "<INPUT TYPE='hidden' NAME='password' VALUE=$password >\n"; |
223 |
print "<INPUT TYPE='hidden' NAME='POPserver' VALUE=$POPserver >\n"; |
224 |
print "<INPUT TYPE='hidden' NAME='cache' VALUE=$cache >\n"; |
225 |
print "</FORM>\n"; |
226 |
|
227 |
|
228 |
$sub = ''; |
229 |
$from = ''; |
230 |
$to = ''; |
231 |
$date = ''; |
232 |
$replyto = ''; |
233 |
|
234 |
#obtain each header with the head() method in POP3Client. |
235 |
|
236 |
foreach ($pop->Head($i)){ |
237 |
#for each line within the message header retrieved, parse |
238 |
#the From,To,Date,Subject fields by finding |
239 |
#the appropriate strings at the beginning |
240 |
#of each line |
241 |
if (/^From:/ ){ |
242 |
$from = $'; #Get string following the succesful match. |
243 |
$from = DecodeQuoted($from); |
244 |
$from =~ s/</<\;/; #Strip out angled brackets to prevent browsers |
245 |
$from =~ s/>/>\;/; #from interpreting them as unknown HTML codes. |
246 |
} |
247 |
elsif (/^To:/) { |
248 |
$to = $'; |
249 |
} |
250 |
elsif (/^Subject:/) { |
251 |
$sub = $'; |
252 |
$sub = DecodeQuoted($sub); |
253 |
} |
254 |
elsif (/^Date:/) { |
255 |
$date = $'; |
256 |
} |
257 |
} |
258 |
$date=~ s/.*\,(.*)\+.*/$1/; |
259 |
$date="<small>$date</small>"; |
260 |
|
261 |
$size=$MessageSize[$i]; |
262 |
$size="<small>".int(($size+512)/1024)."k</small>"; |
263 |
|
264 |
print "<td><a href='.' OnClick='document.lire$i.submit();return false;'>$from </a></td><td><b>$sub </b></td><td>$date </td><td align=right>$size</td>"; |
265 |
|
266 |
#for each message header, also provide a FORM button to |
267 |
#delete using inbox.pl As above, pass in the needed vars |
268 |
#using hidden types. |
269 |
print "<td><FORM METHOD='POST' ACTION='".$CGI_PATH_NSWM."inbox.pl' >\n"; |
270 |
print "<INPUT TYPE='hidden' NAME='loginname' VALUE=$loginname >\n"; |
271 |
print "<INPUT TYPE='hidden' NAME='password' VALUE=$password >\n"; |
272 |
print "<INPUT TYPE='hidden' NAME='POPserver' VALUE=$POPserver >\n"; |
273 |
print "<INPUT TYPE='hidden' NAME='deleteMsg' VALUE=$i >\n"; |
274 |
print "<INPUT TYPE='hidden' NAME='cache' VALUE=$cache >\n"; |
275 |
print "<INPUT TYPE='submit' VALUE='$deletetext' OnClick=\"return confirm('$deleteconfirmtext');\">\n"; |
276 |
print "</td></FORM></tr>\n"; |
277 |
} |
278 |
} |
279 |
|
280 |
############################################################################### |
281 |
sub ReadParse { |
282 |
local(*in)=@_ if @_; |
283 |
local ($i,$key,$val); |
284 |
|
285 |
if ($ENV{'REQUEST_METHOD'} eq "GET") { |
286 |
$in=$ENV{'QUERY_STRING'}; |
287 |
} |
288 |
elsif ($ENV{'REQUEST_METHOD'} eq "POST") { |
289 |
read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); |
290 |
} |
291 |
|
292 |
@in=split(/&/,$in); |
293 |
|
294 |
foreach $i (0 .. $#in) { |
295 |
$in[$i] =~ s/\+/ /g; |
296 |
($key,$val)=split(/=/,$in[$i],2); |
297 |
$key =~ s/%(..)/pack("c",hex($1))/ge; |
298 |
$val =~ s/%(..)/pack("c",hex($1))/ge; |
299 |
$in{$key} .= "\0" if (defined($in{$key})); |
300 |
$in{$key} .=$val; |
301 |
} |
302 |
return length($in); |
303 |
} |