Vidalia
0.2.17
|
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