Utils.h

00001 /*
00002  *  Phusion Passenger - http://www.modrails.com/
00003  *  Copyright (C) 2008  Phusion
00004  *
00005  *  Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; version 2 of the License.
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 along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 #ifndef _PASSENGER_UTILS_H_
00021 #define _PASSENGER_UTILS_H_
00022 
00023 #include <boost/shared_ptr.hpp>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <string>
00027 #include <vector>
00028 #include <utility>
00029 #include <sstream>
00030 #include <cstdio>
00031 #include <climits>
00032 #include <cstdlib>
00033 #include <cstring>
00034 #include <errno.h>
00035 #include "Exceptions.h"
00036 
00037 namespace Passenger {
00038 
00039 using namespace std;
00040 using namespace boost;
00041 
00042 /**
00043  * Convenience shortcut for creating a <tt>shared_ptr</tt>.
00044  * Instead of:
00045  * @code
00046  *    shared_ptr<Foo> foo;
00047  *    ...
00048  *    foo = shared_ptr<Foo>(new Foo());
00049  * @endcode
00050  * one can write:
00051  * @code
00052  *    shared_ptr<Foo> foo;
00053  *    ...
00054  *    foo = ptr(new Foo());
00055  * @endcode
00056  *
00057  * @param pointer The item to put in the shared_ptr object.
00058  * @ingroup Support
00059  */
00060 template<typename T> shared_ptr<T>
00061 ptr(T *pointer) {
00062         return shared_ptr<T>(pointer);
00063 }
00064 
00065 /**
00066  * Used internally by toString(). Do not use directly.
00067  *
00068  * @internal
00069  */
00070 template<typename T>
00071 struct AnythingToString {
00072         string operator()(T something) {
00073                 stringstream s;
00074                 s << something;
00075                 return s.str();
00076         }
00077 };
00078 
00079 /**
00080  * Used internally by toString(). Do not use directly.
00081  *
00082  * @internal
00083  */
00084 template<>
00085 struct AnythingToString< vector<string> > {
00086         string operator()(const vector<string> &v) {
00087                 string result("[");
00088                 vector<string>::const_iterator it;
00089                 unsigned int i;
00090                 for (it = v.begin(), i = 0; it != v.end(); it++, i++) {
00091                         result.append("'");
00092                         result.append(*it);
00093                         if (i == v.size() - 1) {
00094                                 result.append("'");
00095                         } else {
00096                                 result.append("', ");
00097                         }
00098                 }
00099                 result.append("]");
00100                 return result;
00101         }
00102 };
00103 
00104 /**
00105  * Convert anything to a string.
00106  *
00107  * @param something The thing to convert.
00108  * @ingroup Support
00109  */
00110 template<typename T> string
00111 toString(T something) {
00112         return AnythingToString<T>()(something);
00113 }
00114 
00115 /**
00116  * Converts the given string to an integer.
00117  * @ingroup Support
00118  */
00119 int atoi(const string &s);
00120 
00121 /**
00122  * Split the given string using the given separator.
00123  *
00124  * @param str The string to split.
00125  * @param sep The separator to use.
00126  * @param output The vector to write the output to.
00127  * @ingroup Support
00128  */
00129 void split(const string &str, char sep, vector<string> &output);
00130 
00131 /**
00132  * Check whether the specified file exists.
00133  *
00134  * @param filename The filename to check.
00135  * @return Whether the file exists.
00136  * @throws FileSystemException Unable to check because of a filesystem error.
00137  * @ingroup Support
00138  */
00139 bool fileExists(const char *filename);
00140 
00141 /**
00142  * Find the location of the Passenger spawn server script.
00143  * If passengerRoot is given, t T
00144  *
00145  * @param passengerRoot The Passenger root folder. If NULL is given, then
00146  *      the spawn server is found by scanning $PATH. For security reasons,
00147  *      only absolute paths are scanned.
00148  * @return An absolute path to the spawn server script, or
00149  *         an empty string on error.
00150  * @throws FileSystemException Unable to access parts of the filesystem.
00151  * @ingroup Support
00152  */
00153 string findSpawnServer(const char *passengerRoot = NULL);
00154 
00155 /**
00156  * Find the location of the Passenger ApplicationPool server
00157  * executable.
00158  *
00159  * @param passengerRoot The Passenger root folder.
00160  * @return An absolute path to the executable.
00161  * @throws FileSystemException Unable to access parts of the filesystem.
00162  * @pre passengerRoot != NULL
00163  * @ingroup Support
00164  */
00165 string findApplicationPoolServer(const char *passengerRoot);
00166 
00167 /**
00168  * Returns a canonical version of the specified path. All symbolic links
00169  * and relative path elements are resolved.
00170  * Returns an empty string if something went wrong.
00171  *
00172  * @ingroup Support
00173  */
00174 string canonicalizePath(const string &path);
00175 
00176 /**
00177  * Check whether the specified directory is a valid Ruby on Rails
00178  * 'public' directory.
00179  *
00180  * @throws FileSystemException Unable to check because of a system error.
00181  * @ingroup Support
00182  */
00183 bool verifyRailsDir(const string &dir);
00184 
00185 /**
00186  * Check whether the specified directory is a valid Rack 'public'
00187  * directory.
00188  *
00189  * @throws FileSystemException Unable to check because of a filesystem error.
00190  * @ingroup Support
00191  */
00192 bool verifyRackDir(const string &dir);
00193 
00194 /**
00195  * Check whether the specified directory is a valid WSGI 'public'
00196  * directory.
00197  *
00198  * @throws FileSystemException Unable to check because of a filesystem error.
00199  * @ingroup Support
00200  */
00201 bool verifyWSGIDir(const string &dir);
00202 
00203 /**
00204  * Represents a temporary file. The associated file is automatically
00205  * deleted upon object destruction.
00206  *
00207  * @ingroup Support
00208  */
00209 class TempFile {
00210 public:
00211         /** The filename. If this temp file is anonymous, then the filename is an empty string. */
00212         string filename;
00213         /** The file handle. */
00214         FILE *handle;
00215         
00216         /**
00217          * Create an empty, temporary file, and open it for reading and writing.
00218          *
00219          * @param anonymous Set to true if this temp file should be unlinked
00220          *        immediately. Anonymous temp files are useful if one just wants
00221          *        a big not-in-memory buffer to work with.
00222          * @throws SystemException Something went wrong.
00223          */
00224         TempFile(bool anonymous = true) {
00225                 const char *temp_dir;
00226                 char templ[PATH_MAX];
00227                 int fd;
00228                 
00229                 temp_dir = getenv("TMP");
00230                 if (temp_dir == NULL || *temp_dir == '\0') {
00231                         temp_dir = "/tmp";
00232                 }
00233                 
00234                 snprintf(templ, sizeof(templ), "%s/passenger.XXXXXX", temp_dir);
00235                 templ[sizeof(templ) - 1] = '\0';
00236                 fd = mkstemp(templ);
00237                 if (fd == -1) {
00238                         throw SystemException("Cannot create a temporary file", errno);
00239                 }
00240                 if (anonymous) {
00241                         fchmod(fd, 0000);
00242                         unlink(templ);
00243                 } else {
00244                         filename.assign(templ);
00245                 }
00246                 handle = fdopen(fd, "w+");
00247         }
00248         
00249         ~TempFile() {
00250                 fclose(handle);
00251                 if (!filename.empty()) {
00252                         unlink(filename.c_str());
00253                 }
00254         }
00255 };
00256 
00257 } // namespace Passenger
00258 
00259 #endif /* _PASSENGER_UTILS_H_ */
00260 

Generated on Fri Jan 23 08:28:57 2009 for Passenger by  doxygen 1.4.7