PageRenderTime 74ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/rsync/mongoose.c

https://github.com/AnupBansod/SS-Rsync
C | 5457 lines | 4233 code | 730 blank | 494 comment | 1268 complexity | 75b437de0ac5dd9b6bfe890035dd3fff MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. // Copyright (c) 2004-2013 Sergey Lyubka
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be included in
  11. // all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. // THE SOFTWARE.
  20. #if defined(_WIN32)
  21. #define _CRT_SECURE_NO_WARNINGS // Disable deprecation warning in VS2005
  22. #else
  23. #ifdef __linux__
  24. #define _XOPEN_SOURCE 600 // For flockfile() on Linux
  25. #endif
  26. #define _LARGEFILE_SOURCE // Enable 64-bit file offsets
  27. #define __STDC_FORMAT_MACROS // <inttypes.h> wants this for C++
  28. #define __STDC_LIMIT_MACROS // C++ wants that for INT64_MAX
  29. #endif
  30. #if defined (_MSC_VER)
  31. // conditional expression is constant: introduced by FD_SET(..)
  32. #pragma warning (disable : 4127)
  33. // non-constant aggregate initializer: issued due to missing C99 support
  34. #pragma warning (disable : 4204)
  35. #endif
  36. // Disable WIN32_LEAN_AND_MEAN.
  37. // This makes windows.h always include winsock2.h
  38. #ifdef WIN32_LEAN_AND_MEAN
  39. #undef WIN32_LEAN_AND_MEAN
  40. #endif
  41. #if defined(__SYMBIAN32__)
  42. #define NO_SSL // SSL is not supported
  43. #define NO_CGI // CGI is not supported
  44. #define PATH_MAX FILENAME_MAX
  45. #endif // __SYMBIAN32__
  46. #ifndef _WIN32_WCE // Some ANSI #includes are not available on Windows CE
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include <errno.h>
  50. #include <signal.h>
  51. #include <fcntl.h>
  52. #endif // !_WIN32_WCE
  53. #include <time.h>
  54. #include <stdlib.h>
  55. #include <stdarg.h>
  56. #include <assert.h>
  57. #include <string.h>
  58. #include <ctype.h>
  59. #include <limits.h>
  60. #include <stddef.h>
  61. #include <stdio.h>
  62. #include <sys/ioctl.h>
  63. int mg_in;
  64. int mg_out;
  65. #if defined(_WIN32) && !defined(__SYMBIAN32__) // Windows specific
  66. #define _WIN32_WINNT 0x0400 // To make it link in VS2005
  67. #include <windows.h>
  68. #ifndef PATH_MAX
  69. #define PATH_MAX MAX_PATH
  70. #endif
  71. #ifndef _WIN32_WCE
  72. #include <process.h>
  73. #include <direct.h>
  74. #include <io.h>
  75. #else // _WIN32_WCE
  76. #define NO_CGI // WinCE has no pipes
  77. typedef long off_t;
  78. #define errno GetLastError()
  79. #define strerror(x) _ultoa(x, (char *) _alloca(sizeof(x) *3 ), 10)
  80. #endif // _WIN32_WCE
  81. #define MAKEUQUAD(lo, hi) ((uint64_t)(((uint32_t)(lo)) | \
  82. ((uint64_t)((uint32_t)(hi))) << 32))
  83. #define RATE_DIFF 10000000 // 100 nsecs
  84. #define EPOCH_DIFF MAKEUQUAD(0xd53e8000, 0x019db1de)
  85. #define SYS2UNIX_TIME(lo, hi) \
  86. (time_t) ((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)
  87. // Visual Studio 6 does not know __func__ or __FUNCTION__
  88. // The rest of MS compilers use __FUNCTION__, not C99 __func__
  89. // Also use _strtoui64 on modern M$ compilers
  90. #if defined(_MSC_VER) && _MSC_VER < 1300
  91. #define STRX(x) #x
  92. #define STR(x) STRX(x)
  93. #define __func__ __FILE__ ":" STR(__LINE__)
  94. #define strtoull(x, y, z) strtoul(x, y, z)
  95. #define strtoll(x, y, z) strtol(x, y, z)
  96. #else
  97. #define __func__ __FUNCTION__
  98. #define strtoull(x, y, z) _strtoui64(x, y, z)
  99. #define strtoll(x, y, z) _strtoi64(x, y, z)
  100. #endif // _MSC_VER
  101. #define ERRNO GetLastError()
  102. #define NO_SOCKLEN_T
  103. #define SSL_LIB "ssleay32.dll"
  104. #define CRYPTO_LIB "libeay32.dll"
  105. #define O_NONBLOCK 0
  106. #if !defined(EWOULDBLOCK)
  107. #define EWOULDBLOCK WSAEWOULDBLOCK
  108. #endif // !EWOULDBLOCK
  109. #define _POSIX_
  110. #define INT64_FMT "I64d"
  111. #define WINCDECL __cdecl
  112. #define SHUT_WR 1
  113. #define snprintf _snprintf
  114. #define vsnprintf _vsnprintf
  115. #define mg_sleep(x) Sleep(x)
  116. #define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY)
  117. #define popen(x, y) _popen(x, y)
  118. #define pclose(x) _pclose(x)
  119. #define close(x) _close(x)
  120. #define dlsym(x,y) GetProcAddress((HINSTANCE) (x), (y))
  121. #define RTLD_LAZY 0
  122. #define fseeko(x, y, z) _lseeki64(_fileno(x), (y), (z))
  123. #define fdopen(x, y) _fdopen((x), (y))
  124. #define write(x, y, z) _write((x), (y), (unsigned) z)
  125. #define read(x, y, z) _read((x), (y), (unsigned) z)
  126. #define flockfile(x) EnterCriticalSection(&global_log_file_lock)
  127. #define funlockfile(x) LeaveCriticalSection(&global_log_file_lock)
  128. #define sleep(x) Sleep((x) * 1000)
  129. #define va_copy(x, y) x = y
  130. #if !defined(fileno)
  131. #define fileno(x) _fileno(x)
  132. #endif // !fileno MINGW #defines fileno
  133. typedef HANDLE pthread_mutex_t;
  134. typedef struct {HANDLE signal, broadcast;} pthread_cond_t;
  135. typedef DWORD pthread_t;
  136. #define pid_t HANDLE // MINGW typedefs pid_t to int. Using #define here.
  137. static int pthread_mutex_lock(pthread_mutex_t *);
  138. static int pthread_mutex_unlock(pthread_mutex_t *);
  139. static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len);
  140. struct file;
  141. static char *mg_fgets(char *buf, size_t size, struct file *filep, char **p);
  142. #if defined(HAVE_STDINT)
  143. #include <stdint.h>
  144. #else
  145. typedef unsigned int uint32_t;
  146. typedef unsigned short uint16_t;
  147. typedef unsigned __int64 uint64_t;
  148. typedef __int64 int64_t;
  149. #define INT64_MAX 9223372036854775807
  150. #endif // HAVE_STDINT
  151. // POSIX dirent interface
  152. struct dirent {
  153. char d_name[PATH_MAX];
  154. };
  155. typedef struct DIR {
  156. HANDLE handle;
  157. WIN32_FIND_DATAW info;
  158. struct dirent result;
  159. } DIR;
  160. #ifndef HAS_POLL
  161. struct pollfd {
  162. int fd;
  163. short events;
  164. short revents;
  165. };
  166. #define POLLIN 1
  167. #endif
  168. // Mark required libraries
  169. #pragma comment(lib, "Ws2_32.lib")
  170. #else // UNIX specific
  171. #include <sys/wait.h>
  172. #include <sys/socket.h>
  173. #include <sys/poll.h>
  174. #include <netinet/in.h>
  175. #include <arpa/inet.h>
  176. #include <sys/time.h>
  177. #include <stdint.h>
  178. #include <inttypes.h>
  179. #include <netdb.h>
  180. #include <pwd.h>
  181. #include <unistd.h>
  182. #include <dirent.h>
  183. #if !defined(NO_SSL_DL) && !defined(NO_SSL)
  184. #include <dlfcn.h>
  185. #endif
  186. #include <pthread.h>
  187. #if defined(__MACH__)
  188. #define SSL_LIB "libssl.dylib"
  189. #define CRYPTO_LIB "libcrypto.dylib"
  190. #else
  191. #if !defined(SSL_LIB)
  192. #define SSL_LIB "libssl.so"
  193. #endif
  194. #if !defined(CRYPTO_LIB)
  195. #define CRYPTO_LIB "libcrypto.so"
  196. #endif
  197. #endif
  198. #ifndef O_BINARY
  199. #define O_BINARY 0
  200. #endif // O_BINARY
  201. #define closesocket(a) close(a)
  202. #define mg_mkdir(x, y) mkdir(x, y)
  203. #define mg_remove(x) remove(x)
  204. #define mg_rename(x, y) rename(x, y)
  205. #define mg_sleep(x) usleep((x) * 1000)
  206. #define ERRNO errno
  207. #define INVALID_SOCKET (-1)
  208. #define INT64_FMT PRId64
  209. typedef int SOCKET;
  210. #define WINCDECL
  211. #endif // End of Windows and UNIX specific includes
  212. #include "mongoose.h"
  213. #ifdef USE_LUA
  214. #include <lua.h>
  215. #include <lauxlib.h>
  216. #endif
  217. #define MONGOOSE_VERSION "3.8"
  218. #define PASSWORDS_FILE_NAME ".htpasswd"
  219. #define CGI_ENVIRONMENT_SIZE 4096
  220. #define MAX_CGI_ENVIR_VARS 64
  221. #define MG_BUF_LEN 8192
  222. #define MAX_REQUEST_SIZE 16384
  223. #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
  224. #ifdef _WIN32
  225. static CRITICAL_SECTION global_log_file_lock;
  226. static pthread_t pthread_self(void) {
  227. return GetCurrentThreadId();
  228. }
  229. #endif // _WIN32
  230. #ifdef DEBUG_TRACE
  231. #undef DEBUG_TRACE
  232. #define DEBUG_TRACE(x)
  233. #else
  234. #if defined(DEBUG)
  235. #define DEBUG_TRACE(x) do { \
  236. flockfile(stdout); \
  237. printf("*** %lu.%p.%s.%d: ", \
  238. (unsigned long) time(NULL), (void *) pthread_self(), \
  239. __func__, __LINE__); \
  240. printf x; \
  241. putchar('\n'); \
  242. fflush(stdout); \
  243. funlockfile(stdout); \
  244. } while (0)
  245. #else
  246. #define DEBUG_TRACE(x)
  247. #endif // DEBUG
  248. #endif // DEBUG_TRACE
  249. // Darwin prior to 7.0 and Win32 do not have socklen_t
  250. #ifdef NO_SOCKLEN_T
  251. typedef int socklen_t;
  252. #endif // NO_SOCKLEN_T
  253. #define _DARWIN_UNLIMITED_SELECT
  254. #if !defined(MSG_NOSIGNAL)
  255. #define MSG_NOSIGNAL 0
  256. #endif
  257. #if !defined(SOMAXCONN)
  258. #define SOMAXCONN 100
  259. #endif
  260. #if !defined(PATH_MAX)
  261. #define PATH_MAX 4096
  262. #endif
  263. static const char *http_500_error = "Internal Server Error";
  264. #if defined(NO_SSL_DL)
  265. #include <openssl/ssl.h>
  266. #else
  267. // SSL loaded dynamically from DLL.
  268. // I put the prototypes here to be independent from OpenSSL source installation.
  269. typedef struct ssl_st SSL;
  270. typedef struct ssl_method_st SSL_METHOD;
  271. typedef struct ssl_ctx_st SSL_CTX;
  272. struct ssl_func {
  273. const char *name; // SSL function name
  274. void (*ptr)(void); // Function pointer
  275. };
  276. #define SSL_free (* (void (*)(SSL *)) ssl_sw[0].ptr)
  277. #define SSL_accept (* (int (*)(SSL *)) ssl_sw[1].ptr)
  278. #define SSL_connect (* (int (*)(SSL *)) ssl_sw[2].ptr)
  279. #define SSL_read (* (int (*)(SSL *, void *, int)) ssl_sw[3].ptr)
  280. #define SSL_write (* (int (*)(SSL *, const void *,int)) ssl_sw[4].ptr)
  281. #define SSL_get_error (* (int (*)(SSL *, int)) ssl_sw[5].ptr)
  282. #define SSL_set_fd (* (int (*)(SSL *, SOCKET)) ssl_sw[6].ptr)
  283. #define SSL_new (* (SSL * (*)(SSL_CTX *)) ssl_sw[7].ptr)
  284. #define SSL_CTX_new (* (SSL_CTX * (*)(SSL_METHOD *)) ssl_sw[8].ptr)
  285. #define SSLv23_server_method (* (SSL_METHOD * (*)(void)) ssl_sw[9].ptr)
  286. #define SSL_library_init (* (int (*)(void)) ssl_sw[10].ptr)
  287. #define SSL_CTX_use_PrivateKey_file (* (int (*)(SSL_CTX *, \
  288. const char *, int)) ssl_sw[11].ptr)
  289. #define SSL_CTX_use_certificate_file (* (int (*)(SSL_CTX *, \
  290. const char *, int)) ssl_sw[12].ptr)
  291. #define SSL_CTX_set_default_passwd_cb \
  292. (* (void (*)(SSL_CTX *, mg_callback_t)) ssl_sw[13].ptr)
  293. #define SSL_CTX_free (* (void (*)(SSL_CTX *)) ssl_sw[14].ptr)
  294. #define SSL_load_error_strings (* (void (*)(void)) ssl_sw[15].ptr)
  295. #define SSL_CTX_use_certificate_chain_file \
  296. (* (int (*)(SSL_CTX *, const char *)) ssl_sw[16].ptr)
  297. #define SSLv23_client_method (* (SSL_METHOD * (*)(void)) ssl_sw[17].ptr)
  298. #define SSL_pending (* (int (*)(SSL *)) ssl_sw[18].ptr)
  299. #define SSL_CTX_set_verify (* (void (*)(SSL_CTX *, int, int)) ssl_sw[19].ptr)
  300. #define CRYPTO_num_locks (* (int (*)(void)) crypto_sw[0].ptr)
  301. #define CRYPTO_set_locking_callback \
  302. (* (void (*)(void (*)(int, int, const char *, int))) crypto_sw[1].ptr)
  303. #define CRYPTO_set_id_callback \
  304. (* (void (*)(unsigned long (*)(void))) crypto_sw[2].ptr)
  305. #define ERR_get_error (* (unsigned long (*)(void)) crypto_sw[3].ptr)
  306. #define ERR_error_string (* (char * (*)(unsigned long,char *)) crypto_sw[4].ptr)
  307. // set_ssl_option() function updates this array.
  308. // It loads SSL library dynamically and changes NULLs to the actual addresses
  309. // of respective functions. The macros above (like SSL_connect()) are really
  310. // just calling these functions indirectly via the pointer.
  311. static struct ssl_func ssl_sw[] = {
  312. {"SSL_free", NULL},
  313. {"SSL_accept", NULL},
  314. {"SSL_connect", NULL},
  315. {"SSL_read", NULL},
  316. {"SSL_write", NULL},
  317. {"SSL_get_error", NULL},
  318. {"SSL_set_fd", NULL},
  319. {"SSL_new", NULL},
  320. {"SSL_CTX_new", NULL},
  321. {"SSLv23_server_method", NULL},
  322. {"SSL_library_init", NULL},
  323. {"SSL_CTX_use_PrivateKey_file", NULL},
  324. {"SSL_CTX_use_certificate_file",NULL},
  325. {"SSL_CTX_set_default_passwd_cb",NULL},
  326. {"SSL_CTX_free", NULL},
  327. {"SSL_load_error_strings", NULL},
  328. {"SSL_CTX_use_certificate_chain_file", NULL},
  329. {"SSLv23_client_method", NULL},
  330. {"SSL_pending", NULL},
  331. {"SSL_CTX_set_verify", NULL},
  332. {NULL, NULL}
  333. };
  334. // Similar array as ssl_sw. These functions could be located in different lib.
  335. #if !defined(NO_SSL)
  336. static struct ssl_func crypto_sw[] = {
  337. {"CRYPTO_num_locks", NULL},
  338. {"CRYPTO_set_locking_callback", NULL},
  339. {"CRYPTO_set_id_callback", NULL},
  340. {"ERR_get_error", NULL},
  341. {"ERR_error_string", NULL},
  342. {NULL, NULL}
  343. };
  344. #endif // NO_SSL
  345. #endif // NO_SSL_DL
  346. static const char *month_names[] = {
  347. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  348. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  349. };
  350. // Unified socket address. For IPv6 support, add IPv6 address structure
  351. // in the union u.
  352. union usa {
  353. struct sockaddr sa;
  354. struct sockaddr_in sin;
  355. #if defined(USE_IPV6)
  356. struct sockaddr_in6 sin6;
  357. #endif
  358. };
  359. // Describes a string (chunk of memory).
  360. struct vec {
  361. const char *ptr;
  362. size_t len;
  363. };
  364. struct file {
  365. int is_directory;
  366. time_t modification_time;
  367. int64_t size;
  368. FILE *fp;
  369. const char *membuf; // Non-NULL if file data is in memory
  370. };
  371. #define STRUCT_FILE_INITIALIZER {0, 0, 0, NULL, NULL}
  372. // Describes listening socket, or socket which was accept()-ed by the master
  373. // thread and queued for future handling by the worker thread.
  374. struct socket {
  375. SOCKET sock; // Listening socket
  376. union usa lsa; // Local socket address
  377. union usa rsa; // Remote socket address
  378. unsigned is_ssl:1; // Is port SSL-ed
  379. unsigned ssl_redir:1; // Is port supposed to redirect everything to SSL port
  380. };
  381. // NOTE(lsm): this enum shoulds be in sync with the config_options below.
  382. enum {
  383. CGI_EXTENSIONS, CGI_ENVIRONMENT, PUT_DELETE_PASSWORDS_FILE, CGI_INTERPRETER,
  384. PROTECT_URI, AUTHENTICATION_DOMAIN, SSI_EXTENSIONS, THROTTLE,
  385. ACCESS_LOG_FILE, ENABLE_DIRECTORY_LISTING, ERROR_LOG_FILE,
  386. GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
  387. EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE,
  388. NUM_THREADS, RUN_AS_USER, REWRITE, HIDE_FILES, REQUEST_TIMEOUT,
  389. NUM_OPTIONS
  390. };
  391. static const char *config_options[] = {
  392. "C", "cgi_pattern", "**.cgi$|**.pl$|**.php$",
  393. "E", "cgi_environment", NULL,
  394. "G", "put_delete_auth_file", NULL,
  395. "I", "cgi_interpreter", NULL,
  396. "P", "protect_uri", NULL,
  397. "R", "authentication_domain", "mydomain.com",
  398. "S", "ssi_pattern", "**.shtml$|**.shtm$",
  399. "T", "throttle", NULL,
  400. "a", "access_log_file", NULL,
  401. "d", "enable_directory_listing", "yes",
  402. "e", "error_log_file", NULL,
  403. "g", "global_auth_file", NULL,
  404. "i", "index_files",
  405. "index.html,index.htm,index.cgi,index.shtml,index.php,index.lp",
  406. "k", "enable_keep_alive", "no",
  407. "l", "access_control_list", NULL,
  408. "m", "extra_mime_types", NULL,
  409. "p", "listening_ports", "8080",
  410. "r", "document_root", ".",
  411. "s", "ssl_certificate", NULL,
  412. "t", "num_threads", "50",
  413. "u", "run_as_user", NULL,
  414. "w", "url_rewrite_patterns", NULL,
  415. "x", "hide_files_patterns", NULL,
  416. "z", "request_timeout_ms", "30000",
  417. NULL
  418. };
  419. #define ENTRIES_PER_CONFIG_OPTION 3
  420. struct mg_context {
  421. volatile int stop_flag; // Should we stop event loop
  422. SSL_CTX *ssl_ctx; // SSL context
  423. char *config[NUM_OPTIONS]; // Mongoose configuration parameters
  424. struct mg_callbacks callbacks; // User-defined callback function
  425. void *user_data; // User-defined data
  426. struct socket *listening_sockets;
  427. int num_listening_sockets;
  428. volatile int num_threads; // Number of threads
  429. pthread_mutex_t mutex; // Protects (max|num)_threads
  430. pthread_cond_t cond; // Condvar for tracking workers terminations
  431. struct socket queue[20]; // Accepted sockets
  432. volatile int sq_head; // Head of the socket queue
  433. volatile int sq_tail; // Tail of the socket queue
  434. pthread_cond_t sq_full; // Signaled when socket is produced
  435. pthread_cond_t sq_empty; // Signaled when socket is consumed
  436. };
  437. struct mg_connection {
  438. struct mg_request_info request_info;
  439. struct mg_context *ctx;
  440. SSL *ssl; // SSL descriptor
  441. SSL_CTX *client_ssl_ctx; // SSL context for client connections
  442. struct socket client; // Connected client
  443. time_t birth_time; // Time when request was received
  444. int64_t num_bytes_sent; // Total bytes sent to client
  445. int64_t content_len; // Content-Length header value
  446. int64_t consumed_content; // How many bytes of content have been read
  447. char *buf; // Buffer for received data
  448. char *path_info; // PATH_INFO part of the URL
  449. int must_close; // 1 if connection must be closed
  450. int buf_size; // Buffer size
  451. int request_len; // Size of the request + headers in a buffer
  452. int data_len; // Total size of data in a buffer
  453. int status_code; // HTTP reply status code, e.g. 200
  454. int throttle; // Throttling, bytes/sec. <= 0 means no throttle
  455. time_t last_throttle_time; // Last time throttled data was sent
  456. int64_t last_throttle_bytes;// Bytes sent this second
  457. };
  458. const char **mg_get_valid_option_names(void) {
  459. return config_options;
  460. }
  461. static int is_file_in_memory(struct mg_connection *conn, const char *path,
  462. struct file *filep) {
  463. size_t size = 0;
  464. if ((filep->membuf = conn->ctx->callbacks.open_file == NULL ? NULL :
  465. conn->ctx->callbacks.open_file(conn, path, &size)) != NULL) {
  466. // NOTE: override filep->size only on success. Otherwise, it might break
  467. // constructs like if (!mg_stat() || !mg_fopen()) ...
  468. filep->size = size;
  469. }
  470. return filep->membuf != NULL;
  471. }
  472. static int is_file_opened(const struct file *filep) {
  473. return filep->membuf != NULL || filep->fp != NULL;
  474. }
  475. static int mg_fopen(struct mg_connection *conn, const char *path,
  476. const char *mode, struct file *filep) {
  477. if (!is_file_in_memory(conn, path, filep)) {
  478. #ifdef _WIN32
  479. wchar_t wbuf[PATH_MAX], wmode[20];
  480. to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
  481. MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode));
  482. filep->fp = _wfopen(wbuf, wmode);
  483. #else
  484. filep->fp = fopen(path, mode);
  485. #endif
  486. }
  487. return is_file_opened(filep);
  488. }
  489. static void mg_fclose(struct file *filep) {
  490. if (filep != NULL && filep->fp != NULL) {
  491. fclose(filep->fp);
  492. }
  493. }
  494. static int get_option_index(const char *name) {
  495. int i;
  496. for (i = 0; config_options[i] != NULL; i += ENTRIES_PER_CONFIG_OPTION) {
  497. if (strcmp(config_options[i], name) == 0 ||
  498. strcmp(config_options[i + 1], name) == 0) {
  499. return i / ENTRIES_PER_CONFIG_OPTION;
  500. }
  501. }
  502. return -1;
  503. }
  504. const char *mg_get_option(const struct mg_context *ctx, const char *name) {
  505. int i;
  506. if ((i = get_option_index(name)) == -1) {
  507. return NULL;
  508. } else if (ctx->config[i] == NULL) {
  509. return "";
  510. } else {
  511. return ctx->config[i];
  512. }
  513. }
  514. static void sockaddr_to_string(char *buf, size_t len,
  515. const union usa *usa) {
  516. buf[0] = '\0';
  517. #if defined(USE_IPV6)
  518. inet_ntop(usa->sa.sa_family, usa->sa.sa_family == AF_INET ?
  519. (void *) &usa->sin.sin_addr :
  520. (void *) &usa->sin6.sin6_addr, buf, len);
  521. #elif defined(_WIN32)
  522. // Only Windoze Vista (and newer) have inet_ntop()
  523. strncpy(buf, inet_ntoa(usa->sin.sin_addr), len);
  524. #else
  525. inet_ntop(usa->sa.sa_family, (void *) &usa->sin.sin_addr, buf, len);
  526. #endif
  527. }
  528. static void cry(struct mg_connection *conn,
  529. PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
  530. // Print error message to the opened error log stream.
  531. static void cry(struct mg_connection *conn, const char *fmt, ...) {
  532. char buf[MG_BUF_LEN], src_addr[20];
  533. va_list ap;
  534. FILE *fp;
  535. time_t timestamp;
  536. va_start(ap, fmt);
  537. (void) vsnprintf(buf, sizeof(buf), fmt, ap);
  538. va_end(ap);
  539. // Do not lock when getting the callback value, here and below.
  540. // I suppose this is fine, since function cannot disappear in the
  541. // same way string option can.
  542. if (conn->ctx->callbacks.log_message == NULL ||
  543. conn->ctx->callbacks.log_message(conn, buf) == 0) {
  544. fp = conn->ctx == NULL || conn->ctx->config[ERROR_LOG_FILE] == NULL ? NULL :
  545. fopen(conn->ctx->config[ERROR_LOG_FILE], "a+");
  546. if (fp != NULL) {
  547. flockfile(fp);
  548. timestamp = time(NULL);
  549. sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa);
  550. fprintf(fp, "[%010lu] [error] [client %s] ", (unsigned long) timestamp,
  551. src_addr);
  552. if (conn->request_info.request_method != NULL) {
  553. fprintf(fp, "%s %s: ", conn->request_info.request_method,
  554. conn->request_info.uri);
  555. }
  556. fprintf(fp, "%s", buf);
  557. fputc('\n', fp);
  558. funlockfile(fp);
  559. fclose(fp);
  560. }
  561. }
  562. }
  563. // Return fake connection structure. Used for logging, if connection
  564. // is not applicable at the moment of logging.
  565. static struct mg_connection *fc(struct mg_context *ctx) {
  566. static struct mg_connection fake_connection;
  567. fake_connection.ctx = ctx;
  568. return &fake_connection;
  569. }
  570. const char *mg_version(void) {
  571. return MONGOOSE_VERSION;
  572. }
  573. struct mg_request_info *mg_get_request_info(struct mg_connection *conn) {
  574. return &conn->request_info;
  575. }
  576. static void mg_strlcpy(register char *dst, register const char *src, size_t n) {
  577. for (; *src != '\0' && n > 1; n--) {
  578. *dst++ = *src++;
  579. }
  580. *dst = '\0';
  581. }
  582. static int lowercase(const char *s) {
  583. return tolower(* (const unsigned char *) s);
  584. }
  585. static int mg_strncasecmp(const char *s1, const char *s2, size_t len) {
  586. int diff = 0;
  587. if (len > 0)
  588. do {
  589. diff = lowercase(s1++) - lowercase(s2++);
  590. } while (diff == 0 && s1[-1] != '\0' && --len > 0);
  591. return diff;
  592. }
  593. static int mg_strcasecmp(const char *s1, const char *s2) {
  594. int diff;
  595. do {
  596. diff = lowercase(s1++) - lowercase(s2++);
  597. } while (diff == 0 && s1[-1] != '\0');
  598. return diff;
  599. }
  600. static char * mg_strndup(const char *ptr, size_t len) {
  601. char *p;
  602. if ((p = (char *) malloc(len + 1)) != NULL) {
  603. mg_strlcpy(p, ptr, len + 1);
  604. }
  605. return p;
  606. }
  607. static char * mg_strdup(const char *str) {
  608. return mg_strndup(str, strlen(str));
  609. }
  610. // Like snprintf(), but never returns negative value, or a value
  611. // that is larger than a supplied buffer.
  612. // Thanks to Adam Zeldis to pointing snprintf()-caused vulnerability
  613. // in his audit report.
  614. static int mg_vsnprintf(struct mg_connection *conn, char *buf, size_t buflen,
  615. const char *fmt, va_list ap) {
  616. int n;
  617. if (buflen == 0)
  618. return 0;
  619. n = vsnprintf(buf, buflen, fmt, ap);
  620. if (n < 0) {
  621. cry(conn, "vsnprintf error");
  622. n = 0;
  623. } else if (n >= (int) buflen) {
  624. cry(conn, "truncating vsnprintf buffer: [%.*s]",
  625. n > 200 ? 200 : n, buf);
  626. n = (int) buflen - 1;
  627. }
  628. buf[n] = '\0';
  629. return n;
  630. }
  631. static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
  632. PRINTF_FORMAT_STRING(const char *fmt), ...)
  633. PRINTF_ARGS(4, 5);
  634. static int mg_snprintf(struct mg_connection *conn, char *buf, size_t buflen,
  635. const char *fmt, ...) {
  636. va_list ap;
  637. int n;
  638. va_start(ap, fmt);
  639. n = mg_vsnprintf(conn, buf, buflen, fmt, ap);
  640. va_end(ap);
  641. return n;
  642. }
  643. // Skip the characters until one of the delimiters characters found.
  644. // 0-terminate resulting word. Skip the delimiter and following whitespaces.
  645. // Advance pointer to buffer to the next word. Return found 0-terminated word.
  646. // Delimiters can be quoted with quotechar.
  647. static char *skip_quoted(char **buf, const char *delimiters,
  648. const char *whitespace, char quotechar) {
  649. char *p, *begin_word, *end_word, *end_whitespace;
  650. begin_word = *buf;
  651. end_word = begin_word + strcspn(begin_word, delimiters);
  652. // Check for quotechar
  653. if (end_word > begin_word) {
  654. p = end_word - 1;
  655. while (*p == quotechar) {
  656. // If there is anything beyond end_word, copy it
  657. if (*end_word == '\0') {
  658. *p = '\0';
  659. break;
  660. } else {
  661. size_t end_off = strcspn(end_word + 1, delimiters);
  662. memmove (p, end_word, end_off + 1);
  663. p += end_off; // p must correspond to end_word - 1
  664. end_word += end_off + 1;
  665. }
  666. }
  667. for (p++; p < end_word; p++) {
  668. *p = '\0';
  669. }
  670. }
  671. if (*end_word == '\0') {
  672. *buf = end_word;
  673. } else {
  674. end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace);
  675. for (p = end_word; p < end_whitespace; p++) {
  676. *p = '\0';
  677. }
  678. *buf = end_whitespace;
  679. }
  680. return begin_word;
  681. }
  682. // Simplified version of skip_quoted without quote char
  683. // and whitespace == delimiters
  684. static char *skip(char **buf, const char *delimiters) {
  685. return skip_quoted(buf, delimiters, delimiters, 0);
  686. }
  687. // Return HTTP header value, or NULL if not found.
  688. static const char *get_header(const struct mg_request_info *ri,
  689. const char *name) {
  690. int i;
  691. for (i = 0; i < ri->num_headers; i++)
  692. if (!mg_strcasecmp(name, ri->http_headers[i].name))
  693. return ri->http_headers[i].value;
  694. return NULL;
  695. }
  696. const char *mg_get_header(const struct mg_connection *conn, const char *name) {
  697. return get_header(&conn->request_info, name);
  698. }
  699. // A helper function for traversing a comma separated list of values.
  700. // It returns a list pointer shifted to the next value, or NULL if the end
  701. // of the list found.
  702. // Value is stored in val vector. If value has form "x=y", then eq_val
  703. // vector is initialized to point to the "y" part, and val vector length
  704. // is adjusted to point only to "x".
  705. static const char *next_option(const char *list, struct vec *val,
  706. struct vec *eq_val) {
  707. if (list == NULL || *list == '\0') {
  708. // End of the list
  709. list = NULL;
  710. } else {
  711. val->ptr = list;
  712. if ((list = strchr(val->ptr, ',')) != NULL) {
  713. // Comma found. Store length and shift the list ptr
  714. val->len = list - val->ptr;
  715. list++;
  716. } else {
  717. // This value is the last one
  718. list = val->ptr + strlen(val->ptr);
  719. val->len = list - val->ptr;
  720. }
  721. if (eq_val != NULL) {
  722. // Value has form "x=y", adjust pointers and lengths
  723. // so that val points to "x", and eq_val points to "y".
  724. eq_val->len = 0;
  725. eq_val->ptr = (const char *) memchr(val->ptr, '=', val->len);
  726. if (eq_val->ptr != NULL) {
  727. eq_val->ptr++; // Skip over '=' character
  728. eq_val->len = val->ptr + val->len - eq_val->ptr;
  729. val->len = (eq_val->ptr - val->ptr) - 1;
  730. }
  731. }
  732. }
  733. return list;
  734. }
  735. static int match_prefix(const char *pattern, int pattern_len, const char *str) {
  736. const char *or_str;
  737. int i, j, len, res;
  738. if ((or_str = (const char *) memchr(pattern, '|', pattern_len)) != NULL) {
  739. res = match_prefix(pattern, or_str - pattern, str);
  740. return res > 0 ? res :
  741. match_prefix(or_str + 1, (pattern + pattern_len) - (or_str + 1), str);
  742. }
  743. i = j = 0;
  744. res = -1;
  745. for (; i < pattern_len; i++, j++) {
  746. if (pattern[i] == '?' && str[j] != '\0') {
  747. continue;
  748. } else if (pattern[i] == '$') {
  749. return str[j] == '\0' ? j : -1;
  750. } else if (pattern[i] == '*') {
  751. i++;
  752. if (pattern[i] == '*') {
  753. i++;
  754. len = (int) strlen(str + j);
  755. } else {
  756. len = (int) strcspn(str + j, "/");
  757. }
  758. if (i == pattern_len) {
  759. return j + len;
  760. }
  761. do {
  762. res = match_prefix(pattern + i, pattern_len - i, str + j + len);
  763. } while (res == -1 && len-- > 0);
  764. return res == -1 ? -1 : j + res + len;
  765. } else if (pattern[i] != str[j]) {
  766. return -1;
  767. }
  768. }
  769. return j;
  770. }
  771. // HTTP 1.1 assumes keep alive if "Connection:" header is not set
  772. // This function must tolerate situations when connection info is not
  773. // set up, for example if request parsing failed.
  774. static int should_keep_alive(const struct mg_connection *conn) {
  775. const char *http_version = conn->request_info.http_version;
  776. const char *header = mg_get_header(conn, "Connection");
  777. if (conn->must_close ||
  778. conn->status_code == 401 ||
  779. mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
  780. (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
  781. (header == NULL && http_version && strcmp(http_version, "1.1"))) {
  782. return 0;
  783. }
  784. return 1;
  785. }
  786. static const char *suggest_connection_header(const struct mg_connection *conn) {
  787. return should_keep_alive(conn) ? "keep-alive" : "close";
  788. }
  789. static void send_http_error(struct mg_connection *, int, const char *,
  790. PRINTF_FORMAT_STRING(const char *fmt), ...)
  791. PRINTF_ARGS(4, 5);
  792. static void send_http_error(struct mg_connection *conn, int status,
  793. const char *reason, const char *fmt, ...) {
  794. char buf[MG_BUF_LEN];
  795. va_list ap;
  796. int len = 0;
  797. conn->status_code = status;
  798. if (conn->ctx->callbacks.http_error == NULL ||
  799. conn->ctx->callbacks.http_error(conn, status)) {
  800. buf[0] = '\0';
  801. // Errors 1xx, 204 and 304 MUST NOT send a body
  802. if (status > 199 && status != 204 && status != 304) {
  803. len = mg_snprintf(conn, buf, sizeof(buf), "Error %d: %s", status, reason);
  804. buf[len++] = '\n';
  805. va_start(ap, fmt);
  806. len += mg_vsnprintf(conn, buf + len, sizeof(buf) - len, fmt, ap);
  807. va_end(ap);
  808. }
  809. DEBUG_TRACE(("[%s]", buf));
  810. mg_printf(conn, "HTTP/1.1 %d %s\r\n"
  811. "Content-Length: %d\r\n"
  812. "Connection: %s\r\n\r\n", status, reason, len,
  813. suggest_connection_header(conn));
  814. conn->num_bytes_sent += mg_printf(conn, "%s", buf);
  815. }
  816. }
  817. #if defined(_WIN32) && !defined(__SYMBIAN32__)
  818. static int pthread_mutex_init(pthread_mutex_t *mutex, void *unused) {
  819. unused = NULL;
  820. *mutex = CreateMutex(NULL, FALSE, NULL);
  821. return *mutex == NULL ? -1 : 0;
  822. }
  823. static int pthread_mutex_destroy(pthread_mutex_t *mutex) {
  824. return CloseHandle(*mutex) == 0 ? -1 : 0;
  825. }
  826. static int pthread_mutex_lock(pthread_mutex_t *mutex) {
  827. return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1;
  828. }
  829. static int pthread_mutex_unlock(pthread_mutex_t *mutex) {
  830. return ReleaseMutex(*mutex) == 0 ? -1 : 0;
  831. }
  832. static int pthread_cond_init(pthread_cond_t *cv, const void *unused) {
  833. unused = NULL;
  834. cv->signal = CreateEvent(NULL, FALSE, FALSE, NULL);
  835. cv->broadcast = CreateEvent(NULL, TRUE, FALSE, NULL);
  836. return cv->signal != NULL && cv->broadcast != NULL ? 0 : -1;
  837. }
  838. static int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex) {
  839. HANDLE handles[] = {cv->signal, cv->broadcast};
  840. ReleaseMutex(*mutex);
  841. WaitForMultipleObjects(2, handles, FALSE, INFINITE);
  842. return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0? 0 : -1;
  843. }
  844. static int pthread_cond_signal(pthread_cond_t *cv) {
  845. return SetEvent(cv->signal) == 0 ? -1 : 0;
  846. }
  847. static int pthread_cond_broadcast(pthread_cond_t *cv) {
  848. // Implementation with PulseEvent() has race condition, see
  849. // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
  850. return PulseEvent(cv->broadcast) == 0 ? -1 : 0;
  851. }
  852. static int pthread_cond_destroy(pthread_cond_t *cv) {
  853. return CloseHandle(cv->signal) && CloseHandle(cv->broadcast) ? 0 : -1;
  854. }
  855. // For Windows, change all slashes to backslashes in path names.
  856. static void change_slashes_to_backslashes(char *path) {
  857. int i;
  858. for (i = 0; path[i] != '\0'; i++) {
  859. if (path[i] == '/')
  860. path[i] = '\\';
  861. // i > 0 check is to preserve UNC paths, like \\server\file.txt
  862. if (path[i] == '\\' && i > 0)
  863. while (path[i + 1] == '\\' || path[i + 1] == '/')
  864. (void) memmove(path + i + 1,
  865. path + i + 2, strlen(path + i + 1));
  866. }
  867. }
  868. // Encode 'path' which is assumed UTF-8 string, into UNICODE string.
  869. // wbuf and wbuf_len is a target buffer and its length.
  870. static void to_unicode(const char *path, wchar_t *wbuf, size_t wbuf_len) {
  871. char buf[PATH_MAX], buf2[PATH_MAX], *p;
  872. mg_strlcpy(buf, path, sizeof(buf));
  873. change_slashes_to_backslashes(buf);
  874. // Point p to the end of the file name
  875. p = buf + strlen(buf) - 1;
  876. // Convert to Unicode and back. If doubly-converted string does not
  877. // match the original, something is fishy, reject.
  878. memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
  879. MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
  880. WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
  881. NULL, NULL);
  882. if (strcmp(buf, buf2) != 0) {
  883. wbuf[0] = L'\0';
  884. }
  885. }
  886. #if defined(_WIN32_WCE)
  887. static time_t time(time_t *ptime) {
  888. time_t t;
  889. SYSTEMTIME st;
  890. FILETIME ft;
  891. GetSystemTime(&st);
  892. SystemTimeToFileTime(&st, &ft);
  893. t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime);
  894. if (ptime != NULL) {
  895. *ptime = t;
  896. }
  897. return t;
  898. }
  899. static struct tm *localtime(const time_t *ptime, struct tm *ptm) {
  900. int64_t t = ((int64_t) *ptime) * RATE_DIFF + EPOCH_DIFF;
  901. FILETIME ft, lft;
  902. SYSTEMTIME st;
  903. TIME_ZONE_INFORMATION tzinfo;
  904. if (ptm == NULL) {
  905. return NULL;
  906. }
  907. * (int64_t *) &ft = t;
  908. FileTimeToLocalFileTime(&ft, &lft);
  909. FileTimeToSystemTime(&lft, &st);
  910. ptm->tm_year = st.wYear - 1900;
  911. ptm->tm_mon = st.wMonth - 1;
  912. ptm->tm_wday = st.wDayOfWeek;
  913. ptm->tm_mday = st.wDay;
  914. ptm->tm_hour = st.wHour;
  915. ptm->tm_min = st.wMinute;
  916. ptm->tm_sec = st.wSecond;
  917. ptm->tm_yday = 0; // hope nobody uses this
  918. ptm->tm_isdst =
  919. GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0;
  920. return ptm;
  921. }
  922. static struct tm *gmtime(const time_t *ptime, struct tm *ptm) {
  923. // FIXME(lsm): fix this.
  924. return localtime(ptime, ptm);
  925. }
  926. static size_t strftime(char *dst, size_t dst_size, const char *fmt,
  927. const struct tm *tm) {
  928. (void) snprintf(dst, dst_size, "implement strftime() for WinCE");
  929. return 0;
  930. }
  931. #endif
  932. static int mg_rename(const char* oldname, const char* newname) {
  933. wchar_t woldbuf[PATH_MAX];
  934. wchar_t wnewbuf[PATH_MAX];
  935. to_unicode(oldname, woldbuf, ARRAY_SIZE(woldbuf));
  936. to_unicode(newname, wnewbuf, ARRAY_SIZE(wnewbuf));
  937. return MoveFileW(woldbuf, wnewbuf) ? 0 : -1;
  938. }
  939. // Windows happily opens files with some garbage at the end of file name.
  940. // For example, fopen("a.cgi ", "r") on Windows successfully opens
  941. // "a.cgi", despite one would expect an error back.
  942. // This function returns non-0 if path ends with some garbage.
  943. static int path_cannot_disclose_cgi(const char *path) {
  944. static const char *allowed_last_characters = "_-";
  945. int last = path[strlen(path) - 1];
  946. return isalnum(last) || strchr(allowed_last_characters, last) != NULL;
  947. }
  948. static int mg_stat(struct mg_connection *conn, const char *path,
  949. struct file *filep) {
  950. wchar_t wbuf[PATH_MAX];
  951. WIN32_FILE_ATTRIBUTE_DATA info;
  952. if (!is_file_in_memory(conn, path, filep)) {
  953. to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
  954. if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) {
  955. filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh);
  956. filep->modification_time = SYS2UNIX_TIME(
  957. info.ftLastWriteTime.dwLowDateTime,
  958. info.ftLastWriteTime.dwHighDateTime);
  959. filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  960. // If file name is fishy, reset the file structure and return error.
  961. // Note it is important to reset, not just return the error, cause
  962. // functions like is_file_opened() check the struct.
  963. if (!filep->is_directory && !path_cannot_disclose_cgi(path)) {
  964. memset(filep, 0, sizeof(*filep));
  965. }
  966. }
  967. }
  968. return filep->membuf != NULL || filep->modification_time != 0;
  969. }
  970. static int mg_remove(const char *path) {
  971. wchar_t wbuf[PATH_MAX];
  972. to_unicode(path, wbuf, ARRAY_SIZE(wbuf));
  973. return DeleteFileW(wbuf) ? 0 : -1;
  974. }
  975. static int mg_mkdir(const char *path, int mode) {
  976. char buf[PATH_MAX];
  977. wchar_t wbuf[PATH_MAX];
  978. mode = 0; // Unused
  979. mg_strlcpy(buf, path, sizeof(buf));
  980. change_slashes_to_backslashes(buf);
  981. (void) MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, ARRAY_SIZE(wbuf));
  982. return CreateDirectoryW(wbuf, NULL) ? 0 : -1;
  983. }
  984. // Implementation of POSIX opendir/closedir/readdir for Windows.
  985. static DIR * opendir(const char *name) {
  986. DIR *dir = NULL;
  987. wchar_t wpath[PATH_MAX];
  988. DWORD attrs;
  989. if (name == NULL) {
  990. SetLastError(ERROR_BAD_ARGUMENTS);
  991. } else if ((dir = (DIR *) malloc(sizeof(*dir))) == NULL) {
  992. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  993. } else {
  994. to_unicode(name, wpath, ARRAY_SIZE(wpath));
  995. attrs = GetFileAttributesW(wpath);
  996. if (attrs != 0xFFFFFFFF &&
  997. ((attrs & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)) {
  998. (void) wcscat(wpath, L"\\*");
  999. dir->handle = FindFirstFileW(wpath, &dir->info);
  1000. dir->result.d_name[0] = '\0';
  1001. } else {
  1002. free(dir);
  1003. dir = NULL;
  1004. }
  1005. }
  1006. return dir;
  1007. }
  1008. static int closedir(DIR *dir) {
  1009. int result = 0;
  1010. if (dir != NULL) {
  1011. if (dir->handle != INVALID_HANDLE_VALUE)
  1012. result = FindClose(dir->handle) ? 0 : -1;
  1013. free(dir);
  1014. } else {
  1015. result = -1;
  1016. SetLastError(ERROR_BAD_ARGUMENTS);
  1017. }
  1018. return result;
  1019. }
  1020. static struct dirent *readdir(DIR *dir) {
  1021. struct dirent *result = 0;
  1022. if (dir) {
  1023. if (dir->handle != INVALID_HANDLE_VALUE) {
  1024. result = &dir->result;
  1025. (void) WideCharToMultiByte(CP_UTF8, 0,
  1026. dir->info.cFileName, -1, result->d_name,
  1027. sizeof(result->d_name), NULL, NULL);
  1028. if (!FindNextFileW(dir->handle, &dir->info)) {
  1029. (void) FindClose(dir->handle);
  1030. dir->handle = INVALID_HANDLE_VALUE;
  1031. }
  1032. } else {
  1033. SetLastError(ERROR_FILE_NOT_FOUND);
  1034. }
  1035. } else {
  1036. SetLastError(ERROR_BAD_ARGUMENTS);
  1037. }
  1038. return result;
  1039. }
  1040. #ifndef HAVE_POLL
  1041. static int poll(struct pollfd *pfd, int n, int milliseconds) {
  1042. struct timeval tv;
  1043. fd_set set;
  1044. int i, result;
  1045. tv.tv_sec = milliseconds / 1000;
  1046. tv.tv_usec = (milliseconds % 1000) * 1000;
  1047. FD_ZERO(&set);
  1048. for (i = 0; i < n; i++) {
  1049. FD_SET((SOCKET) pfd[i].fd, &set);
  1050. pfd[i].revents = 0;
  1051. }
  1052. if ((result = select(0, &set, NULL, NULL, &tv)) > 0) {
  1053. for (i = 0; i < n; i++) {
  1054. if (FD_ISSET(pfd[i].fd, &set)) {
  1055. pfd[i].revents = POLLIN;
  1056. }
  1057. }
  1058. }
  1059. return result;
  1060. }
  1061. #endif // HAVE_POLL
  1062. #define set_close_on_exec(x) // No FD_CLOEXEC on Windows
  1063. int mg_start_thread(mg_thread_func_t f, void *p) {
  1064. return _beginthread((void (__cdecl *)(void *)) f, 0, p) == -1L ? -1 : 0;
  1065. }
  1066. static HANDLE dlopen(const char *dll_name, int flags) {
  1067. wchar_t wbuf[PATH_MAX];
  1068. flags = 0; // Unused
  1069. to_unicode(dll_name, wbuf, ARRAY_SIZE(wbuf));
  1070. return LoadLibraryW(wbuf);
  1071. }
  1072. #if !defined(NO_CGI)
  1073. #define SIGKILL 0
  1074. static int kill(pid_t pid, int sig_num) {
  1075. (void) TerminateProcess(pid, sig_num);
  1076. (void) CloseHandle(pid);
  1077. return 0;
  1078. }
  1079. static void trim_trailing_whitespaces(char *s) {
  1080. char *e = s + strlen(s) - 1;
  1081. while (e > s && isspace(* (unsigned char *) e)) {
  1082. *e-- = '\0';
  1083. }
  1084. }
  1085. static pid_t spawn_process(struct mg_connection *conn, const char *prog,
  1086. char *envblk, char *envp[], int fd_stdin,
  1087. int fd_stdout, const char *dir) {
  1088. HANDLE me;
  1089. char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
  1090. cmdline[PATH_MAX], buf[PATH_MAX];
  1091. struct file file = STRUCT_FILE_INITIALIZER;
  1092. STARTUPINFOA si = { sizeof(si) };
  1093. PROCESS_INFORMATION pi = { 0 };
  1094. envp = NULL; // Unused
  1095. // TODO(lsm): redirect CGI errors to the error log file
  1096. si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  1097. si.wShowWindow = SW_HIDE;
  1098. me = GetCurrentProcess();
  1099. DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdin), me,
  1100. &si.hStdInput, 0, TRUE, DUPLICATE_SAME_ACCESS);
  1101. DuplicateHandle(me, (HANDLE) _get_osfhandle(fd_stdout), me,
  1102. &si.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);
  1103. // If CGI file is a script, try to read the interpreter line
  1104. interp = conn->ctx->config[CGI_INTERPRETER];
  1105. if (interp == NULL) {
  1106. buf[0] = buf[1] = '\0';
  1107. // Read the first line of the script into the buffer
  1108. snprintf(cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
  1109. if (mg_fopen(conn, cmdline, "r", &file)) {
  1110. p = (char *) file.membuf;
  1111. mg_fgets(buf, sizeof(buf), &file, &p);
  1112. mg_fclose(&file);
  1113. buf[sizeof(buf) - 1] = '\0';
  1114. }
  1115. if (buf[0] == '#' && buf[1] == '!') {
  1116. trim_trailing_whitespaces(buf + 2);
  1117. } else {
  1118. buf[2] = '\0';
  1119. }
  1120. interp = buf + 2;
  1121. }
  1122. if (interp[0] != '\0') {
  1123. GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL);
  1124. interp = full_interp;
  1125. }
  1126. GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL);
  1127. mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%s%s\\%s",
  1128. interp, interp[0] == '\0' ? "" : " ", full_dir, prog);
  1129. DEBUG_TRACE(("Running [%s]", cmdline));
  1130. if (CreateProcessA(NULL, cmdline, NULL, NULL, TRUE,
  1131. CREATE_NEW_PROCESS_GROUP, envblk, NULL, &si, &pi) == 0) {
  1132. cry(conn, "%s: CreateProcess(%s): %d",
  1133. __func__, cmdline, ERRNO);
  1134. pi.hProcess = (pid_t) -1;
  1135. }
  1136. // Always close these to prevent handle leakage.
  1137. (void) close(fd_stdin);
  1138. (void) close(fd_stdout);
  1139. (void) CloseHandle(si.hStdOutput);
  1140. (void) CloseHandle(si.hStdInput);
  1141. (void) CloseHandle(pi.hThread);
  1142. return (pid_t) pi.hProcess;
  1143. }
  1144. #endif // !NO_CGI
  1145. static int set_non_blocking_mode(SOCKET sock) {
  1146. unsigned long on = 1;
  1147. return ioctlsocket(sock, FIONBIO, &on);
  1148. }
  1149. #else
  1150. static int mg_stat(struct mg_connection *conn, const char *path,
  1151. struct file *filep) {
  1152. struct stat st;
  1153. if (!is_file_in_memory(conn, path, filep) && !stat(path, &st)) {
  1154. filep->size = st.st_size;
  1155. filep->modification_time = st.st_mtime;
  1156. filep->is_directory = S_ISDIR(st.st_mode);
  1157. } else {
  1158. filep->modification_time = (time_t) 0;
  1159. }
  1160. return filep->membuf != NULL || filep->modification_time != (time_t) 0;
  1161. }
  1162. static void set_close_on_exec(int fd) {
  1163. fcntl(fd, F_SETFD, FD_CLOEXEC);
  1164. }
  1165. int mg_start_thread(mg_thread_func_t func, void *param) {
  1166. pthread_t thread_id;
  1167. pthread_attr_t attr;
  1168. (void) pthread_attr_init(&attr);
  1169. (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  1170. // TODO(lsm): figure out why mongoose dies on Linux if next line is enabled
  1171. // (void) pthread_attr_setstacksize(&attr, sizeof(struct mg_connection) * 5);
  1172. return pthread_create(&thread_id, &attr, func, param);
  1173. }
  1174. #ifndef NO_CGI
  1175. static pid_t spawn_process(struct mg_connection *conn, const char *prog,
  1176. char *envblk, char *envp[], int fd_stdin,
  1177. int fd_stdout, const char *dir) {
  1178. pid_t pid;
  1179. const char *interp;
  1180. (void) envblk;
  1181. if ((pid = fork()) == -1) {
  1182. // Parent
  1183. send_http_error(conn, 500, http_500_error, "fork(): %s", strerror(ERRNO));
  1184. } else if (pid == 0) {
  1185. // Child
  1186. if (chdir(dir) != 0) {
  1187. cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO));
  1188. } else if (dup2(fd_stdin, 0) == -1) {
  1189. cry(conn, "%s: dup2(%d, 0): %s", __func__, fd_stdin, strerror(ERRNO));
  1190. } else if (dup2(fd_stdout, 1) == -1) {
  1191. cry(conn, "%s: dup2(%d, 1): %s", __func__, fd_stdout, strerror(ERRNO));
  1192. } else {
  1193. (void) dup2(fd_stdout, 2);
  1194. (void) close(fd_stdin);
  1195. (void) close(fd_stdout);
  1196. // After exec, all signal handlers are restored to their default values,
  1197. // with one exception of SIGCHLD. According to POSIX.1-2001 and Linux's
  1198. // implementation, SIGCHLD's handler will leave unchanged after exec
  1199. // if it was set to be ignored. Restore it to default action.
  1200. signal(SIGCHLD, SIG_DFL);
  1201. interp = conn->ctx->config[CGI_INTERPRETER];
  1202. if (interp == NULL) {
  1203. (void) execle(prog, prog, NULL, envp);
  1204. cry(conn, "%s: execle(%s): %s", __func__, prog, strerror(ERRNO));
  1205. } else {
  1206. (void) execle(interp, interp, prog, NULL, envp);
  1207. cry(conn, "%s: execle(%s %s): %s", __func__, interp, prog,
  1208. strerror(ERRNO));
  1209. }
  1210. }
  1211. exit(EXIT_FAILURE);
  1212. }
  1213. // Parent. Close stdio descriptors
  1214. (void) close(fd_stdin);
  1215. (void) close(fd_stdout);
  1216. return pid;
  1217. }
  1218. #endif // !NO_CGI
  1219. static int set_non_blocking_mode(SOCKET sock) {
  1220. int flags;
  1221. flags = fcntl(sock, F_GETFL, 0);
  1222. (void) fcntl(sock, F_SETFL, flags | O_NONBLOCK);
  1223. return 0;
  1224. }
  1225. #endif // _WIN32
  1226. // Write data to the IO channel - opened file descriptor, socket or SSL
  1227. // descriptor. Return number of bytes written.
  1228. static int64_t push(FILE *fp, SOCKET sock, SSL *ssl, const char *buf,
  1229. int64_t len) {
  1230. int64_t sent;
  1231. int n, k;
  1232. sent = 0;
  1233. while (sent < len) {
  1234. // How many bytes we send in this iteration
  1235. k = len - sent > INT_MAX ? INT_MAX : (int) (len - sent);
  1236. #ifndef NO_SSL
  1237. if (ssl != NULL) {
  1238. n = SSL_write(ssl, buf + sent, k);
  1239. } else
  1240. #endif
  1241. if (fp != NULL) {
  1242. n = (int) fwrite(buf + sent, 1, (size_t) k, fp);
  1243. if (ferror(fp))
  1244. n = -1;
  1245. } else {
  1246. n = send(sock, buf + sent, (size_t) k, MSG_NOSIGNAL);
  1247. }
  1248. if (n <= 0)
  1249. break;
  1250. sent += n;
  1251. }
  1252. return sent;
  1253. }
  1254. /*
  1255. char* read_post_data(char *buf)
  1256. {
  1257. int i =0 , count =0 ;
  1258. char *data ; // char data[65536] ; alternate declaration to have more size
  1259. FILE *fp ; fp = fopen("testpd.txt","a");fprintf(fp,"\nbuf->%s\npd-%s",buf,data);
  1260. fclose(fp);
  1261. while (i < strlen (buf))
  1262. {
  1263. if (buf[i] =='\r' && buf[i+1] =='\n' && buf[i+2] =='\r' && buf[i+3] == '\n' )
  1264. {
  1265. i= i+4 ;
  1266. while ( buf[i] != '\r' && buf[i+1]!='\n' )
  1267. {
  1268. data[count] = buf[i] ;
  1269. count++;
  1270. i++;
  1271. }
  1272. data[i] = '\0';
  1273. break ;
  1274. }
  1275. else{i++;}
  1276. }//end while
  1277. // fprintf(fp,"\nbuf->%s\npd-%s",buf,data);fclose(fp);
  1278. return data;
  1279. }*/
  1280. char* read_post_data(char* buf, int len)
  1281. {
  1282. FILE * fp4;
  1283. char *temp;
  1284. temp = malloc(20);
  1285. fp4 = fopen("testpost.txt","w");
  1286. fprintf(fp4,"In the read_post_data %s", buf);
  1287. //fclose(fp4);
  1288. int i=0, j=0;
  1289. /*while(buf[i] != '\r' && buf[i+1]!= '\n' && buf[i+2]!= '\r' && buf[i+3]!= '\n')
  1290. i++;
  1291. i=i+4;
  1292. while(buf[i] != '\r' && buf[i+1]!= '\n')
  1293. {
  1294. temp[j++] = buf[i++];
  1295. }
  1296. temp[j] = '\0';*/
  1297. while (i < strlen (buf))
  1298. {
  1299. if (buf[i] =='\r' && buf[i+1] =='\n' && buf[i+2] =='\r' && buf[i+3] == '\n' )
  1300. {
  1301. i= i+4 ;
  1302. while ( buf[i] != '\r' && buf[i+1]!='\n' )
  1303. {
  1304. temp[j] = buf[i] ;
  1305. j++;
  1306. i++;
  1307. }
  1308. //temp[i] = '\0';
  1309. break ;
  1310. }
  1311. else{i++;}
  1312. }
  1313. fprintf(fp4,"temp: %s", temp);
  1314. fclose(fp4);
  1315. return temp;
  1316. }
  1317. // Read from IO channel - opened file descriptor, socket, or SSL descriptor.
  1318. // Return negative value on error, or number of bytes read on success.
  1319. static int pull(FILE *fp, struct mg_connection *conn, char *buf, int len) {
  1320. int nread;
  1321. const struct mg_request_info *request_info = mg_get_request_info(conn);
  1322. if (fp != NULL) {
  1323. // Use read() instead of fread(), because if we're reading from the CGI
  1324. // pipe, fread() may block until IO buffer is filled up. We cannot afford
  1325. // to block and must pass all read bytes immediately to the client.
  1326. nread = read(fileno(fp), buf, (size_t) len);
  1327. #ifndef NO_SSL
  1328. } else if (conn->ssl != NULL) {
  1329. nread = SSL_read(conn->ssl, buf, len);
  1330. #endif
  1331. } else {
  1332. nread = recv(conn->client.sock, buf, (size_t) len, 0);
  1333. }
  1334. return conn->ctx->stop_flag ? -1 : nread;
  1335. }
  1336. int mg_read(struct mg_connection *conn, void *buf, size_t len) {
  1337. int n, buffered_len, nread;
  1338. const char *body;
  1339. FILE *fp8;
  1340. fp8 = fopen("postdata.txt","a");
  1341. nread = 0;
  1342. if (conn->consumed_content < conn->content_len) {
  1343. // Adjust number of bytes to read.
  1344. int64_t to_read = conn->content_len - conn->consumed_content;
  1345. if (to_read < (int64_t) len) {
  1346. len = (size_t) to_read;
  1347. }
  1348. // Return buffered data
  1349. body = conn->buf + conn->request_len + conn->consumed_content;
  1350. buffered_len = &conn->buf[conn->data_len] - body;
  1351. if (buffered_len > 0) {
  1352. if (len < (size_t) buffered_len) {
  1353. buffered_len = (int) len;
  1354. }
  1355. memcpy(buf, body, (size_t) buffered_len);
  1356. len -= buffered_len;
  1357. conn->consumed_content += buffered_len;
  1358. nread += buffered_len;
  1359. buf = (char *) buf + buffered_len;
  1360. }
  1361. // We have returned all buffered data. Read new data from the remote socket.
  1362. while (len > 0) {
  1363. n = pull(NULL, conn, (char *) buf, (int) len);
  1364. if (n < 0) {
  1365. nread = n; // Propagate the error
  1366. break;
  1367. } else if (n == 0) {
  1368. break; // No more data to read
  1369. } else {
  1370. buf = (char *) buf + n;
  1371. conn->consumed_content += n;
  1372. nread += n;
  1373. len -= n;
  1374. }
  1375. }
  1376. }
  1377. fprintf(fp8, "%s", body);
  1378. fprintf(fp8, "buf: %s", buf);
  1379. fclose(fp8);
  1380. return nread;
  1381. }
  1382. int mg_write(struct mg_connection *conn, const void *buf, size_t len) {
  1383. time_t now;
  1384. int64_t n, total, allowed;
  1385. FILE *fp11;
  1386. fp11 = fopen("mgwrite.txt","a");
  1387. fprintf(fp11," buf: %s",conn->buf );
  1388. fclose(fp11);
  1389. if (conn->throttle > 0) {
  1390. if ((now = time(NULL)) != conn->last_throttle_time) {
  1391. conn->last_throttle_time = now;
  1392. conn->last_throttle_bytes = 0;
  1393. }
  1394. allowed = conn->throttle - conn->last_throttle_bytes;
  1395. if (allowed > (int64_t) len) {
  1396. allowed = len;
  1397. }
  1398. if ((total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
  1399. (int64_t) allowed)) == allowed) {
  1400. buf = (char *) buf + total;
  1401. conn->last_throttle_bytes += total;
  1402. while (total < (int64_t) len && conn->ctx->stop_flag == 0) {
  1403. allowed = conn->throttle > (int64_t) len - total ?
  1404. (int64_t) len - total : conn->throttle;
  1405. if ((n = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
  1406. (int64_t) allowed)) != allowed) {
  1407. break;
  1408. }
  1409. sleep(1);
  1410. conn->last_throttle_bytes = allowed;
  1411. conn->last_throttle_time = time(NULL);
  1412. buf = (char *) buf + n;
  1413. total += n;
  1414. }
  1415. }
  1416. } else {
  1417. total = push(NULL, conn->client.sock, conn->ssl, (const char *) buf,
  1418. (int64_t) len);
  1419. }
  1420. return (int) total;
  1421. }
  1422. // Print message to buffer. If buffer is large enough to hold the message,
  1423. // return buffer. If buffer is to small, allocate large enough buffer on heap,
  1424. // and return allocated buffer.
  1425. static int alloc_vprintf(char **buf, size_t size, const char *fmt, va_list ap) {
  1426. va_list ap_copy;
  1427. int len;
  1428. // Windows is not standard-compliant, and vsnprintf() returns -1 if
  1429. // buffer is too small. Also, older versions of msvcrt.dll do not have
  1430. // _vscprintf(). However, if size is 0, vsnprintf() behaves correctly.
  1431. // Therefore, we make two passes: on first pass, get required message length.
  1432. // On second pass, actually print the message.
  1433. va_copy(ap_copy, ap);
  1434. len = vsnprintf(NULL, 0, fmt, ap_copy);
  1435. if (len > (int) size &&
  1436. (size = len + 1) > 0 &&
  1437. (*buf = (char *) malloc(size)) == NULL) {
  1438. len = -1; // Allocation failed, mark failure
  1439. } else {
  1440. va_copy(ap_copy, ap);
  1441. vsnprintf(*buf, size, fmt, ap_copy);
  1442. }
  1443. return len;
  1444. }
  1445. int mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) {
  1446. char mem[MG_BUF_LEN], *buf = mem;
  1447. int len;
  1448. int i = 0;
  1449. FILE *f9;
  1450. f9 = fopen("mgv.txt","a");
  1451. fprintf(f9,"%s", fmt);
  1452. if ((len = alloc_vprintf(&buf, sizeof(mem), fmt, ap)) > 0) {
  1453. while(i < len)
  1454. {

Large files files are truncated, but you can click here to view the full file