Vidalia  0.2.17
file.cpp
Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.torproject.org/projects/vidalia.html. No part of Vidalia, 
00007 **  including this file, may be copied, modified, propagated, or distributed 
00008 **  except according to the terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file file.cpp
00013 ** \brief Functions and definitions for common file I/O operations
00014 */
00015 
00016 #include "file.h"
00017 #include "stringutil.h"
00018 
00019 #if defined(Q_OS_WIN32)
00020 #include "win32.h"
00021 #endif
00022 
00023 #include <QDir>
00024 #include <QFile>
00025 
00026 
00027 /** Create an empty file named <b>filename</b>. if <b>createdir</b> is true,
00028  * then the full path to <b>filename</b> will be created. Returns true on 
00029  * success, or false on error and <b>errmsg</b> will be set. */
00030 bool
00031 touch_file(const QString &filename, bool createdir, QString *errmsg)
00032 {
00033   /* Expand the file's path if it starts with a shortcut, like "~/" or
00034    * "%APPDATA%" */
00035   QString expanded = expand_filename(filename);
00036     
00037   /* If the file's path doesn't exist and we're supposed to create it, do that
00038    * now. */
00039   if (createdir && !create_path(QFileInfo(expanded).absolutePath())) {
00040     return false;
00041   }
00042  
00043   /* Touch the file */
00044   QFile file(expanded);
00045   if (!QFileInfo(expanded).exists()) {
00046     if (!file.open(QIODevice::WriteOnly)) {
00047       return err(errmsg, file.errorString());
00048     } 
00049   }
00050   return true;
00051 }
00052 
00053 /** Creates all directories in <b>path</b>, if they do not exist. */
00054 bool
00055 create_path(const QString &path)
00056 {
00057   QDir dir(path);
00058   if (!dir.exists()) {
00059     if (!dir.mkpath(dir.absolutePath())) {
00060       return false;
00061     }
00062   }
00063   return true;
00064 }
00065 
00066 /** Recursively copy the contents of one directory to another. The
00067  * destination must already exist. Returns true on success, and false
00068  * otherwise. */
00069 bool
00070 copy_dir(const QString &source, const QString &dest)
00071 {
00072   /* Source and destination as QDir's */
00073   QDir src(source);
00074   QDir dst(dest);
00075   
00076   /* Get contents of the directory */
00077   QFileInfoList contents = src.entryInfoList(QDir::Files | QDir::Dirs 
00078                                                | QDir::NoDotAndDotDot);
00079 
00080   /* Copy each entry in src to dst */
00081   foreach (QFileInfo fileInfo, contents) {
00082     /* Get absolute path of source and destination */
00083     QString fileName = fileInfo.fileName();
00084     QString srcFilePath = src.absoluteFilePath(fileName);
00085     QString dstFilePath = dst.absoluteFilePath(fileName);
00086 
00087     if (fileInfo.isDir()) {
00088       /* This is a directory, make it and recurse */
00089       if (!dst.mkdir(fileName))
00090         return false;
00091       if (!copy_dir(srcFilePath, dstFilePath))
00092         return false;
00093     } else if (fileInfo.isFile()) {
00094       /* This is a file, copy it */
00095       if (!QFile::copy(srcFilePath, dstFilePath))
00096         return false;
00097     } 
00098     /* Ignore special files (e.g. symlinks, devices) */
00099 
00100   }
00101   return true;
00102 }
00103 
00104 /** Expands <b>filename</b> if it starts with "~/". On Windows, this will
00105  * expand "%APPDATA%" and "%PROGRAMFILES%". If <b>filename</b> does not
00106  * start with a shortcut, <b>filename</b> will be returned unmodified. */
00107 QString
00108 expand_filename(const QString &filename)
00109 {
00110   QString fname = filename;
00111 #if defined(Q_OS_WIN32)
00112   if (fname.startsWith("%APPDATA%\\") ||
00113       fname.startsWith("%APPDATA%/"))
00114     return fname.replace(0, 9, win32_app_data_folder());
00115     
00116   if (fname.startsWith("%PROGRAMFILES%\\") ||
00117       fname.startsWith("%PROGRAMFILES%/"))
00118     return fname.replace(0, 14, win32_program_files_folder());
00119 #else
00120   if (fname.startsWith("~/"))
00121     return fname.replace(0, 1, QDir::homePath());
00122 #endif
00123   return fname;
00124 }
00125