kioslave/mbox
readmbox.cpp
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 "readmbox.h" 00020 #include "mbox.h" 00021 #include "urlinfo.h" 00022 00023 #include <kdebug.h> 00024 #include <kio/global.h> 00025 00026 #include <QDateTime> 00027 #include <QFile> 00028 #include <QFileInfo> 00029 #include <QString> 00030 #include <QTextStream> 00031 00032 #include <utime.h> 00033 00034 ReadMBox::ReadMBox( const UrlInfo* info, MBoxProtocol* parent, bool onlynew, bool savetime ) 00035 : MBoxFile( info, parent ), 00036 m_file( 0 ), 00037 m_stream( 0 ), 00038 m_atend( true ), 00039 m_prev_time( 0 ), 00040 m_only_new( onlynew ), 00041 m_savetime( savetime ), 00042 m_status( false ), 00043 m_prev_status( false ), 00044 m_header( true ) 00045 00046 { 00047 if( m_info->type() == UrlInfo::invalid ) 00048 m_mbox->emitError( KIO::ERR_DOES_NOT_EXIST, info->url() ); 00049 00050 if( !open( savetime ) ) 00051 m_mbox->emitError( KIO::ERR_CANNOT_OPEN_FOR_READING, info->url() ); 00052 00053 if( m_info->type() == UrlInfo::message ) 00054 if( !searchMessage( m_info->id() ) ) 00055 m_mbox->emitError( KIO::ERR_DOES_NOT_EXIST, info->url() ); 00056 } 00057 00058 ReadMBox::~ReadMBox() 00059 { 00060 close(); 00061 } 00062 00063 QString ReadMBox::currentLine() const 00064 { 00065 return m_current_line; 00066 } 00067 00068 QString ReadMBox::currentID() const 00069 { 00070 return m_current_id; 00071 } 00072 00073 bool ReadMBox::nextLine() 00074 { 00075 if( !m_stream ) 00076 return true; 00077 00078 m_current_line = m_stream->readLine(); 00079 m_atend = m_current_line.isNull(); 00080 if( m_atend ) // Cursor was at EOF 00081 { 00082 m_current_id.clear(); 00083 m_prev_status = m_status; 00084 return true; 00085 } 00086 00087 //New message 00088 if( m_current_line.left( 5 ) == "From " ) 00089 { 00090 m_current_id = m_current_line; 00091 m_prev_status = m_status; 00092 m_status = true; 00093 m_header = true; 00094 return true; 00095 } else if( m_only_new ) 00096 { 00097 if( m_header && m_current_line.left( 7 ) == "Status:" && 00098 ! m_current_line.contains( "U" ) && ! m_current_line.contains( "N" ) ) 00099 { 00100 m_status = false; 00101 } 00102 } 00103 00104 if( m_current_line.trimmed().isEmpty() ) 00105 m_header = false; 00106 00107 return false; 00108 } 00109 00110 bool ReadMBox::searchMessage( const QString& id ) 00111 { 00112 if( !m_stream ) 00113 return false; 00114 00115 while( !m_atend && m_current_id != id ) 00116 nextLine(); 00117 00118 return m_current_id == id; 00119 } 00120 00121 unsigned int ReadMBox::skipMessage() 00122 { 00123 unsigned int result = m_current_line.length(); 00124 00125 if( !m_stream ) 00126 return 0; 00127 00128 while( !nextLine() ) 00129 result += m_current_line.length(); 00130 00131 return result; 00132 } 00133 00134 void ReadMBox::rewind() 00135 { 00136 if( !m_stream ) 00137 return; 00138 00139 m_stream->device()->reset(); 00140 m_atend = m_stream->atEnd(); 00141 } 00142 00143 bool ReadMBox::atEnd() const 00144 { 00145 if( !m_stream ) 00146 return true; 00147 00148 return m_atend || ( m_info->type() == UrlInfo::message && m_current_id != m_info->id() ); 00149 } 00150 00151 bool ReadMBox::inListing() const 00152 { 00153 return !m_only_new || m_prev_status; 00154 } 00155 00156 bool ReadMBox::open( bool savetime ) 00157 { 00158 if( savetime ) 00159 { 00160 QFileInfo info( m_info->filename() ); 00161 00162 m_prev_time = new utimbuf; 00163 m_prev_time->actime = info.lastRead().toTime_t(); 00164 m_prev_time->modtime = info.lastModified().toTime_t(); 00165 } 00166 00167 if( m_file ) 00168 return false; //File already open 00169 00170 m_file = new QFile( m_info->filename() ); 00171 if( !m_file->open( QIODevice::ReadOnly ) ) 00172 { 00173 delete m_file; 00174 m_file = 0; 00175 return false; 00176 } 00177 m_stream = new QTextStream( m_file ); 00178 skipMessage(); 00179 00180 return true; 00181 } 00182 00183 void ReadMBox::close() 00184 { 00185 if( !m_stream ) 00186 return; 00187 00188 delete m_stream; m_stream = 0; 00189 m_file->close(); 00190 delete m_file; m_file = 0; 00191 00192 if( m_prev_time ) 00193 { 00194 utime( QFile::encodeName( m_info->filename() ), m_prev_time ); 00195 delete m_prev_time; m_prev_time = 0; 00196 } 00197 } 00198