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

Generated on Mon Jun 9 13:34:31 2008 for Passenger by  doxygen 1.5.3