tests/harness/unixcmds.cc

Go to the documentation of this file.
00001 
00004 /* Copyright (C) 2003,2004,2007 Olly Betts
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the
00009  * License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include "unixcmds.h"
00024 
00025 #include <cstring>
00026 #include <string>
00027 #include <stdlib.h>
00028 #include <sys/types.h>
00029 #include "safesysstat.h"
00030 #include "safeunistd.h"
00031 #include "safefcntl.h"
00032 
00033 #ifdef __WIN32__
00034 # include "safewindows.h"
00035 #endif
00036 
00037 #include "stringutils.h"
00038 #include "utils.h"
00039 
00040 using namespace std;
00041 
00043 static bool
00044 append_filename_argument(string & cmd, const string & arg) {
00045 #ifdef __WIN32__
00046     cmd.reserve(cmd.size() + arg.size() + 3);
00047     cmd += " \"";
00048     for (string::const_iterator i = arg.begin(); i != arg.end(); ++i) {
00049         if (*i == '/') {
00050             // Convert Unix path separators to backslashes.  C library
00051             // functions understand "/" in paths, but we are going to
00052             // call commands like "deltree" or "rd" which don't.
00053             cmd += '\\';
00054         } else if (*i < 32 || strchr("<>\"|*?", *i)) {
00055             // Check for illegal characters in filename.
00056             return false;
00057         } else {
00058             cmd += *i;
00059         }
00060     }
00061     cmd += '"';
00062 #else
00063     // Allow for escaping a few characters.
00064     cmd.reserve(cmd.size() + arg.size() + 10);
00065 
00066     // Prevent a leading "-" on the filename being interpreted as a command
00067     // line option.
00068     if (arg[0] == '-')
00069         cmd += " ./";
00070     else
00071         cmd += ' ';
00072 
00073     for (string::const_iterator i = arg.begin(); i != arg.end(); ++i) {
00074         // Don't escape a few safe characters which are common in filenames.
00075         if (!C_isalnum(*i) && strchr("/._-", *i) == NULL) {
00076             cmd += '\\';
00077         }
00078         cmd += *i;
00079     }
00080 #endif
00081     return true;
00082 }
00083 
00085 void cp_R(const std::string &src, const std::string &dest) {
00086 #ifdef __WIN32__
00087     // xcopy should be available on both NT and 95 derivatives.  We create
00088     // the target directory first to avoid being prompted as to whether we
00089     // want to create a directory or a file (which makes no sense when
00090     // copying a directory, but that's how xcopy seems to work!)
00091     mkdir(dest.c_str());
00092     string cmd("xcopy /E /Y");
00093 #else
00094     string cmd("cp -R");
00095 #endif
00096     if (!append_filename_argument(cmd, src)) return;
00097     if (!append_filename_argument(cmd, dest)) return;
00098     system(cmd);
00099 #ifndef __WIN32__
00100     // Allow write access to the copy (to deal with builds where srcdir is
00101     // readonly).
00102     cmd = "chmod -R +w";
00103     if (!append_filename_argument(cmd, dest)) return;
00104     system(cmd);
00105 #endif
00106 }
00107 
00108 #ifdef __WIN32__
00109 static bool running_on_win9x() {
00110     static int win9x = -1;
00111     if (win9x == -1) {
00112         OSVERSIONINFO info;
00113         memset(&info, 0, sizeof(OSVERSIONINFO));
00114         info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00115         if (GetVersionEx(&info)) {
00116             win9x = (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
00117         }
00118     }
00119     return win9x;
00120 }
00121 #endif
00122 
00124 void rm_rf(const string &filename) {
00125     // Check filename exists and is actually a directory
00126     struct stat sb;
00127     if (filename.empty() || stat(filename, &sb) != 0 || !S_ISDIR(sb.st_mode))
00128         return;
00129 
00130 #ifdef __WIN32__
00131     string cmd;
00132     if (running_on_win9x()) {
00133         // For 95-like systems:
00134         cmd = "deltree /y";
00135     } else {
00136         // For NT-like systems:
00137         cmd = "rd /s /q";
00138     }
00139 #else
00140     string cmd("rm -rf");
00141 #endif
00142     if (!append_filename_argument(cmd, filename)) return;
00143     system(cmd);
00144 }
00145 
00147 void touch(const string &filename) {
00148     int fd = open(filename.c_str(), O_CREAT|O_WRONLY|O_BINARY, 0644);
00149     if (fd >= 0) close(fd);
00150 }

Documentation for Xapian (version 1.0.10).
Generated on 24 Dec 2008 by Doxygen 1.5.2.