Fawkes API  Fawkes Development Version
file.cpp
00001 
00002 /***************************************************************************
00003  *  file.cpp - file utils
00004  *
00005  *  Generated: Wed Aug 30 22:47:11 2006
00006  *  Copyright  2006  Tim Niemueller [www.niemueller.de]
00007  *             2007  Daniel Beck
00008  *
00009  ****************************************************************************/
00010 
00011 /*  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version. A runtime exception applies to
00015  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00016  *
00017  *  This program is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *  GNU Library General Public License for more details.
00021  *
00022  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00023  */
00024 
00025 
00026 #include <utils/system/file.h>
00027 #include <core/exceptions/system.h>
00028 
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <unistd.h>
00032 #include <fcntl.h>
00033 #include <string.h>
00034 #include <errno.h>
00035 #include <stdlib.h>
00036 #include <cstdio>
00037 
00038 namespace fawkes {
00039 
00040 /** @class UnableToOpenFileException file.h <utils/system/file.h>
00041  * Opening a file failed for some reason.
00042  * @ingroup Exceptions
00043  */
00044 /** Constructor
00045  * @param filename the name of the file which couldn't be opened
00046  * @param error the errno
00047  */
00048 UnableToOpenFileException::UnableToOpenFileException(const char *filename, int error)
00049   : Exception("Unable to open file", error)
00050 {
00051   append("File that could not be opened: %s", filename);
00052 }
00053 
00054 
00055 /** @class File file.h <utils/system/file.h>
00056  * File utility methods.
00057  * Allows for opening a file and provides utilities to check if a file exists
00058  * or whether it is a regular file (and not a symbolic link/directory).
00059  * @author Tim Niemueller
00060  * @author Daniel Beck
00061  */
00062 
00063 
00064 /** Constructor. 
00065  * Independent of the FileOpenMethod files are created with 
00066  * permissions 660
00067  * @param filename the filename
00068  * @param method the method determines what is done if a file with the
00069  * specified name already exists
00070  */
00071 File::File(const char *filename, FileOpenMethod method)
00072 {
00073   fd = -1;
00074 
00075   switch (method)
00076     {
00077     case OVERWRITE:
00078       fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
00079       fn = strdup(filename);
00080       break;
00081       
00082     case APPEND:
00083       fd = open(filename, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
00084       fn = strdup(filename);
00085       break;
00086       
00087     case ADD_SUFFIX:
00088       {
00089         char *filename_ext = strdup(filename);
00090         int index = 0;
00091         while (File::exists(filename_ext)) {
00092           free(filename_ext);
00093           if ( asprintf(&filename_ext, "%s.%d", filename, ++index) == -1 ) {
00094             throw OutOfMemoryException("Could not allocate filename string");
00095           }
00096    
00097         }
00098         fd = open(filename_ext, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
00099         fn = filename_ext;
00100       }
00101       break;
00102       
00103       default:
00104         printf("%s [line %d]: Unkown method.\n", __FILE__, __LINE__);
00105     }
00106 
00107   if (-1 == fd)
00108     {
00109       throw UnableToOpenFileException(filename, errno);
00110     }
00111   
00112   fp = fdopen(fd, "r+");
00113 }
00114 
00115 
00116 /** Destructor. */
00117 File::~File()
00118 {
00119   // this also closes the underlying file descritptor fd
00120   fclose(fp);
00121   free(fn);
00122 }
00123 
00124 
00125 /** Get access to the file stream.
00126  * @return a pointer to the file stream
00127  */
00128 FILE *
00129 File::stream() const
00130 {
00131   return fp;
00132 }
00133 
00134 /** Get the file's name.
00135  * @return a pointer to a char array where the filename is stored
00136  */
00137 const char *
00138 File::filename() const
00139 {
00140   return fn;
00141 }
00142 
00143 
00144 /** Check if a file exists.
00145  * @param filename the name of the file to check
00146  * @return true, if the file exists, false otherwise
00147  */
00148 bool
00149 File::exists(const char *filename)
00150 {
00151   return (access(filename, F_OK) == 0);
00152 }
00153 
00154 
00155 /** Check if a file is a regular file
00156  * @param filename the name of the file to check
00157  * @return true, if the given path points to a regular file, false otherwise
00158  */
00159 bool
00160 File::is_regular(const char *filename)
00161 {
00162   struct stat s;
00163 
00164   if ( stat(filename, &s) == 0 ) {
00165     return S_ISREG(s.st_mode);
00166   } else {
00167     return false;
00168   }
00169 }
00170 
00171 
00172 } // end namespace fawkes