readmbox.cc
00001 /* 00002 * This is a simple kioslave to handle mbox-files. 00003 * Copyright (C) 2004 Mart Kelder (mart.kde@hccnet.nl) 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 #include <config.h> 00020 00021 #include "readmbox.h" 00022 00023 #include "mbox.h" 00024 #include "urlinfo.h" 00025 00026 #include <kdebug.h> 00027 #include <kio/global.h> 00028 00029 #include <tqfile.h> 00030 #include <tqfileinfo.h> 00031 #include <tqstring.h> 00032 #include <tqtextstream.h> 00033 00034 #ifdef HAVE_SYS_TYPES_H 00035 #include <sys/types.h> 00036 #endif 00037 00038 #include <utime.h> 00039 00040 ReadMBox::ReadMBox( const UrlInfo* info, MBoxProtocol* parent, bool onlynew, bool savetime ) 00041 : MBoxFile( info, parent ), 00042 m_file( 0 ), 00043 m_stream( 0 ), 00044 m_current_line( new TQString( TQString() ) ), 00045 m_current_id( new TQString( TQString() ) ), 00046 m_atend( true ), 00047 m_prev_time( 0 ), 00048 m_only_new( onlynew ), 00049 m_savetime( savetime ), 00050 m_status( false ), 00051 m_prev_status( false ), 00052 m_header( true ) 00053 00054 { 00055 if( m_info->type() == UrlInfo::invalid ) 00056 m_mbox->emitError( KIO::ERR_DOES_NOT_EXIST, info->url() ); 00057 00058 if( !open( savetime ) ) 00059 m_mbox->emitError( KIO::ERR_CANNOT_OPEN_FOR_READING, info->url() ); 00060 00061 if( m_info->type() == UrlInfo::message ) 00062 if( !searchMessage( m_info->id() ) ) 00063 m_mbox->emitError( KIO::ERR_DOES_NOT_EXIST, info->url() ); 00064 } 00065 00066 ReadMBox::~ReadMBox() 00067 { 00068 delete m_current_line; 00069 close(); 00070 } 00071 00072 TQString ReadMBox::currentLine() const 00073 { 00074 return *m_current_line; 00075 } 00076 00077 TQString ReadMBox::currentID() const 00078 { 00079 return *m_current_id; 00080 } 00081 00082 bool ReadMBox::nextLine() 00083 { 00084 if( !m_stream ) 00085 return true; 00086 00087 *m_current_line = m_stream->readLine(); 00088 m_atend = m_current_line->isNull(); 00089 if( m_atend ) // Cursor was at EOF 00090 { 00091 *m_current_id = TQString(); 00092 m_prev_status = m_status; 00093 return true; 00094 } 00095 00096 //New message 00097 if( m_current_line->left( 5 ) == "From " ) 00098 { 00099 *m_current_id = *m_current_line; 00100 m_prev_status = m_status; 00101 m_status = true; 00102 m_header = true; 00103 return true; 00104 } else if( m_only_new ) 00105 { 00106 if( m_header && m_current_line->left( 7 ) == "Status:" && 00107 ! m_current_line->contains( "U" ) && ! m_current_line->contains( "N" ) ) 00108 { 00109 m_status = false; 00110 } 00111 } 00112 00113 if( m_current_line->stripWhiteSpace().isEmpty() ) 00114 m_header = false; 00115 00116 return false; 00117 } 00118 00119 bool ReadMBox::searchMessage( const TQString& id ) 00120 { 00121 if( !m_stream ) 00122 return false; 00123 00124 while( !m_atend && *m_current_id != id ) 00125 nextLine(); 00126 00127 return *m_current_id == id; 00128 } 00129 00130 unsigned int ReadMBox::skipMessage() 00131 { 00132 unsigned int result = m_current_line->length(); 00133 00134 if( !m_stream ) 00135 return 0; 00136 00137 while( !nextLine() ) 00138 result += m_current_line->length(); 00139 00140 return result; 00141 } 00142 00143 void ReadMBox::rewind() 00144 { 00145 if( !m_stream ) 00146 return; //Rewinding not possible 00147 00148 m_stream->device()->reset(); 00149 m_atend = m_stream->atEnd(); 00150 } 00151 00152 bool ReadMBox::atEnd() const 00153 { 00154 if( !m_stream ) 00155 return true; 00156 00157 return m_atend || ( m_info->type() == UrlInfo::message && *m_current_id != m_info->id() ); 00158 } 00159 00160 bool ReadMBox::inListing() const 00161 { 00162 return !m_only_new || m_prev_status; 00163 } 00164 00165 bool ReadMBox::open( bool savetime ) 00166 { 00167 if( savetime ) 00168 { 00169 TQFileInfo info( m_info->filename() ); 00170 00171 m_prev_time = new utimbuf; 00172 m_prev_time->actime = info.lastRead().toTime_t(); 00173 m_prev_time->modtime = info.lastModified().toTime_t(); 00174 } 00175 00176 if( m_file ) 00177 return false; //File already open 00178 00179 m_file = new TQFile( m_info->filename() ); 00180 if( !m_file->open( IO_ReadOnly ) ) 00181 { 00182 delete m_file; 00183 m_file = 0; 00184 return false; 00185 } 00186 m_stream = new TQTextStream( m_file ); 00187 skipMessage(); 00188 00189 return true; 00190 } 00191 00192 void ReadMBox::close() 00193 { 00194 if( !m_stream ) 00195 return; 00196 00197 delete m_stream; m_stream = 0; 00198 m_file->close(); 00199 delete m_file; m_file = 0; 00200 00201 if( m_prev_time ) 00202 utime( TQFile::encodeName( m_info->filename() ), m_prev_time ); 00203 } 00204