// Use the global passwords file, if specified by auth_gpass option, // or search for .htpasswd in the requested directory. static FILE *open_auth_file(struct mg_connection *conn, const char *path) { char name[PATH_MAX]; const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE]; struct file file = STRUCT_FILE_INITIALIZER; FILE *fp = NULL; if (gpass != NULL) { // Use global passwords file fp = mg_fopen(gpass, "r"); // Important: using local struct file to test path for is_directory flag. // If filep is used, mg_stat() makes it appear as if auth file was opened. } else if (mg_stat(path, &file) && file.is_directory) { mg_snprintf(name, sizeof(name), "%s%c%s", path, '/', PASSWORDS_FILE_NAME); fp = mg_fopen(name, "r"); } else { // Try to find .htpasswd in requested directory. for (p = path, e = p + strlen(p) - 1; e > p; e--) if (e[0] == '/') break; mg_snprintf(name, sizeof(name), "%.*s%c%s", (int) (e - p), p, '/', PASSWORDS_FILE_NAME); fp = mg_fopen(name, "r"); } return fp; }
static int handle_lsp_request(struct mg_connection *conn, const char *path, struct file *filep, struct lua_State *ls) { void *p = NULL; lua_State *L = NULL; FILE *fp = NULL; int error = 1; // We need both mg_stat to get file size, and mg_fopen to get fd if (!mg_stat(path, filep) || (fp = mg_fopen(path, "r")) == NULL) { lsp_send_err(conn, ls, "File [%s] not found", path); } else if ((p = mmap(NULL, (size_t) filep->size, PROT_READ, MAP_PRIVATE, fileno(fp), 0)) == MAP_FAILED) { lsp_send_err(conn, ls, "mmap(%s, %zu, %d): %s", path, (size_t) filep->size, fileno(fp), strerror(errno)); } else if ((L = ls != NULL ? ls : luaL_newstate()) == NULL) { send_http_error(conn, 500, http_500_error, "%s", "luaL_newstate failed"); } else { // We're not sending HTTP headers here, Lua page must do it. if (ls == NULL) { prepare_lua_environment(conn, L); } error = lsp(conn, path, p, filep->size, L); } if (L != NULL && ls == NULL) lua_close(L); if (p != NULL) munmap(p, filep->size); fclose(fp); return error; }
static void edit_config_file(struct mg_context *ctx) { const char **names, *value; FILE *fp; int i; char cmd[200]; // Create config file if it is not present yet if ((fp = mg_fopen(config_file, "r")) != NULL) { mg_fclose(fp); } else if ((fp = fopen(config_file, "a+")) != NULL) { fprintf(fp, "# Mongoose web server configuration file.\n" "# Lines starting with '#' and empty lines are ignored.\n" "# For detailed description of every option, visit\n" "# http://code.google.com/p/mongoose/wiki/MongooseManual\n\n"); names = mg_get_valid_option_names(); for (i = 0; names[i] != NULL; i += MG_ENTRIES_PER_CONFIG_OPTION) { value = mg_get_option(ctx, names[i + 1]); fprintf(fp, "# %s %s\n", names[i + 1], *value ? value : "<value>"); } mg_fclose(fp); } snprintf(cmd, sizeof(cmd), "notepad.exe %s", config_file); WinExec(cmd, SW_SHOW); }
// Return 1 if request is authorised, 0 otherwise. static int check_authorization(struct mg_connection *conn, const char *path) { char fname[PATH_MAX]; struct vec uri_vec, filename_vec; const char *list; FILE *fp = NULL; int authorized = 1; list = conn->ctx->config[PROTECT_URI]; while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) { if (!memcmp(conn->request_info.uri, uri_vec.ptr, uri_vec.len)) { mg_snprintf(fname, sizeof(fname), "%.*s", (int) filename_vec.len, filename_vec.ptr); fp = mg_fopen(fname, "r"); break; } } if (fp == NULL) { fp = open_auth_file(conn, path); } if (fp != NULL) { authorized = authorize(conn, fp); fclose(fp); } return authorized; }
REPLACE_STATIC void handle_lsp_request(struct mg_connection *conn, const char *path, struct file *filep) { void *p = NULL; lua_State *L = NULL; if (!mg_fopen(conn, path, "r", filep)) { send_http_error(conn, 404, "Not Found", "%s", "File not found"); } else if (filep->membuf == NULL && (p = mmap(NULL, filep->size, PROT_READ, MAP_PRIVATE, fileno(filep->fp), 0)) == MAP_FAILED) { send_http_error(conn, 500, http_500_error, "%s", "x"); } else if ((L = luaL_newstate()) == NULL) { send_http_error(conn, 500, http_500_error, "%s", "y"); } else { mg_printf(conn, "%s", "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\nConnection: close\r\n\r\n"); prepare_lua_environment(conn, L); conn->request_info.ev_data = L; call_user(conn, MG_INIT_LUA); lsp(conn, filep->membuf == NULL ? p : filep->membuf, filep->size, L); } if (L) lua_close(L); if (p) munmap(p, filep->size); mg_fclose(filep); }
static int is_authorized_for_put(struct mg_connection *conn) { const char *passfile = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE]; FILE *fp; int ret = 0; if (passfile != NULL && (fp = mg_fopen(passfile, "r")) != NULL) { ret = authorize(conn, fp); fclose(fp); } return ret; }
void mg_hexdump_connection(struct mg_connection *nc, const char *path, const void *buf, int num_bytes, int ev) { FILE *fp = NULL; char src[60], dst[60]; const char *tag = NULL; switch (ev) { case MG_EV_RECV: tag = "<-"; break; case MG_EV_SEND: tag = "->"; break; case MG_EV_ACCEPT: tag = "<A"; break; case MG_EV_CONNECT: tag = "C>"; break; case MG_EV_CLOSE: tag = "XX"; break; } if (tag == NULL) return; /* Don't log MG_EV_TIMER, etc */ if (strcmp(path, "-") == 0) { fp = stdout; } else if (strcmp(path, "--") == 0) { fp = stderr; #if MG_ENABLE_FILESYSTEM } else { fp = mg_fopen(path, "a"); #endif } if (fp == NULL) return; mg_conn_addr_to_str(nc, src, sizeof(src), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT); mg_conn_addr_to_str(nc, dst, sizeof(dst), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT | MG_SOCK_STRINGIFY_REMOTE); fprintf(fp, "%lu %p %s %s %s %d\n", (unsigned long) mg_time(), (void *) nc, src, tag, dst, (int) num_bytes); if (num_bytes > 0) { mg_hexdumpf(fp, buf, num_bytes); } if (fp != stdout && fp != stderr) fclose(fp); }
static void process_command_line_arguments(char *argv[], char **options) { char line[MAX_CONF_FILE_LINE_SIZE], opt[sizeof(line)], val[sizeof(line)], *p; FILE *fp = NULL; size_t i; int cmd_line_opts_start = 1; int line_no = 0; options[0] = NULL; // Should we use a config file ? if (argv[1] != NULL && argv[2] == NULL) { snprintf(config_file, sizeof(config_file), "%s", argv[1]); cmd_line_opts_start = 2; } else if ((p = strrchr(argv[0], DIRSEP)) == NULL) { // No command line flags specified. Look where binary lives snprintf(config_file, sizeof(config_file), "%s", CONFIG_FILE); } else { snprintf(config_file, sizeof(config_file), "%.*s%c%s", (int) (p - argv[0]), argv[0], DIRSEP, CONFIG_FILE); } fp = mg_fopen(config_file, "r"); // If config file was set in command line and open failed, exit if (argv[1] != NULL && argv[2] == NULL && fp == NULL) { die("Cannot open config file %s: %s", config_file, mg_strerror(ERRNO)); } // use the default values for starters (so that all options have a known reasonable value): for (i = 0; default_options[i]; i += 2) { set_option(options, default_options[i], default_options[i+1]); } // Load config file settings first if (fp != NULL) { fprintf(stderr, "Loading config file %s\n", config_file); // Loop over the lines in config file while (fgets(line, sizeof(line), fp) != NULL) { if (!line_no && !memcmp(line,"\xEF\xBB\xBF", 3)) { // strip UTF-8 BOM p = line+3; } else { p = line; } line_no++; // Ignore empty lines (with optional, ignored, whitespace) and comments if (line[0] == '#') continue; // MS sscanf() says: The return value is EOF for an error or if the end of the string is reached before the first conversion. // Hence we make sure we don't feed it an empty line --> -1 will only have one meaning then. if (line[strspn(line, " \t\r\n")] == 0) continue; if (2 == sscanf(line, "%s %[^\r\n#]", opt, val)) { set_option(options, opt, val); continue; } else { die("%s: line %d is invalid", config_file, line_no); break; } } (void) mg_fclose(fp); } // Handle command line flags. They override config file and default settings. for (i = cmd_line_opts_start; argv[i] != NULL; i += 2) { if (argv[i][0] != '-' || argv[i + 1] == NULL) { show_usage_and_exit(ctx); } set_option(options, &argv[i][1], argv[i + 1]); } }