?? 列表9.2.txt
字號:
【列表9.2】 CheckMailStuff 的程序代碼。
unit checkmailstuff;
interface
uses
SysUtils, Libc;
type
CountType= (MSG_COUNT, MSG_NOCOUNT);
function CheckNewMail(logName: String; opType:CountType): Integer;
implementation
var
ma ilFile: String;
mailCount: Integer;
new_mailCount: Integer;
old_mailCount: Integer;
newMsgs: Integer;
oldMsgs: Integer;
lastMTime: Time_T;
lastSize: Off_T;
isInternal: boolean;
function isOld( buf: String ): boolean;
begin
Result := False;
if ( Pos( 'S', buf ) <> 1 ) and ( Pos( 'X', buf ) <> 1 )
then Exit;
// Now check for new status from normal mail clients ..
if Pos( 'Status:', buf ) = 1
then begin
if ( Pos( 'R', buf ) <> 0 ) or ( Pos( '0', buf ) <> 0 )
then begin
Result := True;
Exit;
end;
end;
// ...and check for new status from Netscape clients
if ( Pos( 'X-Mozilla-Status:', buf ) =1)
and ( Pos( '0000', buf ) = 19 )
then begin
Result := True;
Exit;
end;
end;
function isFrom( buf: String): boolean;
var
sender: String;
dayNum: Integer;
function GetWord(s : String; idx : Integer) : String;
var
i : Integer;
s1 : String;
w : String;
begin
s1 := s;
W := '';
for i := 1 to idx do
begin
while (Length(s1) > 0) and (s1[1] in [' ', ^I]) do
Delete(s1, 1, 1);
while (Length(s1) > 0) and not (s1[1] in [' ', ^I]) do
begin
if i = idx then w := w + s1[1];
Delete(s1, 1, 1);
end; { while }
end; { for }
Result := w;
end;
function ForceIntConversion(s : String) : Integer;
var
i : Integer;
begin
if Length(s) > 0
then begin
try
i := StrToInt(s);
except
i := 0;
end; { try } ,
end
else i := 0;
Result := i;
end;
begin
sender := '';
Result := False;
// If the first 5 chars of the string are
// not "From ", return false.
if Pos( 'From ', buf ) <> 1 then Exit;
// See if the sending address is missing, by looking
// for the day of the month in field 4 or 5.
dayNum := ForceIntConversion(GetWord(buf, 4)
if dayNum = 0
then begin
sender := GetWord(buf, 2);
dayNum := ForceIntConversion(GetWord(buf, 5));
if (Length(sender) = 0) or (dayNum =0)
then Exit;
end;
if dayNum > 31 then Exit;
// Needed for an "is_Internal" check outsidethis function.
// THIS IS A SIDE EFFECT.
if strcmp( PChar( sender), 'MAILER-DAEMON' ) =0
then isInternal := True;
Result := True;
end;
function isMultipartMsg( buf: String;
var sepLine: String ): boolean;
var
idxField: Integer;
idxSep: Integer;
lenSep: Integer;
begin
Result := false;
// If the string doesn't start with 'Content-Type: ' return Fa
if Pos( 'Content-Type: '. buf ) <> i then Exit;
if Pos( 'multipart/', Copy( buf, 15, 10 ) ) <> 1 then Exit;
// Starting at the 15th character...
idxField := 15;
// ...loop to the end of the string.
while idxField <= Length( buf ) do
begin
// find the next ';' character
while ( idxField <= Length( buf ) )
and (Copy( buf, idxField, 1) <> ';' ) do Inc( idxField );
if Copy( buf, idxField,1) = ';' then Inc( idxField );
// Now find the next non-space character
while ( idxField <= Length( buf ))
and (Copy( buf, idxField, 1 ) = ' ' ) do Inc( idxField);
// If where we are right now says 'boundary='
if Copy( buf. idxField, 9 ) = 'boundary=' then
begin
idxSep := idxField + 9;
if Copy( buf, idxSep, 1 ) = '"' then
begin
Inc( idxSep );
lenSep :=0;
// Count the number of chars between '"' chars
while ( Copy( buf, idxSep + lenSep, 1 ) <> '"' )
and ( Copy( buf, idxSep + lenSep, 1 ) >= ' ' )
do Inc( lenSep );
end
else
begin
lenSep := 0;
// Count the number of chars until a ';' char
while ( Copy( buf, idxSep + lenSep, 1 ) <> ';'
and ( Copy( buf, idxSep + lenSep, 1 ) >- ' ' )
do Inc( lenSep );
end;
// copy the separator string into the supplied buffer
sepLine := '--';
sepLine := sepLine + Copy( buf, idxSep, lenSep );
sepLine := sepLine +'--'
Result := True;
end;
end;
end;
function CheckNewMail(logName: String;opType: CountType): Integer;
var
F: TextFile;
statBuf: TStatBuf;
timeBuf: TUTimeBuffer;
line: String;
sepStr: String;
inHeader: boolean;
markedRead: boolean;
isMultipart: boolean;
begin
inHeader := False;
markedRead := False;
isMultipart := False;
timeBuf.actime := 0;
timeBuf.modtime := 0;
// 第一步,我們郵件的名字是什么?
mailFile := _PATH_MAILDIR + '/' + logName;
// stat the file into the statbuf. If we fail,the file isn't
// accessible and we automatically return a -l(error)
if stat(PChar(mailFile), statbuf ) <> 0
then begin
mailCount:= 0;
newMsgs := 0;
oldMsgs := 0;
Result := -1;
Exit;
end;
// If we're running in "no-count" mode then we'll report new mail
// based on the mailbox file's modification time and size.
if opType = MSG_NOCOUNT
then begin
if ( statbuf.st_size > 0 )
and ( statbuf.st_size >= lastSize )
and ( statbuf.st_mtime >= statbuf.st_atime )
then new_mailCount := 1
else new_mailCount := 0;
// We're not counting, so simply use the fields as a
// boolean value (that is, either there's mail there,
// or there isn't).
if statbuf.st_size > 0
then mailCount := 1
else mailCount := 0;
old_mailCount :=0;
// Keep track of the size and modification time of the file.
lastSize := statBuf.st_size;
lastMTime := statBuf.st_mtime;
// If there's new mail, return 1. Otherwise, return 0.
if new_mailCount <> 0
then begin
Result := 1;
Exit;
end
else begin
Result := 0;
Exit;
end;
end;
// We're running in "count" mode.
// If the mailboxes have been modified since last check,
// count the new/total messages.
if ( statBuf.st_mtime <> lastMTime )
or ( statBuf.st_size <> lastSize )
then begin
// Open the mail file for reading. If we can't,
// return -1 (error).
{$I-}
AssignFile( F, mailFile );
Reset( F );
if IOResult <> 0
then begin
{$I+}
Result := -1;
Exit;
end;
mailCount := 0;
old_mailCount := 0;
// Read a line from the file, and loop on whether or not
// it is available. When we run out of lineS we're done.
while not EOF( F ) do
begin
Readln( F, line );
// If is_multipart is true, AND in_header is false
if isMultipart and not inHeader
then begin
// Skip to last line of multipart mail
if Pos( sepStr, line ) = 1
then isMultipart := False;
end
// Else if the line is empty (first char is a newline)
else begin
if Length( line ) = 0
then begin
inHeader := False;
isInternal := False;
end
// Else if we're on a From: line (see function above)
else begin
if isFrom( line )
then begin
Inc( mailCount );
inHeader := True;
markedRead := False;
end
// Else if inHeader is true AND status_is_old (see above)
// returns true AND markedRead is false
else begin
if ( inHeader and isOld( line )and not markedRead)
then begin
Inc( old_mailCount );
markedRead := True;
end
// Else if in_header is true AND mailstats.is_internal
// is true
else begin
if inHeader and isInternal
then begin
if Pos( 'From: Mail System Internal Data',
line ) = 1
then begin
inHeader := False;
Dec( mailCount );
isInternal := False;
end;
end
// Else if in_header is true AND this is a
// multipart mail message
else if inHeader
and isMultipartMsg( line, sepStr )
then isMultipart := True;
end;
end;
end;
end; { If line is empty }
end; { while }
// Close the file we're done with it.
CloseFile( F );
{$I+}
// Restore the mailfile stat time so that other mail
// checking programs will function correctly.
timeBuf.actime := statBuf.st_atime;
timeBuf.modtime := statBuf.st_mtime;
utime(PChar(mailFile), @timeBuf );
// Keep track of things for next time
lastMtime := statBuf.st_mtime;
lastSize := statBuf.st_size;
// Compute the number of new messages
new_mailCount := mailCount - old_mailCount;
end; ( if statBuf.st_mtime <> stats.lastMTime }
Result := new_mailCount;
end;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -