• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

crypt/file.cc

Go to the documentation of this file.
00001 // $Id: file.cc 3351 2010-09-17 21:55:30Z java $
00002 //
00003 // Copyright (C) 2008-2010  Rafael Ostertag
00004 //
00005 // This file is part of YAPET.
00006 //
00007 // YAPET is free software: you can redistribute it and/or modify it under the
00008 // terms of the GNU General Public License as published by the Free Software
00009 // Foundation, either version 3 of the License, or (at your option) any later
00010 // version.
00011 //
00012 // YAPET is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00015 // details.
00016 //
00017 // You should have received a copy of the GNU General Public License along with
00018 // YAPET.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00020 // Additional permission under GNU GPL version 3 section 7
00021 //
00022 // If you modify this program, or any covered work, by linking or combining it
00023 // with the OpenSSL project's OpenSSL library (or a modified version of that
00024 // library), containing parts covered by the terms of the OpenSSL or SSLeay
00025 // licenses, Rafael Ostertag grants you additional permission to convey the
00026 // resulting work.  Corresponding Source for a non-source form of such a
00027 // combination shall include the source code for the parts of OpenSSL used as
00028 // well as that of the covered work.
00029 //
00030 
00031 #include "../intl.h"
00032 #include "crypt.h"
00033 #include "record.h"
00034 #include "structs.h"
00035 #include "file.h"
00036 
00037 #ifdef TIME_WITH_SYS_TIME
00038 # include <sys/time.h>
00039 # include <time.h>
00040 #else
00041 # ifdef HAVE_SYS_TIME_H
00042 #  include <sys/time.h>
00043 # else
00044 #  include <time.h>
00045 # endif
00046 #endif // TIME_WITH_SYS_TIME
00047 
00048 #ifdef HAVE_INTTYPES_H
00049 # include <inttypes.h>
00050 #endif
00051 
00052 #ifdef HAVE_SYS_TYPES_H
00053 # include <sys/types.h>
00054 #endif
00055 
00056 #ifdef HAVE_SYS_STAT_H
00057 # include <sys/stat.h>
00058 #endif
00059 
00060 #ifdef HAVE_FCNTL_H
00061 # include <fcntl.h>
00062 #endif
00063 
00064 #ifdef HAVE_STRING_H
00065 # include <string.h>
00066 #endif
00067 
00068 #ifdef HAVE_ERRNO_H
00069 # include <errno.h>
00070 #endif
00071 
00072 #ifdef HAVE_UNISTD_H
00073 # include <unistd.h>
00074 #endif
00075 
00076 #ifdef HAVE_ALLOCA_H
00077 # include <alloca.h>
00078 #endif
00079 
00080 using namespace YAPET;
00081 
00091 const char CONTROL_STR[] = "ABCDEFGHIJKLMNOPQRSTUVW";
00092 
00101 const char RECOG_STR[] = "YAPET1.0";
00102 
00110 void
00111 File::checkFileSecurity() throw (YAPETException) {
00112 #if defined(HAVE_FSTAT) && defined(HAVE_GETUID)
00113     struct stat buf;
00114     int err = fstat (fd, &buf);
00115 
00116     if (err == -1)
00117         throw YAPETException (strerror (errno) );
00118 
00119     uid_t uid = getuid();
00120 
00121     if (buf.st_uid != uid) {
00122         std::string tmp (_ ("You are not the owner of ") );
00123         throw YAPETRetryException (tmp + filename);
00124     }
00125 
00126     if (buf.st_mode != (S_IFREG | S_IRUSR | S_IWUSR) ) {
00127         std::string tmp1 (_ ("Permissions of ") );
00128         std::string tmp2 (_ (" not secure.") );
00129         throw YAPETRetryException (tmp1 + filename + tmp2);
00130     }
00131 
00132 #endif
00133 }
00134 
00142 void
00143 File::setFileSecurity() throw (YAPETException) {
00144 #if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD) && defined(HAVE_FSTAT)
00145     struct stat buf;
00146     int err = fstat (fd, &buf);
00147 
00148     if (err == -1)
00149         throw YAPETException (strerror (errno) );
00150 
00151     err = fchown (fd, getuid(), buf.st_gid);
00152 
00153     if (err == -1) {
00154         std::string tmp (_ ("Cannot set the owner of ") );
00155         throw YAPETRetryException (tmp + filename);
00156     }
00157 
00158     err = fchmod (fd, S_IRUSR | S_IWUSR);
00159 
00160     if (err == -1) {
00161         std::string tmp (_ ("Cannot set file permissions on ") );
00162         throw YAPETRetryException (tmp + filename);
00163     }
00164 
00165 #endif
00166 }
00167 
00168 
00174 void
00175 File::openCreate() throw (YAPETException) {
00176     fd = ::open (filename.c_str(),
00177                  O_RDWR | O_CREAT | O_TRUNC | O_APPEND,
00178                  (usefsecurity ? S_IRUSR | S_IWUSR :
00179                   S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH ) );
00180 
00181     if (fd == -1)
00182         throw YAPETException (strerror (errno) );
00183 
00184     if (usefsecurity)
00185         checkFileSecurity();
00186 }
00187 
00192 void
00193 File::openNoCreate() throw (YAPETException) {
00194     fd = ::open (filename.c_str(), O_RDWR | O_APPEND);
00195 
00196     if (fd == -1)
00197         throw YAPETException (strerror (errno) );
00198 
00199     if (usefsecurity)
00200         checkFileSecurity();
00201 }
00202 
00209 int64_t
00210 File::lastModified() const throw (YAPETException) {
00211     struct stat st_buf;
00212     int retval = fstat (fd, &st_buf);
00213 
00214     if (retval == -1)
00215         throw YAPETException (strerror (errno) );
00216 
00217     return st_buf.st_mtime;
00218 }
00219 
00227 void
00228 File::seekCurr (off_t offset) const throw (YAPETException) {
00229     off_t pos = lseek (fd, offset, SEEK_CUR);
00230 
00231     if ( ( (off_t) - 1) == pos)
00232         throw YAPETException (strerror (errno) );
00233 }
00234 
00240 void
00241 File::seekAbs (off_t offset) const throw (YAPETException) {
00242     off_t pos = lseek (fd, offset, SEEK_SET);
00243 
00244     if ( ( (off_t) - 1) == pos)
00245         throw YAPETException (strerror (errno) );
00246 
00247     if (pos != offset)
00248         throw YAPETException (_ ("Error seeking within file: ") + filename);
00249 }
00250 
00256 void
00257 File::preparePWSave() throw (YAPETException) {
00258     BDBuffer* curr_header = readHeader();
00259     ::close (fd);
00260 
00261     try {
00262         openCreate();
00263     } catch (YAPETException& ex) {
00264         if (curr_header != NULL)
00265             delete curr_header;
00266 
00267         throw;
00268     }
00269 
00270     mtime = lastModified();
00271     writeHeader (*curr_header);
00272     delete curr_header;
00273 }
00274 
00280 void
00281 File::seekDataSection() const throw (YAPETException) {
00282     seekAbs (strlen (RECOG_STR) );
00283     uint32_t len;
00284     int retval = ::read (fd, &len, sizeof (uint32_t) );
00285 
00286     if (retval == -1)
00287         throw YAPETException (strerror (errno) );
00288 
00289     if ( ( (size_t) retval) != sizeof (uint32_t) )
00290         throw YAPETException (_ ("Unable to seek to data section") );
00291 
00292     len = int_from_disk<uint32_t> (len);
00293     seekCurr (len);
00294 }
00295 
00313 BDBuffer*
00314 File::read() const throw (YAPETException) {
00315     uint32_t len;
00316     int retval = ::read (fd, &len, sizeof (uint32_t) );
00317 
00318     if (retval == -1)
00319         throw YAPETException (strerror (errno) );
00320 
00321     if (retval == 0)
00322         return NULL;
00323 
00324     if ( ( (size_t) retval) < sizeof (uint32_t) )
00325         throw YAPETException (_ ("Short read on file: ") + filename);
00326 
00327     // Convert len to the endianess of the architecture
00328     len = int_from_disk<uint32_t> (len);
00329     BDBuffer* buf = new BDBuffer (len);
00330     retval = ::read (fd, *buf, len);
00331 
00332     if (retval == -1)
00333         throw YAPETException (strerror (errno) );
00334 
00335     if (retval == 0) {
00336         delete buf;
00337         return NULL;
00338     }
00339 
00340     if ( ( (uint32_t) retval) < len) {
00341         delete buf;
00342         throw YAPETException (_ ("Short read on file: ") + filename);
00343     }
00344 
00345     return buf;
00346 }
00347 
00370 void
00371 File::write (const BDBuffer& buff, bool forceappend, bool forcewrite)
00372 throw (YAPETException, YAPETRetryException) {
00373     if ( (mtime != lastModified() ) && !forcewrite)
00374         throw YAPETRetryException (_ ("File has been modified") );
00375 
00376     if (forceappend) {
00377         off_t pos = lseek (fd, 0, SEEK_END);
00378 
00379         if ( ( (off_t) - 1) == pos)
00380             throw YAPETException (strerror (errno) );
00381     }
00382 
00383     uint32_t s = buff.size();
00384     // Convert s to the on-disk structure
00385     s = int_to_disk<uint32_t> (s);
00386     int retval = ::write (fd, &s, sizeof (uint32_t) );
00387 
00388     if (retval == -1)
00389         throw YAPETException (strerror (errno) );
00390 
00391     if (retval != sizeof (uint32_t) )
00392         throw YAPETException (_ ("Short write on file: ") + filename);
00393 
00394     retval = ::write (fd, buff, buff.size() );
00395 
00396     if (retval == -1)
00397         throw YAPETException (strerror (errno) );
00398 
00399     if ( ( (size_t) retval) < buff.size() )
00400         throw YAPETException (_ ("Short write on file: ") + filename);
00401 
00402     mtime = lastModified();
00403 }
00404 
00410 bool
00411 File::isempty() const throw (YAPETException) {
00412     struct stat st_buf;
00413     int retval = fstat (fd, &st_buf);
00414 
00415     if (retval == -1)
00416         throw YAPETException (strerror (errno) );
00417 
00418     if (st_buf.st_size == 0)
00419         return true;
00420 
00421     return false;
00422 }
00423 
00432 void
00433 File::initFile (const Key& key) throw (YAPETException) {
00434     Crypt crypt (key);
00435     Record<FileHeader_64> header;
00436     FileHeader_64* ptr = header;
00437     ptr->version = VERSION_2;
00438     memcpy (ptr->control, CONTROL_STR, HEADER_CONTROL_SIZE);
00439     ptr->pwset = int_to_disk<int64_t> (time (NULL) );
00440     mtime = lastModified();
00441     writeHeader (header, key);
00442     // Sanity checks
00443     BDBuffer* buff = readHeader();
00444 
00445     if (buff == NULL)
00446         throw YAPETException (_ ("EOF encountered while reading header") );
00447 
00448     Record<FileHeader_64>* dec_hdr = crypt.decrypt<FileHeader_64> (*buff);
00449     FileHeader_64* ptr_dec_hdr = *dec_hdr;
00450     int retval = memcmp (ptr_dec_hdr->control, ptr->control, HEADER_CONTROL_SIZE);
00451 
00452     if (retval != 0)
00453         throw YAPETException (_ ("Sanity check for control field failed") );
00454 
00455     delete buff;
00456     delete dec_hdr;
00457 }
00458 
00471 void
00472 File::writeHeader (const Record<FileHeader_64>& header, const Key& key)
00473 throw (YAPETException) {
00474     Crypt crypt (key);
00475     BDBuffer* buff = NULL;
00476 
00477     try {
00478         buff = crypt.encrypt (header);
00479         writeHeader (*buff);
00480     } catch (YAPETException& ex) {
00481         if (buff != NULL)
00482             delete buff;
00483 
00484         throw;
00485     } catch (...) {
00486         if (buff != NULL)
00487             delete buff;
00488 
00489         throw YAPETException (_ ("Unknown exception catched") );
00490     }
00491 
00492     delete buff;
00493 }
00494 
00502 void
00503 File::writeHeader (const BDBuffer& enc_header) throw (YAPETException) {
00504     seekAbs (0);
00505     // Write the recognition string
00506     ssize_t retval = ::write (fd, RECOG_STR, strlen (RECOG_STR) );
00507 
00508     if (retval == -1)
00509         throw YAPETException (strerror (errno) );
00510 
00511     if ( ( (size_t) retval) != strlen (RECOG_STR) )
00512         throw YAPETException (_ ("Short write on file: ") + filename);
00513 
00514     mtime = lastModified();
00515     write (enc_header);
00516 }
00517 
00530 BDBuffer*
00531 File::readHeader() const throw (YAPETException) {
00532     seekAbs (0);
00533     char* buff = (char*) alloca (strlen (RECOG_STR) );
00534 
00535     if (buff == NULL)
00536         throw YAPETException (_ ("Memory exhausted") );
00537 
00538     int retval = ::read (fd, buff, strlen (RECOG_STR) );
00539 
00540     if (retval == -1)
00541         throw YAPETException (strerror (errno) );
00542 
00543     if ( ( (size_t) retval) != strlen (RECOG_STR) )
00544         throw YAPETException (_ ("File type not recognized") );
00545 
00546     retval = memcmp (RECOG_STR, buff, strlen (RECOG_STR) );
00547 
00548     if (retval != 0)
00549         throw YAPETException (_ ("File type not recognized") );
00550 
00551     return read();
00552 }
00553 
00581 void
00582 File::readHeader(const Key& key, Record<FileHeader_32>** ptr32, Record<FileHeader_64>** ptr64) const throw(YAPETException) {
00583     assert(ptr32 != NULL && ptr64 != NULL);
00584     if (ptr32 == NULL)
00585     throw YAPETException(_("Null pointer passed in ptr32"), NULLPOINTER);
00586     if (ptr64 == NULL)
00587     throw YAPETException(_("Null pointer passed in ptr64"), NULLPOINTER);
00588 
00589     Crypt crypt (key);
00590     BDBuffer* enc_header = NULL;
00591 
00592     try {
00593         enc_header = readHeader();
00594     // First try to read a 32bit header
00595     try {
00596         *ptr32 = crypt.decrypt<FileHeader_32> (*enc_header);
00597     } catch (YAPETException& ex) {
00598 
00599         if (*ptr32 != NULL) {
00600         delete *ptr32;
00601         *ptr32 = NULL;
00602         }
00603 
00604         try {
00605         *ptr64 = crypt.decrypt<FileHeader_64> (*enc_header);
00606         } catch (YAPETEncryptionException& ex) { // Catch invalid password
00607         if (enc_header != NULL) {
00608             delete enc_header;
00609             enc_header = NULL;
00610         }
00611         
00612         if (*ptr32 != NULL) {
00613             delete *ptr32;
00614             *ptr32 = NULL;
00615         }
00616         if (*ptr64 != NULL) {
00617             delete *ptr64;
00618             *ptr64 = NULL;
00619         }
00620         
00621         throw YAPETInvalidPasswordException();
00622         } catch (YAPETException &ex) {
00623         // Ok, we got another problem
00624         if (*ptr64 != NULL) {
00625             delete *ptr64;
00626             *ptr64 = NULL;
00627         }
00628         throw;
00629         }
00630     }
00631     } catch (YAPETEncryptionException& ex) { // Catch invalid password
00632         if (enc_header != NULL) delete enc_header;
00633 
00634         if (*ptr32 != NULL) {
00635         delete *ptr32;
00636         *ptr32 = NULL;
00637     }
00638     if (*ptr64 != NULL) {
00639         delete *ptr64;
00640         *ptr64 = NULL;
00641     }
00642 
00643         throw YAPETInvalidPasswordException();
00644     } catch (YAPETException& ex) {
00645         if (enc_header != NULL) delete enc_header;
00646 
00647         if (*ptr32 != NULL) {
00648         delete *ptr32;
00649         *ptr32 = NULL;
00650     }
00651     if (*ptr64 != NULL) {
00652         delete *ptr64;
00653         *ptr64 = NULL;
00654     }
00655 
00656         throw;
00657     }
00658 
00659     delete enc_header;
00660 }
00661 
00675 void
00676 File::validateKey (const Key& key)
00677 throw (YAPETException, YAPETInvalidPasswordException) {
00678     // Expect either a 32bit or 64bit header
00679     Record<FileHeader_32>* dec_header_32 = NULL;
00680     Record<FileHeader_64>* dec_header_64 = NULL;
00681 
00682     readHeader(key, &dec_header_32, &dec_header_64);
00683     assert(dec_header_32 != NULL || dec_header_64 != NULL);
00684 
00685     FileHeader_32* ptr_dec_header_32 = 
00686     (dec_header_32 != NULL) ? static_cast<FileHeader_32*>(*dec_header_32) : NULL;
00687     FileHeader_64* ptr_dec_header_64 = 
00688     (dec_header_64 != NULL) ? static_cast<FileHeader_64*>(*dec_header_64) : NULL;
00689 
00690     int retval;
00691     if (ptr_dec_header_32 != NULL) {
00692     retval = memcmp (ptr_dec_header_32->control,
00693                          CONTROL_STR,
00694                          HEADER_CONTROL_SIZE);
00695     } else {
00696     assert(ptr_dec_header_64 != NULL);
00697     retval = memcmp (ptr_dec_header_64->control,
00698                          CONTROL_STR,
00699                          HEADER_CONTROL_SIZE);
00700     }
00701     if (dec_header_32 != NULL)
00702     delete dec_header_32;
00703     if (dec_header_64 != NULL)
00704     delete dec_header_64;
00705 
00706     if (retval != 0)
00707         throw YAPETInvalidPasswordException();
00708 }
00709 
00739 File::File (const std::string& fn, const Key& key, bool create, bool secure)
00740 throw (YAPETException) : filename (fn), usefsecurity (secure) {
00741     if (create)
00742         openCreate();
00743     else
00744         openNoCreate();
00745 
00746     if (isempty() ) {
00747         initFile (key);
00748     } else {
00749         validateKey (key);
00750     }
00751 }
00752 
00756 File::File (const File& f) throw (YAPETException) {
00757     fd = dup (f.fd);
00758 
00759     if (fd == -1)
00760         throw YAPETException (strerror (errno) );
00761 
00762     filename = f.filename;
00763     mtime = f.mtime;
00764     usefsecurity = f.usefsecurity;
00765 }
00766 
00770 File::~File() {
00771     close (fd);
00772 }
00773 
00781 void
00782 File::save (std::list<PartDec>& records) throw (YAPETException) {
00783     if (usefsecurity)
00784         setFileSecurity();
00785 
00786     preparePWSave();
00787     std::list<PartDec>::iterator it = records.begin();
00788 
00789     while (it != records.end() ) {
00790         write ( it->getEncRecord() );
00791         it++;
00792     }
00793 }
00794 
00808 std::list<PartDec>
00809 File::read (const Key& key) const throw (YAPETException) {
00810     seekDataSection();
00811     BDBuffer* buff = NULL;
00812     std::list<PartDec> retval;
00813 
00814     try {
00815         buff = read();
00816 
00817         while (buff != NULL) {
00818             retval.push_back (PartDec (*buff, key) );
00819             delete buff;
00820             buff = read();
00821         }
00822     } catch (YAPETException& ex) {
00823         if (buff != NULL)
00824             delete buff;
00825 
00826         throw;
00827     }
00828 
00829     return retval;
00830 }
00831 
00846 void
00847 File::setNewKey (const Key& oldkey,
00848                  const Key& newkey) throw (YAPETException) {
00849     close (fd);
00850     std::string backupfilename (filename + ".bak");
00851     int retval = rename (filename.c_str(), backupfilename.c_str() );
00852 
00853     if (retval == -1) {
00854         // Reopen the old file
00855         openNoCreate();
00856         throw YAPETException (strerror (errno) );
00857     }
00858 
00859     File* oldfile = NULL;
00860 
00861     try {
00862         // Reopen the old (backup) file
00863         oldfile = new File (backupfilename, oldkey, false, false);
00864         // Initialize the (this) file with the new key
00865         openCreate();
00866         initFile (newkey);
00867         // Retrieve the records encrypted with the old key
00868         std::list<PartDec> entries = oldfile->read (oldkey);
00869         std::list<PartDec>::iterator it = entries.begin();
00870         Crypt oldcrypt (oldkey);
00871         Crypt newcrypt (newkey);
00872 
00873         while (it != entries.end() ) {
00874             Record<PasswordRecord>* dec_rec_ptr = NULL;
00875             BDBuffer* new_enc_rec = NULL;
00876 
00877             try {
00878                 // Decrypt with the old key
00879                 const BDBuffer old_enc_rec = (*it).getEncRecord();
00880                 dec_rec_ptr =
00881                     oldcrypt.decrypt<PasswordRecord> (old_enc_rec);
00882                 new_enc_rec =
00883                     newcrypt.encrypt (*dec_rec_ptr);
00884                 write (*new_enc_rec);
00885                 delete dec_rec_ptr;
00886                 delete new_enc_rec;
00887             } catch (YAPETException& ex) {
00888                 if (dec_rec_ptr != NULL)
00889                     delete dec_rec_ptr;
00890 
00891                 if (new_enc_rec != NULL)
00892                     delete new_enc_rec;
00893 
00894                 throw;
00895             }
00896 
00897             it++;
00898         }
00899     } catch (YAPETException& ex) {
00900         if (oldfile != NULL)
00901             delete oldfile;
00902 
00903         throw;
00904     }
00905 
00906     delete oldfile;
00907 }
00908 
00919 int64_t
00920 File::getMasterPWSet (const Key& key) const
00921 throw (YAPETException, YAPETInvalidPasswordException) {
00922     // Expect either a 32bit or 64bit header
00923     Record<FileHeader_32>* dec_header_32 = NULL;
00924     Record<FileHeader_64>* dec_header_64 = NULL;
00925 
00926     readHeader(key, &dec_header_32, &dec_header_64);
00927     assert(dec_header_32 != NULL || dec_header_64 != NULL);
00928 
00929     FileHeader_32* ptr_dec_header_32 = 
00930     (dec_header_32 != NULL) ? static_cast<FileHeader_32*>(*dec_header_32) : NULL;
00931     FileHeader_64* ptr_dec_header_64 = 
00932     (dec_header_64 != NULL) ? static_cast<FileHeader_64*>(*dec_header_64) : NULL;
00933 
00934     int64_t t;
00935     if (ptr_dec_header_32 != NULL) {
00936     t = int_from_disk<int32_t> (ptr_dec_header_32->pwset);
00937     } else {
00938     assert(ptr_dec_header_64 != NULL);
00939     t = int_from_disk<int64_t> (ptr_dec_header_64->pwset);
00940     }
00941 
00942     if (dec_header_32 != NULL)
00943     delete dec_header_32;
00944     if (dec_header_64 != NULL)
00945     delete dec_header_64;
00946 
00947     return t;
00948 }
00949 
00955 FILE_VERSION
00956 File::getFileVersion(const Key& key) const throw (YAPETException, YAPETInvalidPasswordException) {
00957     // Expect either a 32bit or 64bit header
00958     Record<FileHeader_32>* dec_header_32 = NULL;
00959     Record<FileHeader_64>* dec_header_64 = NULL;
00960 
00961     readHeader(key, &dec_header_32, &dec_header_64);
00962     assert(dec_header_32 != NULL || dec_header_64 != NULL);
00963 
00964     FileHeader_32* ptr_dec_header_32 = 
00965     (dec_header_32 != NULL) ? static_cast<FileHeader_32*>(*dec_header_32) : NULL;
00966     FileHeader_64* ptr_dec_header_64 = 
00967     (dec_header_64 != NULL) ? static_cast<FileHeader_64*>(*dec_header_64) : NULL;
00968 
00969     FILE_VERSION v;
00970     if (ptr_dec_header_32 != NULL) {
00971     v = static_cast<FILE_VERSION>(ptr_dec_header_32->version);
00972     } else {
00973     assert(ptr_dec_header_64 != NULL);
00974     v = static_cast<FILE_VERSION>(ptr_dec_header_64->version);
00975     }
00976 
00977     if (dec_header_32 != NULL)
00978     delete dec_header_32;
00979     if (dec_header_64 != NULL)
00980     delete dec_header_64;
00981 
00982     return v;
00983 }
00984 
00985 const File&
00986 File::operator= (const File & f) throw (YAPETException) {
00987     if (this == &f) return *this;
00988 
00989     close (fd);
00990     fd = dup (f.fd);
00991 
00992     if (fd == -1)
00993         throw YAPETException (strerror (errno) );
00994 
00995     filename = f.filename;
00996     return *this;
00997 }

Generated on Sun Sep 19 2010 15:37:13 for YAPET by  doxygen 1.7.1