00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Common/util.h"
00027 #include "io/File.h"
00028
00029
00030 #include <ctime>
00031 #include <iostream>
00032 #include <stdlib.h>
00033 #include <dirent.h>
00034 #ifdef _WIN32
00035 # include <sys/resource.h>
00036 # include <WinSock2.h>
00037 #endif
00038
00039 #ifdef __linux__
00040 # include <sys/sysinfo.h>
00041 #endif
00042
00043 using namespace std;
00044
00045 namespace IXE {
00046
00047
00051
00052
00053 void mapDir(char const* pathname, FileAction& action,
00054 bool recurse_subdirectories, bool follow_symbolic_links,
00055 int verbosity)
00056 {
00057 io::File file(pathname);
00058 # ifndef IXE_NO_SYMBOLIC_LINKS
00059 if (file.isLink() && !follow_symbolic_links) {
00060 if (verbosity > 3)
00061 std::cout << " " << pathname << " (skipped: symbolic link)" << std::endl;
00062 return;
00063 }
00064 # endif
00065
00066 # ifdef __unix__
00067 if (file.isDirectory()) {
00068 if (recurse_subdirectories) {
00069 DIR* dirp = ::opendir(pathname);
00070 if (dirp == NULL) {
00071 if (verbosity > 3)
00072 std::cerr << " " << pathname << " (skipped: can not open)" << std::endl;
00073 return;
00074 }
00075 std::string const dir_string(pathname);
00076 struct dirent const* dir_ent;
00077 while ((dir_ent = readdir(dirp)) != NULL) {
00078 if (dir_ent->d_name[0] == '.')
00079 continue;
00080 std::string const path(dir_string + PATH_SEPARATOR + dir_ent->d_name);
00081 mapDir(path.c_str(), action,
00082 recurse_subdirectories, follow_symbolic_links, verbosity);
00083 }
00084 ::closedir(dirp);
00085 }
00086 }
00087 # elif defined(_WIN32)
00088 if (file.isDirectory()) {
00089 if (recurse_subdirectories) {
00090 WIN32_FIND_DATA find;
00091 HANDLE directory;
00092
00093 std::string const dir_string(pathname + std::string("\\*"));
00094
00095 directory = FindFirstFile(dir_string.c_str(), &find);
00096 if (directory == INVALID_HANDLE_VALUE) {
00097 if (verbosity > 3)
00098 std::cerr << " " << pathname << " (skipped: can not open)" << std::endl;
00099 return;
00100 }
00101 if (verbosity > 1)
00102 std::cerr << pathname << std::endl;
00103
00104 FindNextFile(directory, &find);
00105
00106 while (FindNextFile(directory, &find)) {
00107 string const path(string(pathname) + PATH_SEPARATOR +
00108 find.cFileName);
00109 mapDir(path.c_str(), action,
00110 recurse_subdirectories, follow_symbolic_links, verbosity);
00111 }
00112 }
00113 }
00114 # endif // _WIN32
00115 else
00116 action(pathname);
00117 }
00118
00119 static int htoi(char const* s)
00120 {
00121 int c = s[0];
00122 if (isupper(c))
00123 c = tolower(c);
00124 int value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
00125 c = s[1];
00126 if (isupper(c))
00127 c = tolower(c);
00128 value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
00129 return (value);
00130 }
00131
00132
00140
00141
00142 int url_decode(char* dest, char const* src, int len)
00143 {
00144 char* cur = dest;
00145 if (!len)
00146 len = ::strlen(src) ;
00147
00148 while (len--) {
00149 if (*src == '+')
00150 *cur = ' ';
00151 else if (*src == '%' && len >= 2 && isxdigit((int)(src[1]))
00152 && isxdigit((int)(src[2]))) {
00153 # ifdef CHARSET_EBCDIC
00154 *cur = os_toebcdic[(char)htoi(src + 1)];
00155 # else
00156 *cur = (char)htoi(src + 1);
00157 # endif
00158 src += 2;
00159 len -= 2;
00160 } else
00161 *cur = *src;
00162 src++;
00163 cur++;
00164 }
00165 *cur = '\0';
00166 return cur - dest;
00167 }
00168
00169 static unsigned char hexchars[] = "0123456789abcdef";
00170
00171
00186
00187 char* url_encode(char const* s)
00188 {
00189 int len = ::strlen(s);
00190 unsigned char* str = (unsigned char *)malloc(3 * len + 1);
00191 register int x, y;
00192
00193 for (x = 0, y = 0; len--; x++, y++) {
00194 unsigned char c = str[y] = (unsigned char)s[x];
00195
00196 if (!(c >= 'a' && c <= 'z') &&
00197 !(c >= 'A' && c <= 'Z') &&
00198 !(c >= '0' && c <= '9') &&
00199 ::strchr("-_.!~*'()", c) == NULL) {
00200 str[y++] = '%';
00201 str[y++] = hexchars[(unsigned char)s[x] >> 4];
00202 str[y] = hexchars[(unsigned char)s[x] & 15];
00203 }
00204 }
00205 str[y] = '\0';
00206 return (char *)str;
00207 }
00208
00213 int url_encode(char* dst, char const* s)
00214 {
00215 unsigned char* str = (unsigned char*)dst;
00216 unsigned char c;
00217
00218 for (; c = *s; s++) {
00219
00220 if (!(c >= 'a' && c <= 'z') &&
00221 !(c >= 'A' && c <= 'Z') &&
00222 !(c >= '0' && c <= '9') &&
00223 ::strchr("-_.!~*'()", c) == NULL) {
00224 *str++ = '%';
00225 *str++ = hexchars[c >> 4];
00226 *str++ = hexchars[c & 15];
00227 } else
00228 *str++ = c;
00229 }
00230 *str = '\0';
00231 return str - (unsigned char*)dst;
00232 }
00233
00239 void reverseURLdomain(char* revDomain, char const* url, Size len)
00240 {
00241
00242 static char const http[] = "http:/" "/";
00243 static char const https[] = "https:/" "/";
00244 char const* start = url;
00245 if (!::strncasecmp(http, url, 7))
00246 start += 7;
00247 else if (!::strncasecmp(https, url, 8))
00248 start += 8;
00249 else {
00250 revDomain[0] = '\0';
00251 return;
00252 }
00253 char const* end = ::strchr(start, '/');
00254 if (!end)
00255 end = start + ::strlen(start);
00256
00257 char const* port = ::strchr(start, ':');
00258 if (port && port < end)
00259 end = port;
00260
00261 char const* q = ::strchr(start, '?');
00262 if (q && q < end)
00263 end = q;
00264 if ((Size)(end - start) > len)
00265 start = end - len;
00266 while (start < end) {
00267 char const* domain = end;
00268 while (start < domain && *--domain != '.') ;
00269 if (start <= domain) {
00270 if (start == domain &&
00271 *domain != '.')
00272 domain--;
00273 int len = end - (domain + 1);
00274 ::strncpy(revDomain, domain + 1, len);
00275 revDomain += len;
00276 *revDomain++ = '.';
00277 end = domain;
00278 }
00279 else
00280 break;
00281 }
00282
00283 revDomain[-1] = '\0';
00284 }
00285
00286 void unreverseURLdomain(char* domain, char const* revDomain)
00287 {
00288 char const* start = revDomain;
00289 char const* end = revDomain + ::strlen(revDomain);
00290 if (start == end) {
00291 domain[0] = '\0';
00292 return;
00293 }
00294 while (start < end) {
00295 char const* RevDomain = end;
00296 while (start < RevDomain && *--RevDomain != '.') ;
00297 if (start <= RevDomain) {
00298 if (start == RevDomain &&
00299 *RevDomain != '.')
00300 RevDomain--;
00301 int len = end - (RevDomain + 1);
00302 ::strncpy(domain, RevDomain + 1, len);
00303 domain += len;
00304 *domain++ = '.';
00305 end = RevDomain;
00306 }
00307 else
00308 break;
00309 }
00310
00311 domain[-1] = '\0';
00312 }
00313
00317 Size availableMemory() {
00318 # ifdef __linux__
00319 # include <linux/version.h>
00320 # if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,48)
00321 # define MEM_UNIT(info) info.mem_unit
00322 # else
00323 # define MEM_UNIT(info) 1
00324 # endif
00325 struct sysinfo info;
00326 sysinfo(&info);
00327 return (info.totalram * MEM_UNIT(info));
00328 # elif defined(_WIN32)
00329 MEMORYSTATUS ms;
00330 GlobalMemoryStatus(&ms);
00331 return ms.dwAvailPhys;
00332 # else
00333 return 0;
00334 # endif
00335 }
00336
00341 void cgi_parse(map<char const*, char const*>& keyMap, char* qstart)
00342 {
00343
00344 char* qend = qstart;
00345 for (char c = *qstart; (c = *qend); qend++)
00346 if (c == ';')
00347 *qend = '&';
00348
00349 do {
00350 char* key = qstart;
00351 char* valstart = ::strchr(qstart, '=');
00352 valstart = valstart ? valstart : qend;
00353 char* valend = ::strchr(valstart, '&');
00354 valend = valend ? valend : qend;
00355 if (key < valstart && valstart < valend) {
00356 *valstart = '\0';
00357 *valend = '\0';
00358 url_decode(valstart + 1, valstart + 1);
00359 keyMap[key] = valstart+1;
00360 }
00361 qstart = valend + 1;
00362 } while (qstart < qend);
00363 }
00364
00365 }