⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unixfolderc.c

📁 linux下的E_MAIL客户端源码
💻 C
字号:
/* * $Id: UnixFolderC.C,v 1.3 2000/08/07 11:05:17 evgeny Exp $ *   *  Copyright (c) 1994 HAL Computer Systems International, Ltd. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#include <config.h>#include "UnixFolderC.h"#include "UnixMsgC.h"#include "FileMisc.h"#include "HeaderC.h"#include "IshAppC.h"#include "MainWinC.h"#include "MsgItemC.h"#include "AddressC.h"#include "AppPrefC.h"#include "MsgListC.h"#include <hgl/CharC.h>#include <hgl/RegexC.h>#include <hgl/SysErr.h>#include <hgl/VBoxC.h>#include <hgl/ViewC.h>#include <Xm/Xm.h>#include <time.h>#include <unistd.h>RegexC  *UnixFolderC::fromPat = NULL;#define MAXLINE 255/*------------------------------------------------------------------------ * UnixFolderC constructor */UnixFolderC::UnixFolderC(const char *n, Boolean create): FileFolderC(n, UNIX_FOLDER, create){   if ( !fromPat ) {      char	*nonWhite = "\\([^ \t\n]+\\)";      char	*white    = "[ \t]+";      char	*alpha    = "[a-zA-Z]+";      char	*num      = "[0-9]+";      char	*time     = "[0-9][0-9]:[0-9][0-9]:?[0-9]?[0-9]?";      char	*etc      = ".*\n?";      StringC	pat = "From ";      pat += nonWhite;	// Address      pat += white;      pat += alpha;	// Weekday      pat += white;      pat += alpha;	// Month      pat += white;      pat += num;	// Daynum      pat += white;      pat += time;	// Time      pat += white;      pat += etc;	// [tz | offset] year [remote from addr]  -or-      			// year [tz | offset] [remote from addr]      fromPat = new RegexC(pat);   }   if ( !opened ) return;//// File should exist at this point.  Make sure it's a Unix folder.  It should//    start with a From line//   if ( stats.st_size > 0 ) {      if ( !OpenFile() ) return;      char	line[MAXLINE+1];      fgets(line, MAXLINE, fp);      if ( !fromPat->match(line) ) {	 StringC	errmsg = name;	 errmsg += " is not a Unix-format mail folder.\n";	 errmsg += "A Unix folder begins with a line starting with \"From \".";	 halApp->PopupMessage(errmsg);	 opened = False;	 return;      }      CloseFile();   }} // End constructor/*------------------------------------------------------------------------ * UnixFolderC destructor */UnixFolderC::~UnixFolderC(){}/*------------------------------------------------------------------------ * Method to extract messages from file */BooleanUnixFolderC::Scan(){   time_t	timeIn = 0;   if ( debuglev > 0 ) {      cout <<"Entering UnixFolderC(" <<BaseName(name) <<")::Scan" <<endl;      timeIn = time(0);   }   Boolean	showCount = (ishApp->mainWin->IsShown() &&   			    !ishApp->mainWin->IsIconified());   if ( !OpenFile() ) return False;   fseek(fp, 0, SEEK_SET);   Boolean	haveIndex = OpenIndex();   Boolean	indexEOF  = False;   if ( haveIndex ) fseek(indexfp, 0, SEEK_SET);//// Read lines until we hit the first From line//   char		line[MAXLINE+1];   CharC	lineStr;   StringC	statusStr;   while ( fgets(line, MAXLINE, fp) ) {      lineStr = line;      if ( lineStr.StartsWith("From ") && fromPat->match(line) ) {//// Update progress message if necessary//	 if ( showCount /*&& (msgList->size() % 10) == 0*/ ) {	    statusStr = abbrev;	    statusStr += " - Scanning messages: ";	    statusStr += (int)msgList->size();	    ishApp->mainWin->Message(statusStr);	 }	 UnixMsgC *msg = new UnixMsgC(this, msgList->size()+1, 	 			      (u_int)ftell(fp), line);	 msgList->add(msg);//// If we have the index file, try to read the info for this message//         if ( haveIndex && !indexEOF ) {//// Try to read the index//	    msg->indexOffset = ftell(indexfp);	    if ( !msg->ReadIndex(indexfp) ) {	       if ( !feof(indexfp) )		  ftruncate(fileno(indexfp), msg->indexOffset);	       msg->indexOffset = -1;	       indexEOF = True;	    }	 } // End if we have an index//// If this is a partial message, process it//         if ( msg->IsPartial() ) AddPartial(msg);//// Move to the end of this message//	 fseek(fp, msg->BodyOffset()+msg->BodyBytes(), SEEK_SET);      } // End if we got a From line   } // End for each line in file//// Update progress message if necessary//   if ( showCount ) {      statusStr = abbrev;      statusStr += " - Scanning messages: ";      statusStr += (int)msgList->size();      ishApp->mainWin->Message(statusStr);   }   if ( haveIndex ) CloseIndex();   CloseFile();   scanned = True;   SetChanged(False);   if ( haveIndex ) UpdateIndex();   else		    ScanIndex();   UpdateIcon();   ishApp->mainWin->ClearMessage();   if ( debuglev > 0 ) {      time_t	timeOut = time(0);      cout <<"Leaving UnixFolderC(" <<BaseName(name) <<")::Scan after "	   <<(timeOut-timeIn) <<" seconds" <<endl;   }   return True;} // End Scan/*------------------------------------------------------------------------ * Method to extract new messages from file */BooleanUnixFolderC::ScanNew(){   time_t	timeIn = 0;   if ( debuglev > 0 ) {      cout <<"Entering UnixFolderC(" <<BaseName(name) <<")::ScanNew" <<endl;      timeIn = time(0);   }   if ( !OpenFile() ) return False;   char		line[MAXLINE+1];   CharC	lineStr;//// Seek to where we think the last Unix message should start.  There could//    also be external File messages in the folder.//   UnixMsgC	*lastMsg = NULL;   u_int	count = msgList->size();   int i=count-1; for (i=count-1; !lastMsg && i>=0; i--) {      MsgC	*msg = (*msgList)[i];      if ( msg->IsUnix() ) lastMsg = (UnixMsgC*)msg;   }   if ( lastMsg ) {      fseek(fp, lastMsg->HeadOffset(), SEEK_SET);//// Read a line and make sure it's the first header in the message//      Boolean	error = False;      if ( !fgets(line, MAXLINE, fp) ) {	 error = True;      }      else {	 HeaderC	*firstHead = lastMsg->Headers();	 if ( firstHead ) {	    lineStr = line;	    error = !lineStr.StartsWith(firstHead->key);	 }	 else {	    error = (strlen(line) > 1);	 }      }      if ( error ) {	 StringC	errmsg = "Mail folder ";	 errmsg += name;	 errmsg += " appears to be different than I think it should be.\n";	 errmsg += "I will now re-read it.";	 if ( !ishApp->sleeping )	    halApp->PopupMessage(errmsg, XmDIALOG_WARNING);	 CloseFile();	 Rescan();	 return True;      }   } // End if there is a last message      VBoxC&	vbox = ishApp->mainWin->MsgVBox();   MsgItemC	*firstNew = NULL;   MsgItemC	*lastNew  = NULL;//// Seek to where we think the first new message should start//   int	newPos = 0;   if ( lastMsg ) newPos = lastMsg->BodyOffset() + lastMsg->BodyBytes();   fseek(fp, newPos, SEEK_SET);//// Read lines until we hit the first From line//   while ( fgets(line, MAXLINE, fp) ) {      lineStr = line;      if ( lineStr.StartsWith("From ") && fromPat->match(line) ) {	 UnixMsgC *msg = new UnixMsgC(this, msgList->size()+1,	 			      (u_int)ftell(fp), line);	 msgList->add(msg);//// Create a message icon for this message//	 if ( active ) {	    msg->CreateIcon();	    InsertInThread(msg->icon);	    msgItemList->add(msg->icon);	    vbox.AddItem(*msg->icon);            if ( !firstNew ) firstNew = msg->icon;	    lastNew = msg->icon;	 } // End if folder is active//// If this is a partial message, process it//         if ( msg->IsPartial() ) AddPartial(msg);//// Reset to the end of the last message since the next From line was already//   read by the message.	 fseek(fp, msg->BodyOffset()+msg->BodyBytes(), SEEK_SET);      } // End if start of new message   } // End for each new line   CloseFile();   scanned = True;   if ( active ) {//// Scroll to the last then the first to display as many new messages//    as possible//      if ( lastNew && ishApp->appPrefs->scrollToNew ) {	 vbox.View()->ScrollToItem(*lastNew);	 vbox.View()->ScrollToItem(*firstNew);      }      vbox.Refresh();   }   UpdateIndex();   if ( debuglev > 0 ) {      time_t	timeOut = time(0);      cout <<"Leaving UnixFolderC(" <<BaseName(name) <<")::ScanNew after "	   <<(timeOut-timeIn) <<" seconds" <<endl;   }   return True;} // End ScanNew/*------------------------------------------------------------------------ * Function to build a From line for a message */static voidGetFromLine(MsgC *msg, StringC& fromLine){   fromLine = "From ";   AddressC	*from = msg->From();   if ( from ) fromLine += from->addr;   else	       fromLine += "unknown";   fromLine += ' ';   time_t	epochTime = msg->Time();   fromLine += (char*)ctime(&epochTime);   if ( fromLine.EndsWith('\n') ) fromLine.CutEnd(1);} // End GetFromLine/*------------------------------------------------------------------------ * Method to write a message to this open folder */BooleanUnixFolderC::WriteMessage(MsgC *msg, FILE *fp){#if 0//// Before we start, see if the index is valid//   Boolean	indexValid = IndexValid();   u_int	msgOff     = (u_int)ftell(fp);#endif   StringC	fromLine;   if ( msg->type == UNIX_MSG ) fromLine = ((UnixMsgC*)msg)->fromLine;   else				GetFromLine(msg, fromLine);   if ( !fromLine.WriteFile(fp) ) return False;   CharC	nl("\n");   if ( !nl.WriteFile(fp)       ) return False;   msg->headWritePos = ftell(fp);   if ( !msg->WriteHeaders(fp)  ) return False;   msg->bodyWritePos = ftell(fp);   if ( !msg->WriteBody(fp, True/*add blank*/, True/*protect Froms*/) )      return False;#if 0//// If the index is valid, add an entry//   if ( indexValid ) {      long	indexOff = AddIndexEntry(msg->status, msg->BodyBytes(),      					 msg->BodyLines(), msg->Id());//// Display the new message//      if ( scanned ) {	 UnixMsgC	*newMsg = new UnixMsgC(this, msgList->size()+1, msgOff,	 				       fromLine, indexOff);	 msgList->add(newMsg);//// Create a message icon for this message//	 if ( active ) {	    newMsg->CreateIcon();	    InsertInThread(newMsg->icon);	    msgItemList->add(newMsg->icon);	    ishApp->mainWin->MsgVBox().AddItem(*newMsg->icon);	 } // End if folder is active//// If this is a partial message, process it//         if ( newMsg->IsPartial() ) AddPartial(newMsg);      } // End if folder has been scanned   } // End if the index file is good   else if ( scanned )      ScanNew();#endif   return True;} // End WriteMessage/*------------------------------------------------------------------------ * Method to write a message to this open folder */BooleanUnixFolderC::WriteMessage(StringListC& headList, char *bodyFile, FILE *fp){//// Write "From " line//   StringC	fromStr = "From ";   fromStr += ishApp->userAtHost;   fromStr += " ";   time_t	now = time(0);   fromStr += ctime(&now);   if ( !fromStr.WriteFile(fp) ) return False;   if ( !WriteHeaders(headList, name, /*addBlank=*/True, fp) )      return False;   if ( !CopyFile(bodyFile, name, True/*add blank*/, True/*protect Froms*/,      		  NULL, fp) )      return False;   return True;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -