kioslaves

readmbox.cc

Go to the documentation of this file.
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 <qfile.h>
00030 #include <qfileinfo.h>
00031 #include <qstring.h>
00032 #include <qtextstream.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 QString( QString::null ) ),
00045     m_current_id( new QString( QString::null ) ),
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 QString ReadMBox::currentLine() const
00073 {
00074     return *m_current_line;
00075 }
00076 
00077 QString 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 = QString::null;
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 QString& 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         QFileInfo 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 QFile( 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 QTextStream( 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( QFile::encodeName( m_info->filename() ), m_prev_time );
00203 }
00204