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
00028
00029 #ifdef _WIN32
00030 # include <WinSock2.h>
00031 #endif
00032 #include <assert.h>
00033 #include <ctime>
00034 #include <iomanip>
00035 #ifdef __linux__
00036 # include <sys/sysinfo.h>
00037 #endif
00038
00039
00040 #include "conf/conf_int.h"
00041 #include "conf/conf_bool.h"
00042
00043 using namespace std;
00044
00045 namespace IXE {
00046
00047 struct stat stat_buf;
00048
00049 bool is_indexable_file(char const* path) {
00050 # ifdef _WIN32
00051 DWORD dwAttrs = GetFileAttributes(path);
00052 return !(dwAttrs & (FILE_ATTRIBUTE_SYSTEM |
00053 FILE_ATTRIBUTE_HIDDEN |
00054 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED));
00055 # else
00056 return is_plain_file(path);
00057 # endif
00058 }
00059
00060
00064
00065
00066 void
00067 mapDir(char const* pathname, FileAction& action,
00068 bool recurse_subdirectories, bool follow_symbolic_links,
00069 int verbosity)
00070 {
00071 # ifndef IXE_NO_SYMBOLIC_LINKS
00072 if (is_symbolic_link(pathname) && !follow_symbolic_links) {
00073 if (verbosity > 3)
00074 std::cout << " " << pathname << " (skipped: symbolic link)" << std::endl;
00075 return;
00076 }
00077 # endif
00078
00079 # ifdef __unix__
00080 if (is_directory(pathname)) {
00081 if (recurse_subdirectories) {
00082 DIR *dirp = ::opendir(pathname);
00083 if (dirp == NULL) {
00084 if (verbosity > 3)
00085 std::cerr << " " << pathname << " (skipped: can not open)" << std::endl;
00086 return;
00087 }
00088 std::string const dir_string(pathname);
00089 struct dirent const* dir_ent;
00090 while ((dir_ent = readdir(dirp)) != NULL) {
00091 if (dir_ent->d_name[0] == '.')
00092 continue;
00093 std::string const path(dir_string + PATH_SEPARATOR + dir_ent->d_name);
00094 mapDir(path.c_str(), action,
00095 recurse_subdirectories, follow_symbolic_links, verbosity);
00096 }
00097 ::closedir(dirp);
00098 }
00099 }
00100 # elif defined(_WIN32)
00101 if (is_directory(pathname)) {
00102 if (recurse_subdirectories) {
00103 WIN32_FIND_DATA find;
00104 HANDLE directory;
00105
00106 std::string const dir_string(pathname + std::string("\\*"));
00107
00108 directory = FindFirstFile(dir_string.c_str(), &find);
00109 if (directory == INVALID_HANDLE_VALUE) {
00110 if (verbosity > 3)
00111 std::cerr << " " << pathname << " (skipped: can not open)" << std::endl;
00112 return;
00113 }
00114 if (verbosity > 1)
00115 std::cerr << pathname << std::endl;
00116
00117 FindNextFile(directory, &find);
00118
00119 while (FindNextFile(directory, &find)) {
00120 string const path(string(pathname) + PATH_SEPARATOR +
00121 find.cFileName);
00122 mapDir(path.c_str(), action,
00123 recurse_subdirectories, follow_symbolic_links, verbosity);
00124 }
00125 }
00126 }
00127 # endif // _WIN32
00128 else
00129 action(pathname);
00130 }
00131
00132
00140
00141 void
00142 showTime(char const* msg, struct ::timeval& l0, struct ::timeval& l1, ostream& out)
00143 {
00144 long sec = l1.tv_sec - l0.tv_sec;
00145 long usec = l1.tv_usec - l0.tv_usec;
00146 if (usec < 0) {
00147 sec--;
00148 usec += 1000000;
00149 }
00150 out << msg << setw(3) << sec << "\"" << setw(4) << usec / 1000 << " ms";
00151 }
00152
00153 static int htoi(char const* s)
00154 {
00155 int value;
00156 int c = s[0];
00157 if (isupper(c))
00158 c = tolower(c);
00159 value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
00160 c = s[1];
00161 if (isupper(c))
00162 c = tolower(c);
00163 value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
00164 return (value);
00165 }
00166
00167
00175
00176
00177 int url_decode(char* dest, char const* src, int len)
00178 {
00179 char* cur = dest;
00180 if (!len)
00181 len = ::strlen(src) ;
00182
00183 while (len--) {
00184 if (*src == '+')
00185 *cur = ' ';
00186 else if (*src == '%' && len >= 2 && isxdigit((int)(src[1]))
00187 && isxdigit((int)(src[2]))) {
00188 # ifdef CHARSET_EBCDIC
00189 *cur = os_toebcdic[(char)htoi(src + 1)];
00190 # else
00191 *cur = (char)htoi(src + 1);
00192 # endif
00193 src += 2;
00194 len -= 2;
00195 } else
00196 *cur = *src;
00197 src++;
00198 cur++;
00199 }
00200 *cur = '\0';
00201 return cur - dest;
00202 }
00203
00204 static unsigned char hexchars[] = "0123456789abcdef";
00205
00206
00221
00222 char *
00223 url_encode(char const* s)
00224 {
00225 register int x, y;
00226 unsigned char* str;
00227 int len = ::strlen(s);
00228
00229 str = (unsigned char *)malloc(3 * len + 1);
00230 for (x = 0, y = 0; len--; x++, y++) {
00231 unsigned char c = str[y] = (unsigned char)s[x];
00232
00233 if (!(c >= 'a' && c <= 'z') &&
00234 !(c >= 'A' && c <= 'Z') &&
00235 !(c >= '0' && c <= '9') &&
00236 ::strchr("-_.!~*'()", c) == NULL) {
00237 str[y++] = '%';
00238 str[y++] = hexchars[(unsigned char)s[x] >> 4];
00239 str[y] = hexchars[(unsigned char)s[x] & 15];
00240 }
00241 }
00242 str[y] = '\0';
00243 return (char *)str;
00244 }
00245
00249 int
00250 url_encode(char* dst, char const* s)
00251 {
00252 unsigned char* str = (unsigned char*)dst;
00253 unsigned char c;
00254
00255 for (; (c = *s); s++) {
00256
00257 if (!(c >= 'a' && c <= 'z') &&
00258 !(c >= 'A' && c <= 'Z') &&
00259 !(c >= '0' && c <= '9') &&
00260 ::strchr("-_.!~*'()", c) == NULL) {
00261 *str++ = '%';
00262 *str++ = hexchars[c >> 4];
00263 *str++ = hexchars[c & 15];
00264 } else
00265 *str++ = c;
00266 }
00267 *str = '\0';
00268 return (str - (unsigned char*)dst);
00269 }
00270
00276 void
00277 reverseURLdomain(char* revDomain, char const* url, Size len)
00278 {
00279
00280 static char const URL[] = "http:/" "/";
00281 if (::strncasecmp(URL, url, 7)) {
00282 revDomain[0] = '\0';
00283 return;
00284 }
00285 char const* start = url + 7;
00286 char const* end = ::strchr(start, '/');
00287 if (!end)
00288 end = start + ::strlen(start);
00289
00290 char const* port = ::strchr(start, ':');
00291 if (port && port < end)
00292 end = port;
00293 if ((Size)(end - start) > len)
00294 start = end - len;
00295 while (start < end) {
00296 char const* domain = end;
00297 while (start < domain && *--domain != '.') ;
00298 if (start <= domain) {
00299 if (start == domain &&
00300 *domain != '.')
00301 domain--;
00302 int len = end - (domain + 1);
00303 ::strncpy(revDomain, domain + 1, len);
00304 revDomain += len;
00305 *revDomain++ = '.';
00306 end = domain;
00307 }
00308 else
00309 break;
00310 }
00311
00312 revDomain[-1] = '\0';
00313 }
00314
00315 void
00316 unreverseURLdomain(char* domain, char const* revDomain)
00317 {
00318 char const* start = revDomain;
00319 char const* end = revDomain + ::strlen(revDomain);
00320 if (start == end) {
00321 domain[0] = '\0';
00322 return;
00323 }
00324 while (start < end) {
00325 char const* RevDomain = end;
00326 while (start < RevDomain && *--RevDomain != '.') ;
00327 if (start <= RevDomain) {
00328 if (start == RevDomain &&
00329 *RevDomain != '.')
00330 RevDomain--;
00331 int len = end - (RevDomain + 1);
00332 ::strncpy(domain, RevDomain + 1, len);
00333 domain += len;
00334 *domain++ = '.';
00335 end = RevDomain;
00336 }
00337 else
00338 break;
00339 }
00340
00341 domain[-1] = '\0';
00342 }
00343
00347 Size
00348 availableMemory() {
00349 # ifdef __linux__
00350 # include <linux/version.h>
00351 # if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,48)
00352 # define MEM_UNIT(info) info.mem_unit
00353 # else
00354 # define MEM_UNIT(info) 1
00355 # endif
00356 struct sysinfo info;
00357 sysinfo(&info);
00358 return (info.totalram * MEM_UNIT(info));
00359 # elif defined(_WIN32)
00360 MEMORYSTATUS ms;
00361 GlobalMemoryStatus(&ms);
00362 return ms.dwAvailPhys;
00363 # else
00364 return 0;
00365 # endif
00366 }
00367
00371 void
00372 cgi_parse(map<char const*, char const*>& keyMap, char* qstart)
00373 {
00374
00375 char* qend = qstart;
00376 for (char c = *qstart; (c = *qend); qend++)
00377 if (c == ';')
00378 *qend = '&';
00379
00380 do {
00381 char* key = qstart;
00382 char* valstart = ::strchr(qstart, '=');
00383 valstart = valstart ? valstart : qend;
00384 char* valend = ::strchr(valstart, '&');
00385 valend = valend ? valend : qend;
00386 if (key < valstart && valstart < valend) {
00387 *valstart = '\0';
00388 *valend = '\0';
00389 url_decode(valstart + 1, valstart + 1);
00390 keyMap[key] = valstart+1;
00391 }
00392 qstart = valend + 1;
00393 } while (qstart < qend);
00394 }
00395
00396 }