Example #1
0
static int uwsgi_libssh2_init() {
	char *home = getenv("HOME");

	if (!home) {
		uwsgi_error("uwsgi_libssh2_init()/getenv()");
	}

	if (!ulibssh2.mountpoints && !ulibssh2.username) {
		uwsgi_log("[SSH] you need to specify at least a mountpoint or a username!");
	}

	if (ulibssh2.auth_pw && !ulibssh2.password) {
		uwsgi_log("[SSH] password authentication needs a password!");
		exit(1);
	}

	if (!ulibssh2.private_key_path) {
		ulibssh2.private_key_path = uwsgi_concat2(home, "/.ssh/id_rsa");
	}

	if (!ulibssh2.private_key_passphrase) {
		ulibssh2.private_key_passphrase = "";
	}

	if (!ulibssh2.known_hosts_path) {
		ulibssh2.known_hosts_path = uwsgi_concat2(home, "/.ssh/known_hosts");
	}

	if (!ulibssh2.ssh_timeout) {
		ulibssh2.ssh_timeout = uwsgi.socket_timeout;
	}

	return 0;
}
Example #2
0
static int uwsgi_ssh_routing(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
	// ssh://username[:password]@127.0.0.1:2222/tmp/foo.txt,username[:password]@127.0.0.1:2222/tmp/foobis.txt

	char *remote_url = NULL;

	char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
	uint16_t *subject_len = (uint16_t *)  (((char *)(wsgi_req))+ur->subject_len);
	struct uwsgi_buffer *ub = uwsgi_routing_translate(wsgi_req, ur, *subject, *subject_len, ur->data, ur->data_len);
	if (!ub) {
		uwsgi_error("uwsgi_ssh_routing()/uwsgi_routing_translate()");
		remote_url = ur->data;
	} else {
		remote_url = ub->buf;
	}

	remote_url = uwsgi_concat2(remote_url, ",");
	char *remote_pointer = remote_url;
	char *comma = NULL;
	struct uwsgi_ssh_mountpoint *usm = uwsgi_calloc(sizeof(struct uwsgi_ssh_mountpoint));
	int return_status = -1;

	while ((comma = strchr(remote_url, ',')) != NULL) {
		*comma = 0;

		if (uwsgi_ssh_url_parser(remote_url, &usm)) {
			uwsgi_log("[SSH] skipping malformed route %s\n", remote_url);
			return_status = 500;
			continue;
		}

		if (!(return_status = uwsgi_ssh_request_file(
					wsgi_req,
					usm->path,
					usm
		)))
		{
			goto end;
		} else {
			uwsgi_log("[SSH] route %s to %s returned %d. Engaging fail-over mechanism (if any)...\n",
				usm->remote, usm->path, return_status);
		}

		remote_url = comma + 1;
	}

	switch (return_status) {
		case 404:
			uwsgi_404(wsgi_req);
			break;

		case 500:
		default:
			uwsgi_500(wsgi_req);
	}

end:
	free(remote_pointer);
	uwsgi_buffer_destroy(ub);
	return UWSGI_OK;
}
char *uwsgi_pythonize(char *orig) {

	char *name = uwsgi_concat2(orig, "");
	size_t i;
	size_t len = 0;

	if (!strncmp(name, "sym://", 6)) {
		name+=6;
	}
	else if (!strncmp(name, "http://", 7)) {
		name+=7;
	}
	else if (!strncmp(name, "data://", 7)) {
		name+=7;
	}

	len = strlen(name);
	for(i=0;i<len;i++) {
		if (name[i] == '.') {
			name[i] = '_';
		}
		else if (name[i] == '/') {
			name[i] = '_';
		}
	}


	if ((name[len-3] == '.' || name[len-3] == '_') && name[len-2] == 'p' && name[len-1] == 'y') {
		name[len-3] = 0;
	}

	return name;

}
Example #4
0
File: init.c Project: hfeeki/uwsgi
void uwsgi_autoload_plugins_by_name(char *argv_zero) {

	char *plugins_requested = NULL;

	char *original_proc_name = getenv("UWSGI_ORIGINAL_PROC_NAME");
	if (!original_proc_name) {
		// here we use argv[0];
		original_proc_name = argv_zero;
		setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
	}
	char *p = strrchr(original_proc_name, '/');
	if (p == NULL)
		p = original_proc_name;
	p = strstr(p, "uwsgi_");
	if (p != NULL) {
		plugins_requested = strtok(uwsgi_str(p + 6), "_");
		while (plugins_requested) {
			uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
			uwsgi_load_plugin(-1, plugins_requested, NULL);
			plugins_requested = strtok(NULL, "_");
		}
	}

	plugins_requested = getenv("UWSGI_PLUGINS");
	if (plugins_requested) {
		plugins_requested = uwsgi_concat2(plugins_requested, "");
		char *p = strtok(plugins_requested, ",");
		while (p != NULL) {
			uwsgi_load_plugin(-1, p, NULL);
			p = strtok(NULL, ",");
		}
	}

}
Example #5
0
File: ldap.c Project: AGoodId/uwsgi
void uwsgi_opt_ldap_dump_ldif(char *opt, char *foo, void *bar) {

	int i;
	int items;

	uwsgi_log("\n");
	uwsgi_log("dn: cn=uwsgi,cn=schema,cn=config\n");
	uwsgi_log("objectClass: olcSchemaConfig\n");
	uwsgi_log("cn: uwsgi\n");

	struct uwsgi_ldap_entry *entry, *ule = get_ldap_names(&items);

	for (i = 0; i < items; i++) {

		entry = &ule[i];
		uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.%d NAME (%s", entry->num, entry->names);

		if (entry->has_arg) {
			uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )\n");
		}
		else {
			uwsgi_log(" ) SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");
		}
	}

	uwsgi_log("olcAttributeTypes: ( 1.3.6.1.4.1.35156.17.4.50000 NAME 'uWSGInull' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 )\n");


	uwsgi_log("olcObjectClasses: ( 1.3.6.1.4.1.35156.17.3.1 NAME 'uWSGIConfig' SUP top AUXILIARY DESC 'uWSGI configuration' MAY ( ");


	for (i = 0; i < items; i++) {

		entry = &ule[i];

		char *list2 = uwsgi_concat2(entry->names + 1, "");
		char *p = strtok(list2, " ");
		while (p != NULL) {
			uwsgi_log("%.*s $ ", strlen(p) - 2, p + 1);
			p = strtok(NULL, " ");
		}

		free(list2);

	}

	uwsgi_log("uWSGInull ))\n");

	uwsgi_log("\n");

	exit(0);
}
Example #6
0
/* trying to emulate Graham's mod_wsgi, this will allows easy and fast migrations */
PyObject *uwsgi_file_loader(void *arg1) {

	char *filename = (char *) arg1;
	PyObject *wsgi_file_module, *wsgi_file_dict;
	PyObject *wsgi_file_callable;

	char *callable = up.callable;
	if (!callable) callable = "application";

	char *pythonized_filename = uwsgi_pythonize(filename);
	char *py_filename = uwsgi_concat2("uwsgi_file_", pythonized_filename);
	free(pythonized_filename);

	wsgi_file_module = uwsgi_pyimport_by_filename(py_filename, filename);
	if (!wsgi_file_module) {
		PyErr_Print();
		free(py_filename);
		return NULL;
	}

	wsgi_file_dict = PyModule_GetDict(wsgi_file_module);
	if (!wsgi_file_dict) {
		PyErr_Print();
		Py_DECREF(wsgi_file_module);
		free(py_filename);
		return NULL;
	}

	wsgi_file_callable = PyDict_GetItemString(wsgi_file_dict, callable);
	if (!wsgi_file_callable) {
		PyErr_Print();
		Py_DECREF(wsgi_file_dict);
		Py_DECREF(wsgi_file_module);
                free(py_filename);
		uwsgi_log( "unable to find \"application\" callable in file %s\n", filename);
		return NULL;
	}

	if (!PyFunction_Check(wsgi_file_callable) && !PyCallable_Check(wsgi_file_callable)) {
		uwsgi_log( "\"application\" must be a callable object in file %s\n", filename);
		Py_DECREF(wsgi_file_callable);
		Py_DECREF(wsgi_file_dict);
		Py_DECREF(wsgi_file_module);
                free(py_filename);
		return NULL;
	}

        free(py_filename);

	return wsgi_file_callable;

}
Example #7
0
struct uwsgi_imperial_monitor *imperial_monitor_get_by_scheme(char *arg) {
	struct uwsgi_imperial_monitor *uim = uwsgi.emperor_monitors;
	while (uim) {
		char *scheme = uwsgi_concat2(uim->scheme, "://");
		if (!uwsgi_starts_with(arg, strlen(arg), scheme, strlen(scheme))) {
			free(scheme);
			return uim;
		}
		free(scheme);
		uim = uim->next;
	}
	return NULL;
}
Example #8
0
char *uwsgi_getsockname(int fd) {

	socklen_t socket_type_len = sizeof(struct sockaddr_un);
	union uwsgi_sockaddr usa;
	union uwsgi_sockaddr_ptr gsa;
	char computed_port[6];
	char ipv4a[INET_ADDRSTRLEN + 1];

	gsa.sa = (struct sockaddr *) &usa;

	if (!getsockname(fd, gsa.sa, &socket_type_len)) {
		if (gsa.sa->sa_family == AF_UNIX) {
			if (usa.sa_un.sun_path[0] == 0) {
				return uwsgi_concat2("@", usa.sa_un.sun_path + 1);
			}
			else {
				return uwsgi_str(usa.sa_un.sun_path);
			}
		}
		else {
			memset(ipv4a, 0, INET_ADDRSTRLEN + 1);
			memset(computed_port, 0, 6);
			if (snprintf(computed_port, 6, "%d", ntohs(gsa.sa_in->sin_port)) > 0) {
				if (inet_ntop(AF_INET, (const void *) &gsa.sa_in->sin_addr.s_addr, ipv4a, INET_ADDRSTRLEN)) {
					if (!strcmp("0.0.0.0", ipv4a)) {
						return uwsgi_concat2(":", computed_port);
					}
					else {
						return uwsgi_concat3(ipv4a, ":", computed_port);
					}
				}
			}
		}
	}
	return NULL;
}
Example #9
0
int uwsgi_cr_map_use_cs(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) {
	if (uwsgi.p[ucr->code_string_modifier1]->code_string) {
		char *name = uwsgi_concat2("uwsgi_", ucr->short_name);
		peer->instance_address = uwsgi.p[ucr->code_string_modifier1]->code_string(name, ucr->code_string_code, ucr->code_string_function, peer->key, peer->key_len);
		free(name);
		if (peer->instance_address) {
			peer->instance_address_len = strlen(peer->instance_address);
			char *cs_mod = uwsgi_str_contains(peer->instance_address, peer->instance_address_len, ',');
			if (cs_mod) {
				peer->modifier1 = uwsgi_str_num(cs_mod + 1, (peer->instance_address_len - (cs_mod - peer->instance_address)) - 1);
				peer->instance_address_len = (cs_mod - peer->instance_address);
			}
		}
	}
	return 0;
}
Example #10
0
void uwsgi_opt_ini_paste(char *opt, char *value, void *foobar) {

	uwsgi_opt_load_ini(opt, value, NULL);

	if (value[0] != '/') {
		up.paste = uwsgi_concat4("config:", uwsgi.cwd, "/", value);
	}
	else {
		up.paste = uwsgi_concat2("config:", value);
        }

	if (!strcmp("ini-paste-logged", opt)) {
		up.paste_logger = 1;
	}
	
}
Example #11
0
int uwsgi_cr_map_use_cs(struct uwsgi_corerouter *ucr, struct corerouter_session *cr_session) {
	if (uwsgi.p[ucr->code_string_modifier1]->code_string) {
		char *name = uwsgi_concat2("uwsgi_", ucr->short_name);
		cr_session->instance_address = uwsgi.p[ucr->code_string_modifier1]->code_string(name, ucr->code_string_code, ucr->code_string_function, cr_session->hostname, cr_session->hostname_len);
		free(name);
		if (cr_session->instance_address) {
			cr_session->instance_address_len = strlen(cr_session->instance_address);
			char *cs_mod = uwsgi_str_contains(cr_session->instance_address, cr_session->instance_address_len, ',');
			if (cs_mod) {
				cr_session->modifier1 = uwsgi_str_num(cs_mod + 1, (cr_session->instance_address_len - (cs_mod - cr_session->instance_address)) - 1);
				cr_session->instance_address_len = (cs_mod - cr_session->instance_address);
			}
		}
	}
	return 0;
}
Example #12
0
int uwsgi_ssh_url_parser(char *url, struct uwsgi_ssh_mountpoint **usm) {
	// [ssh://]username[:password]@host:port/path

	if (!url || !(*usm)) {
		return -1;
	}

	if (!memcmp(url, "ssh://", 6)) {
		url += 6;
	}

	// first of all, the remote path
	char *slash = strchr(url, '/');

	if (slash) {
		*slash = 0;
		(*usm)->path = uwsgi_concat2("/", slash + 1);
	} else {
		uwsgi_log("[SSH] malformed ssh url (path)\n");
		return -1;
	}

	// then, the user:password
	char *at = strchr(url, '@');

	if (at) {
		*at = 0;

		char *colon = strchr(url, ':');

		if (colon) {
			*colon = 0;
			(*usm)->password = uwsgi_str(colon + 1);
		} else {
			(*usm)->password = NULL;  // there is no password!
		}
		(*usm)->username = uwsgi_str(url);

		// and eventually, the remote host (ip:port)
		(*usm)->remote = uwsgi_str(at + 1);
	} else {
		(*usm)->remote = uwsgi_str(url);
	}

	return 0;
}
Example #13
0
File: webdav.c Project: JuanS/uwsgi
static int uwsgi_webdav_prop_del(char *filename, char *attr, char *ns) {
        int ret = 0;
#if defined(__linux__) || defined(__APPLE__)
        char *xattr_name = NULL;
        if (ns) {
                xattr_name = uwsgi_concat4("user.uwsgi.webdav.", ns, "|", attr);
        }
        else {
                xattr_name = uwsgi_concat2("user.uwsgi.webdav.", attr);
        }
#if defined(__linux__)
        ret = removexattr(filename, xattr_name);
#elif defined(__APPLE__)
        ret = removexattr(filename, xattr_name, 0);
#endif
        free(xattr_name);
#endif
        return ret;
}
Example #14
0
void uwsgi_python_harakiri(int wid) {

	if (up.tracebacker) {

        	char buf[8192];
		char *address = uwsgi_concat2(up.tracebacker, uwsgi_num2str(wid));

        	int fd = uwsgi_connect(address, -1, 0);
        	for (;;) {
                	int ret = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
                	if (ret <= 0) {
				break;
                	}
                	ssize_t len = read(fd, buf, 8192);
                	if (len <= 0) {
				break;
                	}
                	uwsgi_log("%.*s", (int) len, buf);
        	}

		free(address);
	}

}
Example #15
0
static int uwsgi_ssh_request(struct wsgi_request *wsgi_req) {


#if !defined(UWSGI_PLUGIN_API) || UWSGI_PLUGIN_API == 1
	if (!wsgi_req->uh->pktsize)
#else
	if (!wsgi_req->len)
#endif
	{
		uwsgi_log("[SSH] skipping empty request.\n");
		return -1;
	}

	if (uwsgi_parse_vars(wsgi_req)) {
		uwsgi_error("uwsgi_ssh_request()/uwsgi_parse_vars()");
		return -1;
	}

	if (wsgi_req->path_info_len == 0 ||
		wsgi_req->path_info_len > PATH_MAX ||
		wsgi_req->path_info[wsgi_req->path_info_len - 1] == '/') {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}

	wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, libssh2_plugin.modifier1);

	if (wsgi_req->app_id == -1 && !uwsgi.no_default_app && uwsgi.default_app > -1) {
		if (uwsgi_apps[uwsgi.default_app].modifier1 == libssh2_plugin.modifier1) {
			wsgi_req->app_id = uwsgi.default_app;
		}
	}

	if (wsgi_req->app_id == -1) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];
	struct uwsgi_ssh_mountpoint *usm_list = (struct uwsgi_ssh_mountpoint *) ua->callable;

	char *complete_filepath = NULL;
	char *filepath = NULL;

	if (wsgi_req->path_info_len > ua->mountpoint_len &&
		memcmp(wsgi_req->path_info, ua->mountpoint, ua->mountpoint_len) == 0) {

		filepath = uwsgi_strncopy(
			wsgi_req->path_info + ua->mountpoint_len,
			wsgi_req->path_info_len - ua->mountpoint_len
		);

	} else {
		filepath = uwsgi_strncopy(wsgi_req->path_info, wsgi_req->path_info_len);
	}

	complete_filepath = uwsgi_concat2(usm_list->path, filepath);
	free(filepath);

	int return_status = 500;
	struct uwsgi_ssh_mountpoint *usm = usm_list;

	do {
		return_status = uwsgi_ssh_request_file(
			wsgi_req,
			complete_filepath,
			usm
		);

	} while (return_status == 500 && ((usm = usm->next) != NULL));

	free(complete_filepath);

	switch (return_status) {
		case 404:
			uwsgi_404(wsgi_req);
			break;

		case 500:
		default:
			uwsgi_500(wsgi_req);
	}

	return 0;
}
Example #16
0
PyObject *uwsgi_pyimport_by_filename(char *name, char *filename) {

#ifdef UWSGI_PYPY
	uwsgi_log("import by filename is currently not supported on PyPy !!!\n");
	return NULL;
#else
	FILE *pyfile;
	struct _node *py_file_node = NULL;
	PyObject *py_compiled_node, *py_file_module;
	int is_a_package = 0;
	struct stat pystat;
	char *real_filename = filename;


	if (!uwsgi_check_scheme(filename)) {

		pyfile = fopen(filename, "r");
		if (!pyfile) {
			uwsgi_log("failed to open python file %s\n", filename);
			return NULL;
		}

		if (fstat(fileno(pyfile), &pystat)) {
			uwsgi_error("fstat()");
			return NULL;
		}

		if (S_ISDIR(pystat.st_mode)) {
			is_a_package = 1;
			fclose(pyfile);
			real_filename = uwsgi_concat2(filename, "/__init__.py");
			pyfile = fopen(real_filename, "r");
			if (!pyfile) {
				uwsgi_error_open(real_filename);
				free(real_filename);
				return NULL;
			}
		}

		py_file_node = PyParser_SimpleParseFile(pyfile, real_filename, Py_file_input);
		if (!py_file_node) {
			PyErr_Print();
			uwsgi_log("failed to parse file %s\n", real_filename);
			if (is_a_package)
				free(real_filename);
			fclose(pyfile);
			return NULL;
		}

		fclose(pyfile);
	}
	else {
		int pycontent_size = 0;
		char *pycontent = uwsgi_open_and_read(filename, &pycontent_size, 1, NULL);

		if (pycontent) {
			py_file_node = PyParser_SimpleParseString(pycontent, Py_file_input);
			if (!py_file_node) {
				PyErr_Print();
				uwsgi_log("failed to parse url %s\n", real_filename);
				return NULL;
			}
		}
	}

	py_compiled_node = (PyObject *) PyNode_Compile(py_file_node, real_filename);

	if (!py_compiled_node) {
		PyErr_Print();
		uwsgi_log("failed to compile python file %s\n", real_filename);
		return NULL;
	}

	if (is_a_package) {
		py_file_module = PyImport_AddModule(name);
		if (py_file_module) {
			PyModule_AddObject(py_file_module, "__path__", Py_BuildValue("[O]", PyString_FromString(filename)));
		}
		free(real_filename);
	}

	py_file_module = PyImport_ExecCodeModule(name, py_compiled_node);
	if (!py_file_module) {
		PyErr_Print();
		return NULL;
	}

	Py_DECREF(py_compiled_node);

	return py_file_module;
#endif

}
Example #17
0
File: emperor.c Project: ahua/c
int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {

	int i;
	char *colon = NULL;
	int counter;
	char **uenvs;
	char *uef;
	char **vassal_argv;
	pid_t pid;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe)) {
		uwsgi_error("socketpair()");
		return -1;
	}

	event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);

	if (n_ui->use_config) {
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe_config)) {
			uwsgi_error("socketpair()");
			return -1;
		}
	}

	if (n_ui->zerg) {
		uwsgi.emperor_broodlord_num++;
	}

	// TODO pre-start hook

	// a new uWSGI instance will start 
	pid = fork();
	if (pid < 0) {
		uwsgi_error("fork()")
	}
	else if (pid > 0) {
		n_ui->pid = pid;
		// close the right side of the pipe
		close(n_ui->pipe[1]);
		// close the "on demand" socket
		if (n_ui->on_demand_fd > -1) {
			close(n_ui->on_demand_fd);
			n_ui->on_demand_fd = -1;
		}
		if (n_ui->use_config) {
			close(n_ui->pipe_config[1]);
		}

		if (n_ui->use_config) {
			struct uwsgi_header uh;
			uh.modifier1 = 115;
                	uh.pktsize = n_ui->config_len;
                	uh.modifier2 = 0;
                	if (write(n_ui->pipe_config[0], &uh, 4) != 4) {
                        	uwsgi_error("[uwsgi-emperor] write() header config");
                	}
                	else {
                        	if (write(n_ui->pipe_config[0], n_ui->config, n_ui->config_len) != (long) n_ui->config_len) {
                                	uwsgi_error("[uwsgi-emperor] write() config");
                        	}
                	}

		}
		return 0;
	}
	else {

		if (uwsgi.emperor_tyrant) {
			uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) n_ui->uid, (int) n_ui->gid, n_ui->name);
			if (setgid(n_ui->gid)) {
				uwsgi_error("setgid()");
				exit(1);
			}
			if (setgroups(0, NULL)) {
				uwsgi_error("setgroups()");
				exit(1);
			}

			if (setuid(n_ui->uid)) {
				uwsgi_error("setuid()");
				exit(1);
			}

		}

		unsetenv("UWSGI_RELOADS");
		unsetenv("NOTIFY_SOCKET");

		uef = uwsgi_num2str(n_ui->pipe[1]);
		if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
			uwsgi_error("setenv()");
			exit(1);
		}
		free(uef);

		// add UWSGI_BROODLORD_NUM
		if (n_ui->zerg) {
			uef = uwsgi_num2str(uwsgi.emperor_broodlord_num);
			if (setenv("UWSGI_BROODLORD_NUM", uef, 1)) {
                        	uwsgi_error("setenv()");
                        	exit(1);
                	}
                	free(uef);
		}

		if (n_ui->use_config) {
			uef = uwsgi_num2str(n_ui->pipe_config[1]);
			if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
				uwsgi_error("setenv()");
				exit(1);
			}
			free(uef);
		}

		uenvs = environ;
		while (*uenvs) {
			if (!strncmp(*uenvs, "UWSGI_VASSAL_", 13)) {
				char *ne = uwsgi_concat2("UWSGI_", *uenvs + 13);
				char *oe = uwsgi_concat2n(*uenvs, strchr(*uenvs, '=') - *uenvs, "", 0);
				if (unsetenv(oe)) {
					uwsgi_error("unsetenv()");
					free(oe);
					break;
				}
				free(oe);
#ifdef UWSGI_DEBUG
				uwsgi_log("putenv %s\n", ne);
#endif

				if (putenv(ne)) {
					uwsgi_error("putenv()");
				}
				// do not free ne as putenv will add it to the environ
				uenvs = environ;
				continue;
			}
			uenvs++;
		}

		// close the left side of the pipe
		close(n_ui->pipe[0]);

		if (n_ui->use_config) {
			close(n_ui->pipe_config[0]);
		}

		counter = 4;
		struct uwsgi_string_list *uct = uwsgi.vassals_templates;
		while (uct) {
			counter += 2;
			uct = uct->next;
		}

		vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
		// set args
		vassal_argv[0] = uwsgi.binary_path;

		if (uwsgi.emperor_broodlord) {
			colon = strchr(n_ui->name, ':');
			if (colon) {
				colon[0] = 0;
			}
		}
		// initialize to a default value
		vassal_argv[1] = "--inherit";

		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".xml"))
			vassal_argv[1] = "--xml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".ini"))
			vassal_argv[1] = "--ini";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".yml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".yaml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 3), ".js"))
			vassal_argv[1] = "--json";
		if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".json"))
			vassal_argv[1] = "--json";
	
		struct uwsgi_string_list *usl = uwsgi.emperor_extra_extension;
		while(usl) {
			if (uwsgi_endswith(n_ui->name, usl->value)) {
				vassal_argv[1] = "--config";
				break;
			}
			usl = usl->next;
		}

		if (colon) {
			colon[0] = ':';
		}


		vassal_argv[2] = n_ui->name;
		if (uwsgi.emperor_magic_exec) {
			if (!access(n_ui->name, R_OK | X_OK)) {
				vassal_argv[2] = uwsgi_concat2("exec://", n_ui->name);
			}

		}

		if (n_ui->use_config) {
			vassal_argv[2] = uwsgi_concat2("emperor://", n_ui->name);
		}

		counter = 3;
		uct = uwsgi.vassals_templates;
		while (uct) {
			vassal_argv[counter] = "--inherit";
			vassal_argv[counter + 1] = uct->value;
			counter += 2;
			uct = uct->next;
		}
		vassal_argv[counter] = NULL;

		// disable stdin OR map it to the "on demand" socket
		if (n_ui->on_demand_fd > -1) {
			if (n_ui->on_demand_fd != 0) {
				if (dup2(n_ui->on_demand_fd, 0) < 0) {
                                        uwsgi_error("dup2()");
                                        exit(1);
                                }
                                close(n_ui->on_demand_fd);
			}
		}
		else {
			int stdin_fd = open("/dev/null", O_RDONLY);
			if (stdin_fd < 0) {
				uwsgi_error_open("/dev/null");
				exit(1);
			}
			if (stdin_fd != 0) {
				if (dup2(stdin_fd, 0) < 0) {
					uwsgi_error("dup2()");
					exit(1);
				}
				close(stdin_fd);
			}
		}

		// close all of the unneded fd
		for (i = 3; i < (int) uwsgi.max_fd; i++) {
			if (n_ui->use_config) {
				if (i == n_ui->pipe_config[1])
					continue;
			}
			if (i != n_ui->pipe[1]) {
				close(i);
			}
		}

		if (uwsgi.vassals_start_hook) {
			uwsgi_log("[emperor] running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
			if (uwsgi.emperor_absolute_dir) {
				if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
					uwsgi_error("setenv()");
				}
			}
			int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
			uwsgi_log("[emperor] %s start-hook returned %d\n", n_ui->name, start_hook_ret);
		}

		// start !!!
		if (execvp(vassal_argv[0], vassal_argv)) {
			uwsgi_error("execvp()");
		}
		uwsgi_log("[emperor] is the uwsgi binary in your system PATH ?\n");
		// never here
		exit(UWSGI_EXILE_CODE);
	}

	return -1;
}
Example #18
0
File: lock.c Project: Nikolo/uwsgi
void uwsgi_setup_locking() {

	int i;

	if (uwsgi.locking_setup) return;

	// use the fastest available locking
	if (uwsgi.lock_engine) {
		if (!strcmp(uwsgi.lock_engine, "ipcsem")) {
			uwsgi_log_initial("lock engine: ipcsem\n");
			atexit(uwsgi_ipcsem_clear);
			uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init;
			uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check;
			uwsgi.lock_ops.lock = uwsgi_lock_ipcsem;
			uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem;
			uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init;
			uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check;
			uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem;
			uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem;
			uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
			uwsgi.lock_size = 8;
			uwsgi.rwlock_size = 8;
			goto ready;
		}
		uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
		exit(1);
	}

	uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
#ifdef UWSGI_IPCSEM_ATEXIT
	atexit(uwsgi_ipcsem_clear);
#endif
	uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init;
	uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check;
	uwsgi.lock_ops.lock = uwsgi_lock_fast;
	uwsgi.lock_ops.unlock = uwsgi_unlock_fast;
	uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init;
	uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check;
	uwsgi.lock_ops.rlock = uwsgi_rlock_fast;
	uwsgi.lock_ops.wlock = uwsgi_wlock_fast;
	uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast;
	uwsgi.lock_size = UWSGI_LOCK_SIZE;
	uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE;

ready:
	// application generic lock
	uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
	for (i = 0; i < uwsgi.locks + 1; i++) {
		char *num = uwsgi_num2str(i);
		uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", num));
		free(num);
	}

	// event queue lock (mitigate same event on multiple queues)
	if (uwsgi.threads > 1) {
		pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
	}

	if (uwsgi.master_process) {
		// signal table lock
		uwsgi.signal_table_lock = uwsgi_lock_init("signal");

		// fmon table lock
		uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");

		// timer table lock
		uwsgi.timer_table_lock = uwsgi_lock_init("timer");

		// rb_timer table lock
		uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");

		// cron table lock
		uwsgi.cron_table_lock = uwsgi_lock_init("cron");
	}

	if (uwsgi.use_thunder_lock) {
		// process shared thunder lock
		uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");	
#ifdef UNBIT
		// we have a serious bug on Unbit (and very probably on older libc)
		// when all of the workers die in the same moment the pthread robust mutes is left
		// in inconsistent state and we have no way to recover
		// we span a thread in the master constantly ensuring the lock is ok
		// for now we apply it only for Unbit (where thunder-lock is automatically enabled)
		uwsgi_robust_mutexes_watchdog();		
#endif
	}

	uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");

#ifdef UWSGI_SSL
	// register locking for legions
	struct uwsgi_legion *ul = uwsgi.legions;
	while(ul) {
		ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion));
		ul = ul->next;
	}
#endif
	uwsgi.locking_setup = 1;
}
Example #19
0
void *uwsgi_python_autoreloader_thread(void *foobar) {

	PyObject *modules;

	// block signals on this thread
	sigset_t smask;
        sigfillset(&smask);
#ifndef UWSGI_DEBUG
        sigdelset(&smask, SIGSEGV);
#endif
        pthread_sigmask(SIG_BLOCK, &smask, NULL);

	PyThreadState *pts = PyThreadState_New(up.main_thread->interp);
	pthread_setspecific(up.upt_save_key, (void *) pts);
        pthread_setspecific(up.upt_gil_key, (void *) pts);
	UWSGI_GET_GIL;
	PyObject *threading_module = PyImport_ImportModule("threading");
	if (threading_module) {
		PyObject *threading_module_dict = PyModule_GetDict(threading_module);
                if (threading_module_dict) {
#ifdef PYTHREE
                        PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "current_thread");
#else
                        PyObject *threading_current = PyDict_GetItemString(threading_module_dict, "currentThread");
#endif
                        if (threading_current) {
                                PyObject *current_thread = PyEval_CallObject(threading_current, (PyObject *)NULL);
                                if (!current_thread) {
                                        // ignore the error
                                        PyErr_Clear();
                                }
                                else {
                                        PyObject_SetAttrString(current_thread, "name", PyString_FromString("uWSGIAutoReloader"));
                                        Py_INCREF(current_thread);
					modules = PyImport_GetModuleDict();
					goto cycle;
                                }
                        }
                }

	}
	return NULL;
cycle:
	if (uwsgi.mywid == 1) {
		uwsgi_log("Python auto-reloader enabled\n");
	}
	PyObject *times_dict = PyDict_New();
	char *filename;
	for(;;) {
		UWSGI_RELEASE_GIL;
		sleep(up.auto_reload);
		UWSGI_GET_GIL;
		// do not start monitoring til the first app is loaded (required for lazy mode)
		if (uwsgi_apps_cnt == 0) continue;
#ifdef UWSGI_PYTHON_OLD
                int pos = 0;
#else
                Py_ssize_t pos = 0;
#endif
		PyObject *mod_name, *mod;
                while (PyDict_Next(modules, &pos, &mod_name, &mod)) {
			int found = 0;
			struct uwsgi_string_list *usl = up.auto_reload_ignore;
			while(usl) {
				if (!strcmp(usl->value, PyString_AsString(mod_name))) {
					found = 1;
					break;
				}
				usl = usl->next;
			}
			if (found) continue;
			if (!PyObject_HasAttrString(mod, "__file__")) continue;
			PyObject *mod_file = PyObject_GetAttrString(mod, "__file__");
			if (!mod_file) continue;
#ifdef PYTHREE
			PyObject *zero = PyUnicode_AsUTF8String(mod_file);
			char *mod_filename = PyString_AsString(zero);
#else
			char *mod_filename = PyString_AsString(mod_file);
#endif
			if (!mod_filename) {
#ifdef PYTHREE
				Py_DECREF(zero);
#endif
				continue;
			}
			char *ext = strrchr(mod_filename, '.');
			if (ext && (!strcmp(ext+1, "pyc") || !strcmp(ext+1, "pyd") || !strcmp(ext+1, "pyo"))) {
				filename = uwsgi_concat2n(mod_filename, strlen(mod_filename)-1, "", 0);
			}
			else {
				filename = uwsgi_concat2(mod_filename, "");
			}
			if (uwsgi_check_python_mtime(times_dict, filename)) {
				UWSGI_RELEASE_GIL;
				return NULL;
			}
			free(filename);
#ifdef PYTHREE
			Py_DECREF(zero);
#endif
		}
	}

	return NULL;
}
Example #20
0
void *uwsgi_python_tracebacker_thread(void *foobar) {

	struct iovec iov[9];

	PyObject *new_thread = uwsgi_python_setup_thread("uWSGITraceBacker");
	if (!new_thread) return NULL;

	struct sockaddr_un so_sun;
	socklen_t so_sun_len = 0;

	char *str_wid = uwsgi_num2str(uwsgi.mywid);
	char *sock_path = uwsgi_concat2(up.tracebacker, str_wid);

	int current_defer_accept = uwsgi.no_defer_accept;
        uwsgi.no_defer_accept = 1;
	int fd = bind_to_unix(sock_path, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
        uwsgi.no_defer_accept = current_defer_accept;
	PyObject *threading_module = PyImport_ImportModule("threading");
	if (!threading_module) return NULL;
	//PyObject *threading_dict = PyModule_GetDict(threading_module);

	PyObject *traceback_module = PyImport_ImportModule("traceback");
	if (!traceback_module) return NULL;
	PyObject *traceback_dict = PyModule_GetDict(traceback_module);
	PyObject *extract_stack = PyDict_GetItemString(traceback_dict, "extract_stack");

	PyObject *sys_module = PyImport_ImportModule("sys");
	PyObject *sys_dict = PyModule_GetDict(sys_module);


	PyObject *_current_frames = PyDict_GetItemString(sys_dict, "_current_frames");

	uwsgi_log("python tracebacker for worker %d available on %s\n", uwsgi.mywid, sock_path);
	for(;;) {
		UWSGI_RELEASE_GIL;
		int client_fd = accept(fd, (struct sockaddr *) &so_sun, &so_sun_len);
		if (client_fd < 0) {
			uwsgi_error("accept()");
			UWSGI_GET_GIL;
			continue;
		}
		UWSGI_GET_GIL;
// here is the core of the tracebacker
		PyObject *current_frames = PyEval_CallObject(_current_frames, (PyObject *)NULL);
		if (!current_frames) goto end;
		uwsgi_log("current_frames = %p\n", current_frames);
		PyObject *current_frames_items = PyObject_GetAttrString(current_frames, "items");
		if (!current_frames_items) goto end;
		uwsgi_log("current_frames_items = %p\n", current_frames_items);
		PyObject *frames_ret = PyEval_CallObject(current_frames_items, (PyObject *)NULL);
		if (!frames_ret) goto end;
		uwsgi_log("frames_ret = %p\n", frames_ret);
		PyObject *frames_iter = PyObject_GetIter(frames_ret);
		uwsgi_log("frames_iter = %p\n", frames_iter);
		PyObject *frame = PyIter_Next(frames_iter);
		while(frame) {
			uwsgi_log("frame = %p\n", frame);
			PyObject *stack = PyTuple_GetItem(frame, 1);
			uwsgi_log("stack = %p\n", stack);
			PyObject *arg_tuple = PyTuple_New(1);
			PyTuple_SetItem(arg_tuple, 0, stack);
			PyObject *stacktrace = PyEval_CallObject( extract_stack, arg_tuple);
			uwsgi_log("stacktrace = %p\n", stacktrace);
			PyObject *stacktrace_iter = PyObject_GetIter(stacktrace);
			PyObject *st_items = PyIter_Next(stacktrace_iter);
			while(st_items) {
				uwsgi_log("st_items = %p\n", st_items);
				PyObject *st_filename = PyTuple_GetItem(st_items, 0);
				PyObject *st_lineno = PyTuple_GetItem(st_items, 1);
				PyObject *st_name = PyTuple_GetItem(st_items, 2);
				PyObject *st_line = PyTuple_GetItem(st_items, 3);
				iov[0].iov_base = "filename = ";
				iov[0].iov_len = 11;
				iov[1].iov_base = PyString_AsString(st_filename);
				iov[1].iov_len = strlen(iov[1].iov_base);
				iov[2].iov_base = " lineno = ";
				iov[2].iov_len = 10 ;
				iov[3].iov_base = uwsgi_num2str(PyInt_AsLong(st_lineno));
				iov[3].iov_len = strlen(iov[3].iov_base);
				iov[4].iov_base = " function = ";
				iov[4].iov_len = 12 ;
				iov[5].iov_base = PyString_AsString(st_name);
                                iov[5].iov_len = strlen(iov[5].iov_base);
				iov[6].iov_base = "\n";
				iov[6].iov_len = 1 ;
				if (st_line) {
				}
				if (writev(client_fd, iov, 7) < 0) {
					uwsgi_error("writev()");
				}
				st_items = PyIter_Next(stacktrace_iter);
			}
			frame = PyIter_Next(frames_iter);
		}

	
end:
		close(client_fd);
	}
	return NULL;
}
Example #21
0
void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {

	struct uwsgi_instance *c_ui = ui;
	struct uwsgi_instance *n_ui = NULL;
	pid_t pid;
	char **vassal_argv;
	char *uef;
	char **uenvs;
	int counter;
	char *colon = NULL;
	int i;
	struct timeval tv;

#ifdef UWSGI_DEBUG
	uwsgi_log("\n\nVASSAL %s %d %.*s %d %d\n", name, born, config_size, config, uid, gid);
#endif

	if (strlen(name) > (0xff - 1)) {
		uwsgi_log("[emperor] invalid vassal name\n", name);
		return;
	}


	gettimeofday(&tv, NULL);
	int now = tv.tv_sec;
	uint64_t micros = (tv.tv_sec * 1000 * 1000) + tv.tv_usec;

	// blacklist check
	struct uwsgi_emperor_blacklist_item *uebi = uwsgi_emperor_blacklist_check(name);
	if (uebi) {
		uint64_t i_micros = (uebi->last_attempt.tv_sec * 1000 * 1000) + uebi->last_attempt.tv_usec + uebi->throttle_level;
		if (i_micros > micros) {
			return;
		}
	}

	if (now - emperor_throttle < 1) {
		emperor_throttle_level = emperor_throttle_level * 2;
	}
	else {
		if (emperor_throttle_level > uwsgi.emperor_throttle) {
			emperor_throttle_level = emperor_throttle_level / 2;
		}

		if (emperor_throttle_level < uwsgi.emperor_throttle) {
			emperor_throttle_level = uwsgi.emperor_throttle;
		}
	}

	emperor_throttle = now;
#ifdef UWSGI_DEBUG
	uwsgi_log("emperor throttle = %d\n", emperor_throttle_level);
#endif
	usleep(emperor_throttle_level);

	if (uwsgi.emperor_tyrant) {
		if (uid == 0 || gid == 0) {
			uwsgi_log("[emperor-tyrant] invalid permissions for vassal %s\n", name);
			return;
		}
	}

	while (c_ui->ui_next) {
		c_ui = c_ui->ui_next;
	}

	n_ui = uwsgi_malloc(sizeof(struct uwsgi_instance));
	memset(n_ui, 0, sizeof(struct uwsgi_instance));

	if (config) {
		n_ui->use_config = 1;
		n_ui->config = config;
		n_ui->config_len = config_size;
	}

	c_ui->ui_next = n_ui;
#ifdef UWSGI_DEBUG
	uwsgi_log("c_ui->ui_next = %p\n", c_ui->ui_next);
#endif
	n_ui->ui_prev = c_ui;

	if (strchr(name, ':')) {
		n_ui->zerg = 1;
		uwsgi.emperor_broodlord_count++;
	}

	n_ui->scanner = ues;
	memcpy(n_ui->name, name, strlen(name));
	n_ui->born = born;
	n_ui->uid = uid;
	n_ui->gid = gid;
	n_ui->last_mod = born;
	// start without loyalty
	n_ui->last_loyal = 0;
	n_ui->loyal = 0;

	n_ui->first_run = uwsgi_now();
	n_ui->last_run = n_ui->first_run;

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe)) {
		uwsgi_error("socketpair()");
		goto clear;
	}

	event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);

	if (n_ui->use_config) {
		if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe_config)) {
			uwsgi_error("socketpair()");
			goto clear;
		}
	}

	// TODO pre-start hook

	// a new uWSGI instance will start 
	pid = fork();
	if (pid < 0) {
		uwsgi_error("fork()")
	}
	else if (pid > 0) {
		n_ui->pid = pid;
		// close the right side of the pipe
		close(n_ui->pipe[1]);
		if (n_ui->use_config) {
			close(n_ui->pipe_config[1]);
		}

		if (n_ui->use_config) {
			if (write(n_ui->pipe_config[0], n_ui->config, n_ui->config_len) <= 0) {
				uwsgi_error("write()");
			}
			close(n_ui->pipe_config[0]);
		}
		return;
	}
	else {

		if (uwsgi.emperor_tyrant) {
			uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) uid, (int) gid, name);
			if (setgid(gid)) {
				uwsgi_error("setgid()");
				exit(1);
			}
			if (setgroups(0, NULL)) {
				uwsgi_error("setgroups()");
				exit(1);
			}

			if (setuid(uid)) {
				uwsgi_error("setuid()");
				exit(1);
			}

		}

		unsetenv("UWSGI_RELOADS");
		unsetenv("NOTIFY_SOCKET");

		uef = uwsgi_num2str(n_ui->pipe[1]);
		if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
			uwsgi_error("setenv()");
			exit(1);
		}
		free(uef);

		if (n_ui->use_config) {
			uef = uwsgi_num2str(n_ui->pipe_config[1]);
			if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
				uwsgi_error("setenv()");
				exit(1);
			}
			free(uef);
		}

		uenvs = environ;
		while (*uenvs) {
			if (!strncmp(*uenvs, "UWSGI_VASSAL_", 13)) {
				char *ne = uwsgi_concat2("UWSGI_", *uenvs + 13);
				char *oe = uwsgi_concat2n(*uenvs, strchr(*uenvs, '=') - *uenvs, "", 0);
				if (unsetenv(oe)) {
					uwsgi_error("unsetenv()");
					break;
				}
				free(oe);
#ifdef UWSGI_DEBUG
				uwsgi_log("putenv %s\n", ne);
#endif

				if (putenv(ne)) {
					uwsgi_error("putenv()");
				}
				// do not free ne as putenv will add it to the environ
				uenvs = environ;
				continue;
			}
			uenvs++;
		}

		// close the left side of the pipe
		close(n_ui->pipe[0]);

		if (n_ui->use_config) {
			close(n_ui->pipe_config[0]);
		}

		counter = 4;
		struct uwsgi_string_list *uct = uwsgi.vassals_templates;
		while (uct) {
			counter += 2;
			uct = uct->next;
		}

		vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
		// set args
		vassal_argv[0] = uwsgi.binary_path;

		if (uwsgi.emperor_broodlord) {
			colon = strchr(name, ':');
			if (colon) {
				colon[0] = 0;
			}
		}
		// initialize to a default value
		vassal_argv[1] = "--inherit";

		if (!strcmp(name + (strlen(name) - 4), ".xml"))
			vassal_argv[1] = "--xml";
		if (!strcmp(name + (strlen(name) - 4), ".ini"))
			vassal_argv[1] = "--ini";
		if (!strcmp(name + (strlen(name) - 4), ".yml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(name + (strlen(name) - 5), ".yaml"))
			vassal_argv[1] = "--yaml";
		if (!strcmp(name + (strlen(name) - 3), ".js"))
			vassal_argv[1] = "--json";
		if (!strcmp(name + (strlen(name) - 5), ".json"))
			vassal_argv[1] = "--json";

		if (colon) {
			colon[0] = ':';
		}


		vassal_argv[2] = name;
		if (uwsgi.emperor_magic_exec) {
			if (!access(name, R_OK | X_OK)) {
				vassal_argv[2] = uwsgi_concat2("exec://", name);
			}

		}

		if (n_ui->use_config) {
			vassal_argv[2] = uwsgi_concat2("emperor://", name);
		}

		counter = 3;
		uct = uwsgi.vassals_templates;
		while (uct) {
			vassal_argv[counter] = "--inherit";
			vassal_argv[counter + 1] = uct->value;
			counter += 2;
			uct = uct->next;
		}
		vassal_argv[counter] = NULL;

		// disable stdin
		int stdin_fd = open("/dev/null", O_RDONLY);
		if (stdin_fd < 0) {
			uwsgi_error_open("/dev/null");
			exit(1);
		}
		if (stdin_fd != 0) {
			if (dup2(stdin_fd, 0)) {
				uwsgi_error("dup2()");
				exit(1);
			}
			close(stdin_fd);
		}

		// close all of the unneded fd
		for (i = 3; i < (int) uwsgi.max_fd; i++) {
			if (n_ui->use_config) {
				if (i == n_ui->pipe_config[1])
					continue;
			}
			if (i != n_ui->pipe[1]) {
				close(i);
			}
		}

		if (uwsgi.vassals_start_hook) {
			uwsgi_log("[emperor] running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
			if (uwsgi.emperor_absolute_dir) {
				if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
					uwsgi_error("setenv()");
				}
			}
			int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
			uwsgi_log("[emperor] %s start-hook returned %d\n", n_ui->name, start_hook_ret);
		}

		// start !!!
		if (execvp(vassal_argv[0], vassal_argv)) {
			uwsgi_error("execvp()");
		}
		uwsgi_log("[emperor] is the uwsgi binary in your system PATH ?\n");
		// never here
		exit(UWSGI_EXILE_CODE);
	}

clear:

	free(n_ui);
	c_ui->ui_next = NULL;

}
Example #22
0
File: rados.c Project: Nikolo/uwsgi
static void uwsgi_rados_propfind(struct wsgi_request *wsgi_req, rados_ioctx_t ctx, char *key, uint64_t size, time_t mtime, int timeout) {
	// consume the body
	size_t remains = wsgi_req->post_cl;
        while(remains > 0) {
                ssize_t body_len = 0;
                char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768), &body_len);
                if (!body || body == uwsgi.empty) break;
		remains -= body_len;
	}

	if (uwsgi_response_prepare_headers(wsgi_req, "207 Multi-Status", 16)) return;
	if (uwsgi_response_add_content_type(wsgi_req, "text/xml; charset=\"utf-8\"", 25)) return;
	struct uwsgi_buffer *ub = uwsgi_webdav_multistatus_new();
	if (!ub) return;
	if (key) {
		size_t mime_type_len = 0;
        	char *mime_type = uwsgi_get_mime_type(key, strlen(key), &mime_type_len);
		char *slashed = uwsgi_concat2("/", key);
		if (uwsgi_webdav_propfind_item_add(ub, slashed, strlen(key)+1, size, mtime, mime_type, mime_type_len, NULL, 0, NULL, 0)) {
			free(slashed);
			goto end;
		}
		free(slashed);
		if (uwsgi_webdav_multistatus_close(ub)) goto end;
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		goto end;
	}
	// request for /
	size_t depth = 0;
	uint16_t http_depth_len = 0;
        char *http_depth = uwsgi_get_var(wsgi_req, "HTTP_DEPTH", 10, &http_depth_len);
        if (http_depth) {
                depth = uwsgi_str_num(http_depth, http_depth_len);
        }

	if (depth == 0) {
		if (uwsgi_webdav_propfind_item_add(ub, "/", 1, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
                        goto end;
                }
                if (uwsgi_webdav_multistatus_close(ub)) goto end;
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		goto end;
	}

	struct uwsgi_rados_io *urio = &urados.urio[wsgi_req->async_id];
	rados_list_ctx_t ctx_list;
	if (rados_objects_list_open(ctx, &ctx_list) < 0) {
		goto end;
	}

	char *entry = NULL;
	while(rados_objects_list_next(ctx_list, (const char **)&entry, NULL) == 0) {
		uint64_t stat_size = 0;
		time_t stat_mtime = 0;
		if (uwsgi.async > 0) {
        		if (uwsgi_rados_async_stat(urio, ctx, entry, &stat_size, &stat_mtime, timeout) < 0) goto end;
        	}
        	else {
                	if (rados_stat(ctx, entry, &stat_size, &stat_mtime) < 0) goto end;
        	}

		size_t mime_type_len = 0;
                char *mime_type = uwsgi_get_mime_type(entry, strlen(entry), &mime_type_len);
                char *slashed = uwsgi_concat2("/", entry);
                if (uwsgi_webdav_propfind_item_add(ub, slashed, strlen(entry)+1, stat_size, stat_mtime, mime_type, mime_type_len, NULL, 0, NULL, 0)) {
                        free(slashed);
                        goto end;
                }
                free(slashed);
                if (uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos)) goto end;
		// reset buffer;
		ub->pos = 0;
	}
	rados_objects_list_close(ctx_list);
        if (uwsgi_webdav_multistatus_close(ub)) goto end;
        uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);

end:
	uwsgi_buffer_destroy(ub);
}
Example #23
0
static int uwsgi_hook_print(char *arg) {
	char *line = uwsgi_concat2(arg, "\n");
	uwsgi_log(line);
	free(line);
	return 0;
}
Example #24
0
int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, PerlInterpreter **interpreters) {

	struct stat st;
	int i;
	SV **callables;

	time_t now = uwsgi_now();

	char *app_name = uwsgi_concat2n(app, app_len, "", 0);

	// prepare for $0
	uperl.embedding[1] = app_name;
		
	int fd = open(app_name, O_RDONLY);
	if (fd < 0) {
		uwsgi_error_open(app_name);
		goto clear2;
	}

	if (fstat(fd, &st)) {
		uwsgi_error("fstat()");
		close(fd);
		goto clear2;
	}

	char *buf = uwsgi_calloc(st.st_size+1);
	if (read(fd, buf, st.st_size) != st.st_size) {
		uwsgi_error("read()");
		close(fd);
		free(buf);
		goto clear2;
	}

	close(fd);

	// the first (default) app, should always be loaded in the main interpreter
	if (interpreters == NULL) {
		if (uwsgi_apps_cnt) {
			interpreters = uwsgi_calloc(sizeof(PerlInterpreter *) * uwsgi.threads);
			interpreters[0] = uwsgi_perl_new_interpreter();
			if (!interpreters[0]) {
				uwsgi_log("unable to create new perl interpreter\n");
				free(interpreters);
				goto clear2;
			}
		}
		else {
			interpreters = uperl.main;
		}		
	}

	if (!interpreters) {
		goto clear2;
	}


	callables = uwsgi_calloc(sizeof(SV *) * uwsgi.threads);
	uperl.tmp_streaming_stash = uwsgi_calloc(sizeof(HV *) * uwsgi.threads);
	uperl.tmp_input_stash = uwsgi_calloc(sizeof(HV *) * uwsgi.threads);
	uperl.tmp_error_stash = uwsgi_calloc(sizeof(HV *) * uwsgi.threads);
	uperl.tmp_stream_responder = uwsgi_calloc(sizeof(CV *) * uwsgi.threads);
	uperl.tmp_psgix_logger = uwsgi_calloc(sizeof(CV *) * uwsgi.threads);

	for(i=0;i<uwsgi.threads;i++) {

		if (i > 0 && interpreters != uperl.main) {
		
			interpreters[i] = uwsgi_perl_new_interpreter();
			if (!interpreters[i]) {
				uwsgi_log("unable to create new perl interpreter\n");
				// what to do here ? i hope no-one will use threads with dynamic apps...but clear the whole stuff...
				free(callables);
				uwsgi_perl_free_stashes();
				while(i>=0) {
					perl_destruct(interpreters[i]);	
					perl_free(interpreters[i]);
					goto clear2;
				}
			}
		}

		PERL_SET_CONTEXT(interpreters[i]);

		uperl.tmp_current_i = i;


		if (uperl.locallib) {
                        uwsgi_log("using %s as local::lib directory\n", uperl.locallib);
                        uperl.embedding[1] = uwsgi_concat2("-Mlocal::lib=", uperl.locallib);
                        uperl.embedding[2] = app_name;
                        if (perl_parse(interpreters[i], xs_init, 3, uperl.embedding, NULL)) {
				// what to do here ? i hope no-one will use threads with dynamic apps... but clear the whole stuff...
				free(uperl.embedding[1]);
				uperl.embedding[1] = app_name;
				free(callables);
				uwsgi_perl_free_stashes();
				goto clear;
                        }
			free(uperl.embedding[1]);
			uperl.embedding[1] = app_name;
                }
		else {
			if (perl_parse(interpreters[i], xs_init, 2, uperl.embedding, NULL)) {
				// what to do here ? i hope no-one will use threads with dynamic apps... but clear the whole stuff...
				free(callables);
				uwsgi_perl_free_stashes();
				goto clear;
        		}
		}

		perl_eval_pv("use IO::Handle;", 0);
		perl_eval_pv("use IO::File;", 0);
		perl_eval_pv("use Scalar::Util;", 0);
		if (!uperl.no_die_catch) {
			perl_eval_pv("use Devel::StackTrace;", 0);
			if (!SvTRUE(ERRSV)) {
				uperl.stacktrace_available = 1;
				perl_eval_pv("$SIG{__DIE__} = \\&uwsgi::stacktrace;", 0);
			}
		}

		SV *dollar_zero = get_sv("0", GV_ADD);
		sv_setsv(dollar_zero, newSVpv(app, app_len));

		callables[i] = perl_eval_pv(uwsgi_concat4("#line 1 ", app_name, "\n", buf), 0);
		if (!callables[i]) {
			uwsgi_log("unable to find PSGI function entry point.\n");
			// what to do here ? i hope no-one will use threads with dynamic apps...
			free(callables);
			uwsgi_perl_free_stashes();
                	goto clear;
		}

		PERL_SET_CONTEXT(interpreters[0]);
	}

	free(buf);

	if(SvTRUE(ERRSV)) {
        	uwsgi_log("%s\n", SvPV_nolen(ERRSV));
		free(callables);
		uwsgi_perl_free_stashes();
		goto clear;
        }

	if (uwsgi_apps_cnt >= uwsgi.max_apps) {
		uwsgi_log("ERROR: you cannot load more than %d apps in a worker\n", uwsgi.max_apps);
		goto clear;
	}

	int id = uwsgi_apps_cnt;
	struct uwsgi_app *wi = NULL;

	if (wsgi_req) {
		// we need a copy of app_id
		wi = uwsgi_add_app(id, psgi_plugin.modifier1, uwsgi_concat2n(wsgi_req->appid, wsgi_req->appid_len, "", 0), wsgi_req->appid_len, interpreters, callables);
	}
	else {
		wi = uwsgi_add_app(id, psgi_plugin.modifier1, "", 0, interpreters, callables);
	}

	wi->started_at = now;
	wi->startup_time = uwsgi_now() - now;

        uwsgi_log("PSGI app %d (%s) loaded in %d seconds at %p (interpreter %p)\n", id, app_name, (int) wi->startup_time, callables[0], interpreters[0]);
	free(app_name);

	// copy global data to app-specific areas
	wi->stream = uperl.tmp_streaming_stash;
	wi->input = uperl.tmp_input_stash;
	wi->error = uperl.tmp_error_stash;
	wi->responder0 = uperl.tmp_stream_responder;
	wi->responder1 = uperl.tmp_psgix_logger;

	uwsgi_emulate_cow_for_apps(id);


	// restore context if required
	if (interpreters != uperl.main) {
		PERL_SET_CONTEXT(uperl.main[0]);
	}

	return id;

clear:
	if (interpreters != uperl.main) {
		for(i=0;i<uwsgi.threads;i++) {
			perl_destruct(interpreters[i]);
			perl_free(interpreters[i]);
		}
		free(interpreters);
	}

	PERL_SET_CONTEXT(uperl.main[0]);
clear2:
	free(app_name);
       	return -1; 
}
Example #25
0
static int uwsgi_pypy_init() {

	size_t rlen = 0;
	char *buffer = NULL;

	void *is_cpython_loaded = dlsym(RTLD_DEFAULT, "Py_Initialize");
	if (is_cpython_loaded) {
		uwsgi_log("!!! Loading both PyPy and CPython in the same process IS PURE EVIL AND IT IS NOT SUPPORTED !!!\n");
		exit(1);
	}

	if (dlsym(RTLD_DEFAULT, "rpython_startup_code")) {
		uwsgi_log("PyPy runtime detected, skipping libpypy-c loading\n");
		goto ready;
	}
	else if (upypy.lib) {
		upypy.handler = dlopen(upypy.lib, RTLD_NOW | RTLD_GLOBAL);
	}
	else {
		if (upypy.home) {
#ifdef __CYGWIN__
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dll");
#elif defined(__APPLE__)
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.dylib");
#else
                        char *libpath = uwsgi_concat2(upypy.home, "/libpypy-c.so");
#endif
			if (uwsgi_file_exists(libpath)) {
				upypy.handler = dlopen(libpath, RTLD_NOW | RTLD_GLOBAL);
			}
			free(libpath);
		}
		// fallback to standard library search path
		if (!upypy.handler) {
#ifdef __CYGWIN__
			upypy.handler = dlopen("libpypy-c.dll", RTLD_NOW | RTLD_GLOBAL);
#elif defined(__APPLE__)
			upypy.handler = dlopen("libpypy-c.dylib", RTLD_NOW | RTLD_GLOBAL);
#else
			upypy.handler = dlopen("libpypy-c.so", RTLD_NOW | RTLD_GLOBAL);
#endif
		}
	}

	if (!upypy.handler) {
		uwsgi_log("unable to load pypy library: %s\n", dlerror());
		exit(1);
	}

	u_rpython_startup_code = dlsym(upypy.handler, "rpython_startup_code");
	if (!u_rpython_startup_code) {
		uwsgi_log("unable to find rpython_startup_code() symbol\n");
		exit(1);
	}

	u_pypy_setup_home = dlsym(upypy.handler, "pypy_setup_home");
	if (!u_pypy_setup_home) {
		uwsgi_log("unable to find pypy_setup_home() symbol\n");
		exit(1);
	}

	u_pypy_init_threads = dlsym(upypy.handler, "pypy_init_threads");
        if (!u_pypy_init_threads) {
                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_init_threads, multithreading will not work !!!\n");
        }
	
	u_rpython_startup_code();

	if (!upypy.home) {
		upypy.home = getenv("PYPY_HOME");
		if (!upypy.home) {
			uwsgi_log("you have to specify a pypy home with --pypy-home\n");
			exit(1);
		}
	}

	if (u_pypy_setup_home(upypy.home, 0)) {
		char *retry = uwsgi_concat2(upypy.home, "/lib_pypy");
		if (uwsgi_is_dir(retry)) {
			// this time we use debug
			if (!u_pypy_setup_home(retry, 1)) {
				free(retry);
				goto ready;
			}
		}
                uwsgi_log("unable to set pypy home to \"%s\"\n", upypy.home);
		exit(1);
        }

ready:
	u_pypy_execute_source = dlsym(upypy.handler, "pypy_execute_source");
	if (!u_pypy_execute_source) {
		uwsgi_log("unable to find pypy_execute_source() symbol\n");
		exit(1);
	}

	u_pypy_thread_attach = dlsym(upypy.handler, "pypy_thread_attach");
        if (!u_pypy_thread_attach) {
                uwsgi_log("!!! WARNING your libpypy-c does not export pypy_thread_attach, multithreading will not work !!!\n");
        }

	if (upypy.setup) {
		buffer = uwsgi_open_and_read(upypy.setup, &rlen, 1, NULL);
	}
	else {
		char *start = dlsym(RTLD_DEFAULT, "uwsgi_pypy_setup_start");
		if (!start) {
			start = dlsym(RTLD_DEFAULT, "_uwsgi_pypy_setup_start");
		}
		char *end = dlsym(RTLD_DEFAULT, "uwsgi_pypy_setup_end");
		if (!end) {
			end = dlsym(RTLD_DEFAULT, "_uwsgi_pypy_setup_end");
		}
		if (start && end) {
			buffer = uwsgi_concat2n(start, end-start, "", 0);
		}
	}

	if (!buffer) {
		uwsgi_log("you have to load a pypy setup file with --pypy-setup\n");
		exit(1);
	}
	if (u_pypy_execute_source(buffer)) {
		exit(1);
	}
	free(buffer);

	// add items to the pythonpath
	struct uwsgi_string_list *usl = upypy.pp;
	while(usl) {
		if (uwsgi_pypy_hook_pythonpath) {
			uwsgi_pypy_hook_pythonpath(usl->value);
		}
		usl = usl->next;
	}

	return 0;
}
Example #26
0
void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option) {

	void *plugin_handle = NULL;
	char *plugin_abs_path = NULL;
	char *plugin_filename = NULL;

	int need_free = 0;
	char *plugin_name = uwsgi_strip(uwsgi_str(plugin));
	char *plugin_symbol_name_start = plugin_name;

	struct uwsgi_plugin *up;
	char linkpath_buf[1024], linkpath[1024];
	int linkpath_size;

	char *colon = strchr(plugin_name, ':');
	if (colon) {
		colon[0] = 0;
		modifier = atoi(plugin_name);
		plugin_name = colon + 1;
		colon[0] = ':';
	}

	if (!uwsgi_endswith(plugin_name, "_plugin.so")) {
		plugin_name = uwsgi_concat2(plugin_name, "_plugin.so");
		need_free = 1;
	}

	plugin_symbol_name_start = plugin_name;

	// step 1: check for absolute plugin (stop if it fails)
	if (strchr(plugin_name, '/')) {
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_name);
#endif
		plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
		if (!plugin_handle) {
			if (!has_option)
				uwsgi_log("%s\n", dlerror());
			goto end;
		}
		plugin_symbol_name_start = uwsgi_get_last_char(plugin_name, '/');
		plugin_symbol_name_start++;
		plugin_abs_path = plugin_name;
		goto success;
	}

	// step dir, check for user-supplied plugins directory
	struct uwsgi_string_list *pdir = uwsgi.plugins_dir;
	while (pdir) {
		plugin_filename = uwsgi_concat3(pdir->value, "/", plugin_name);
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_filename);
#endif
		plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
		if (plugin_handle) {
			plugin_abs_path = plugin_filename;
			//free(plugin_filename);
			goto success;
		}
		free(plugin_filename);
		plugin_filename = NULL;
		pdir = pdir->next;
	}

	// last step: search in compile-time plugin_dir
	if (!plugin_handle) {
		plugin_filename = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin_name);
#ifdef UWSGI_ELF
		uwsgi_plugin_parse_section(plugin_filename);
#endif
		plugin_handle = dlopen(plugin_filename, RTLD_NOW | RTLD_GLOBAL);
		plugin_abs_path = plugin_filename;
		//free(plugin_filename);
	}

success:
	if (!plugin_handle) {
		if (!has_option)
			uwsgi_log("!!! UNABLE to load uWSGI plugin: %s !!!\n", dlerror());
	}
	else {
		char *plugin_entry_symbol = uwsgi_concat2n(plugin_symbol_name_start, strlen(plugin_symbol_name_start) - 3, "", 0);
		up = dlsym(plugin_handle, plugin_entry_symbol);
		if (!up) {
			// is it a link ?
			memset(linkpath_buf, 0, 1024);
			memset(linkpath, 0, 1024);
			if ((linkpath_size = readlink(plugin_abs_path, linkpath_buf, 1023)) > 0) {
				do {
					linkpath_buf[linkpath_size] = '\0';
					strncpy(linkpath, linkpath_buf, linkpath_size + 1);
				} while ((linkpath_size = readlink(linkpath, linkpath_buf, 1023)) > 0);
#ifdef UWSGI_DEBUG
				uwsgi_log("%s\n", linkpath);
#endif
				free(plugin_entry_symbol);
				char *slash = uwsgi_get_last_char(linkpath, '/');
				if (!slash) {
					slash = linkpath;
				}
				else {
					slash++;
				}
				plugin_entry_symbol = uwsgi_concat2n(slash, strlen(slash) - 3, "", 0);
				up = dlsym(plugin_handle, plugin_entry_symbol);
			}
		}
		if (up) {
			if (!up->name) {
				uwsgi_log("the loaded plugin (%s) has no .name attribute\n", plugin_name);
				if (dlclose(plugin_handle)) {
					uwsgi_error("dlclose()");
				}
				if (need_free)
					free(plugin_name);
				if (plugin_filename)
					free(plugin_filename);
				free(plugin_entry_symbol);
				return NULL;
			}
			if (plugin_already_loaded(up->name)) {
				if (dlclose(plugin_handle)) {
					uwsgi_error("dlclose()");
				}
				if (need_free)
					free(plugin_name);
				if (plugin_filename)
					free(plugin_filename);
				free(plugin_entry_symbol);
				return NULL;
			}
			if (has_option) {
				struct uwsgi_option *op = up->options;
				int found = 0;
				while (op && op->name) {
					if (!strcmp(has_option, op->name)) {
						found = 1;
						break;
					}
					op++;
				}
				if (!found) {
					if (dlclose(plugin_handle)) {
						uwsgi_error("dlclose()");
					}
					if (need_free)
						free(plugin_name);
					if (plugin_filename)
						free(plugin_filename);
					free(plugin_entry_symbol);
					return NULL;
				}

			}
			if (modifier != -1) {
				fill_plugin_table(modifier, up);
				up->modifier1 = modifier;
			}
			else {
				fill_plugin_table(up->modifier1, up);
			}
			if (need_free)
				free(plugin_name);
			if (plugin_filename)
				free(plugin_filename);
			free(plugin_entry_symbol);

			if (up->on_load)
				up->on_load();
			return plugin_handle;
		}
		if (!has_option)
			uwsgi_log("%s\n", dlerror());
	}

end:
	if (need_free)
		free(plugin_name);
	if (plugin_filename)
		free(plugin_filename);

	return NULL;
}
Example #27
0
void *uwsgi_python_autoreloader_thread(void *foobar) {

	PyObject *new_thread = uwsgi_python_setup_thread("uWSGIAutoReloader");
	if (!new_thread) return NULL;

	PyObject *modules = PyImport_GetModuleDict();

	if (uwsgi.mywid == 1) {
		uwsgi_log("Python auto-reloader enabled\n");
	}

	PyObject *times_dict = PyDict_New();
	char *filename;
	for(;;) {
		UWSGI_RELEASE_GIL;
		sleep(up.auto_reload);
		UWSGI_GET_GIL;
		// do not start monitoring til the first app is loaded (required for lazy mode)
		if (uwsgi_apps_cnt == 0) continue;
#ifdef UWSGI_PYTHON_OLD
                int pos = 0;
#else
                Py_ssize_t pos = 0;
#endif
		PyObject *mod_name, *mod;
                while (PyDict_Next(modules, &pos, &mod_name, &mod)) {
			int found = 0;
			struct uwsgi_string_list *usl = up.auto_reload_ignore;
			while(usl) {
				if (!strcmp(usl->value, PyString_AsString(mod_name))) {
					found = 1;
					break;
				}
				usl = usl->next;
			}
			if (found) continue;
			if (!PyObject_HasAttrString(mod, "__file__")) continue;
			PyObject *mod_file = PyObject_GetAttrString(mod, "__file__");
			if (!mod_file) continue;
#ifdef PYTHREE
			PyObject *zero = PyUnicode_AsUTF8String(mod_file);
			char *mod_filename = PyString_AsString(zero);
#else
			char *mod_filename = PyString_AsString(mod_file);
#endif
			if (!mod_filename) {
#ifdef PYTHREE
				Py_DECREF(zero);
#endif
				continue;
			}
			char *ext = strrchr(mod_filename, '.');
			if (ext && (!strcmp(ext+1, "pyc") || !strcmp(ext+1, "pyd") || !strcmp(ext+1, "pyo"))) {
				filename = uwsgi_concat2n(mod_filename, strlen(mod_filename)-1, "", 0);
			}
			else {
				filename = uwsgi_concat2(mod_filename, "");
			}
			if (uwsgi_check_python_mtime(times_dict, filename)) {
				UWSGI_RELEASE_GIL;
				return NULL;
			}
			free(filename);
#ifdef PYTHREE
			Py_DECREF(zero);
#endif
		}
	}

	return NULL;
}
Example #28
0
File: emperor.c Project: ahua/c
static char *emperor_check_on_demand_socket(char *filename) {
	size_t len = 0;
	if (uwsgi.emperor_on_demand_extension) {
		char *tmp = uwsgi_concat2(filename, uwsgi.emperor_on_demand_extension);
		int fd = open(tmp, O_RDONLY);
		free(tmp);
		if (fd < 0) return NULL;
		char *ret = uwsgi_read_fd(fd, &len, 1);
		close(fd);
		// change the first non prinabel character to 0
		size_t i;
		for(i=0;i<len;i++) {
			if (ret[i] < 32) {
				ret[i] = 0;
				break;
			}
		}
		if (ret[0] == 0) {
			free(ret);
			return NULL;
		}
		return ret;
	}
	else if (uwsgi.emperor_on_demand_directory) {
		// we need to build the socket path automagically
		char *start_of_vassal_name = uwsgi_get_last_char(filename, '/');
		if (!start_of_vassal_name) {
			start_of_vassal_name = filename;
		}
		else {
			start_of_vassal_name++;
		}
		char *last_dot = uwsgi_get_last_char(filename, '.');
		if (!last_dot) return NULL;

		return uwsgi_concat4n(uwsgi.emperor_on_demand_directory, strlen(uwsgi.emperor_on_demand_directory), "/", 1, start_of_vassal_name, last_dot - start_of_vassal_name, ".socket", 7);
	}
	else if (uwsgi.emperor_on_demand_exec) {
		int cpipe[2];
                if (pipe(cpipe)) {
                        uwsgi_error("emperor_check_on_demand_socket()pipe()");
			return NULL;
                }
		char *cmd = uwsgi_concat4(uwsgi.emperor_on_demand_exec, " \"", filename, "\"");
                int r = uwsgi_run_command(cmd, NULL, cpipe[1]);
		free(cmd);
		if (r < 0) {
                	close(cpipe[0]);
                	close(cpipe[1]);
			return NULL;
		}
                char *ret = uwsgi_read_fd(cpipe[0], &len, 1);
                close(cpipe[0]);
                close(cpipe[1]);
		// change the first non prinabel character to 0
                size_t i;
                for(i=0;i<len;i++) {
                        if (ret[i] < 32) {
                                ret[i] = 0;
                                break;
                        }
                }
		if (ret[0] == 0) {
			free(ret);
			return NULL;
		}
		return ret;
	}
	return NULL;
}
Example #29
0
void uwsgi_setup_locking() {

	int i;

	if (uwsgi.locking_setup) return;

	// use the fastest available locking
	if (uwsgi.lock_engine) {
		if (!strcmp(uwsgi.lock_engine, "ipcsem")) {
			uwsgi_log_initial("lock engine: ipcsem\n");
			atexit(uwsgi_ipcsem_clear);
			uwsgi.lock_ops.lock_init = uwsgi_lock_ipcsem_init;
			uwsgi.lock_ops.lock_check = uwsgi_lock_ipcsem_check;
			uwsgi.lock_ops.lock = uwsgi_lock_ipcsem;
			uwsgi.lock_ops.unlock = uwsgi_unlock_ipcsem;
			uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_ipcsem_init;
			uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_ipcsem_check;
			uwsgi.lock_ops.rlock = uwsgi_rlock_ipcsem;
			uwsgi.lock_ops.wlock = uwsgi_wlock_ipcsem;
			uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
			uwsgi.lock_size = 8;
			uwsgi.rwlock_size = 8;
			goto ready;
		}
		uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
		exit(1);
	}

	uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
#ifdef UWSGI_IPCSEM_ATEXIT
	atexit(uwsgi_ipcsem_clear);
#endif
	uwsgi.lock_ops.lock_init = uwsgi_lock_fast_init;
	uwsgi.lock_ops.lock_check = uwsgi_lock_fast_check;
	uwsgi.lock_ops.lock = uwsgi_lock_fast;
	uwsgi.lock_ops.unlock = uwsgi_unlock_fast;
	uwsgi.lock_ops.rwlock_init = uwsgi_rwlock_fast_init;
	uwsgi.lock_ops.rwlock_check = uwsgi_rwlock_fast_check;
	uwsgi.lock_ops.rlock = uwsgi_rlock_fast;
	uwsgi.lock_ops.wlock = uwsgi_wlock_fast;
	uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_fast;
	uwsgi.lock_size = UWSGI_LOCK_SIZE;
	uwsgi.rwlock_size = UWSGI_RWLOCK_SIZE;

ready:
	// application generic lock
	uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
	for (i = 0; i < uwsgi.locks + 1; i++) {
		uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
	}

	// event queue lock (mitigate same event on multiple queues)
	if (uwsgi.threads > 1) {
		pthread_mutex_init(&uwsgi.thunder_mutex, NULL);
	}

	if (uwsgi.master_process) {
		// signal table lock
		uwsgi.signal_table_lock = uwsgi_lock_init("signal");

		// fmon table lock
		uwsgi.fmon_table_lock = uwsgi_lock_init("filemon");

		// timer table lock
		uwsgi.timer_table_lock = uwsgi_lock_init("timer");

		// rb_timer table lock
		uwsgi.rb_timer_table_lock = uwsgi_lock_init("rbtimer");

		// cron table lock
		uwsgi.cron_table_lock = uwsgi_lock_init("cron");
	}

	if (uwsgi.use_thunder_lock) {
		// process shared thunder lock
		uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");	
	}

	uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");

#ifdef UWSGI_SSL
	// register locking for legions
	struct uwsgi_legion *ul = uwsgi.legions;
	while(ul) {
		ul->lock = uwsgi_lock_init(uwsgi_concat2("legion_", ul->legion));
		ul = ul->next;
	}
#endif
	uwsgi.locking_setup = 1;
}
char *uwsgi_format_airbrake_backtrace(struct uwsgi_thread *ut) {

	struct uwsgi_airbrake_config *uacc = (struct uwsgi_airbrake_config *) ut->data;

	xmlChar *xmlbuff;
	int buffersize;
	xmlDocPtr doc = NULL;
	xmlNodePtr notice_node = NULL, node = NULL, line_node = NULL, errnode = NULL;
	char *msg = NULL;

	doc = xmlNewDoc(BAD_CAST "1.0");
	notice_node = xmlNewNode(NULL, BAD_CAST "notice");
	xmlNewProp(notice_node, BAD_CAST "version", BAD_CAST "2.3");
	xmlDocSetRootElement(doc, notice_node);

	xmlNewChild(notice_node, NULL, BAD_CAST "api-key", BAD_CAST uacc->apikey);

	node = xmlNewChild(notice_node, NULL, BAD_CAST "notifier", NULL);
	xmlNewChild(node, NULL, BAD_CAST "name", BAD_CAST "uWSGI");
	xmlNewChild(node, NULL, BAD_CAST "version", BAD_CAST UWSGI_VERSION);
	xmlNewChild(node, NULL, BAD_CAST "url", BAD_CAST "https://github.com/unbit/uwsgi");

	// request env
	node = xmlNewChild(notice_node, NULL, BAD_CAST "request", NULL);
	node = xmlNewChild(node, NULL, BAD_CAST "cgi-data", NULL);

	line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST UWSGI_VERSION);
	xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "uwsgi_version");

	line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST __VERSION__);
	xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "compiled_with_version");

	struct utsname uuts;
#ifdef __sun__
	if (uname(&uuts) < 0) {
#else
	if (uname(&uuts)) {
#endif
		uwsgi_error("uname()");
	}
	else {
		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.sysname);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "os_sysname");

		char *os_version = uwsgi_concat3(uuts.release, "-", uuts.version);
		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST os_version);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "os_version");
		free(os_version);

		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.machine);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "machine");

		line_node = xmlNewChild(node, NULL, BAD_CAST "var", BAD_CAST uuts.nodename);
		xmlNewProp(line_node, BAD_CAST "key", BAD_CAST "nodename");

	}
	// end request env

	node = xmlNewChild(notice_node, NULL, BAD_CAST "server-environment", NULL);
	xmlNewChild(node, NULL, BAD_CAST "app-version", BAD_CAST UWSGI_VERSION);
	if (uacc->env) {
		xmlNewChild(node, NULL, BAD_CAST "environment-name", BAD_CAST uacc->env);
	}
	else {
		xmlNewChild(node, NULL, BAD_CAST "environment-name", BAD_CAST UWSGI_VERSION);
	}

	errnode = xmlNewChild(notice_node, NULL, BAD_CAST "error", NULL);
	xmlNewChild(errnode, NULL, BAD_CAST "class", BAD_CAST "RuntimeError");
	node = xmlNewChild(errnode, NULL, BAD_CAST "backtrace", NULL);

	char *ctx = NULL;
	char *text = uwsgi_str(ut->buf);
	char *p = strtok_r(text, "\n", &ctx);
	while (p) {
		// skip log messages
		if (!uwsgi_startswith(p, "***", 3))
			goto next;
		// backtrace line looks like this: uwsgi(simple_loop_run+0xc5) [0x451555]
		// we take binary/lib as filename
		// and extract method name from remaining string
		char *n = strchr(p, '(');
		if (n) {
			*n = 0;

			char *pls = strchr(n+1, '+');
			if (pls) {
				*pls = 0;
			}

			if (!strcmp("uwsgi_backtrace", n+1) || !strcmp("what_i_am_doing", n+1)) {
				goto next;
			}
			else if (!strcmp("uwsgi_fpe", n+1)) {
				msg = uwsgi_concat4("uWSGI FPE at ", n+1, " in ", p);
				goto next;
			}

			if (!msg) {
				if (strlen(n+1)) {
					msg = uwsgi_concat4("uWSGI segfault at ", n+1, " in ", p);
				}
				else {
					// method name might be missing
					msg = uwsgi_concat2("uWSGI segfault in ", p);
				}
			}

			// skip empty lines
			if (!p)
				goto next;

			line_node = xmlNewChild(node, NULL, BAD_CAST "line", NULL);

			if ((n+1)[0] == ')') {
				xmlNewProp(line_node, BAD_CAST "method", BAD_CAST "()");
			}
			else {
				xmlNewProp(line_node, BAD_CAST "method", BAD_CAST n+1);
			}

			xmlNewProp(line_node, BAD_CAST "file", BAD_CAST p);

			//xmlNewProp(line_node, BAD_CAST "number", BAD_CAST "0");
		}
next:
		p = strtok_r(NULL, "\n", &ctx);
	}

	xmlNewChild(errnode, NULL, BAD_CAST "message", BAD_CAST msg);

	xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);

	xmlFreeDoc(doc);
	xmlCleanupParser();
	xmlMemoryDump();
	free(msg);
	free(text);

	return (char *) xmlbuff;
}


static void uwsgi_airbrake_loop(struct uwsgi_thread *ut) {
	int interesting_fd;
	ut->buf = uwsgi_malloc(uwsgi.log_master_bufsize);

	CURL *curl = curl_easy_init();
	// ARGH !!!
	if (!curl) return;

	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]);
	curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL);
	curl_easy_setopt(curl, CURLOPT_READDATA, ut);
	curl_easy_setopt(curl, CURLOPT_POST, 1L);
	struct curl_slist *expect = NULL; expect = curl_slist_append(expect, "Expect:");
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);

	struct uwsgi_airbrake_config *uacc = (struct uwsgi_airbrake_config *) ut->data;
	char *opts = uwsgi_str(uacc->arg);

	// fill curl options
	char *ctx = NULL;
	char *p = strtok_r(opts, ";", &ctx);
	while(p) {
		uwsgi_airbrake_setopt(curl, uwsgi_str(p), uacc);
		p = strtok_r(NULL, ";", &ctx);
	}

	for(;;) {
		int ret = event_queue_wait(ut->queue, -1, &interesting_fd);
		if (ret < 0) return;
		if (ret == 0) continue;
		if (interesting_fd != ut->pipe[1]) continue;
		ssize_t rlen = read(ut->pipe[1], ut->buf, uwsgi.log_master_bufsize);
		if (rlen <= 0) continue;
		ut->pos = 0;
		ut->len = (size_t) rlen;
		ut->custom0 = 0;

		char *notice = uwsgi_format_airbrake_backtrace(ut);

		curl_slist_append(expect, "Accept: */*");
		curl_slist_append(expect, "Content-Type: text/xml; charset=utf-8");
		curl_easy_setopt(curl, CURLOPT_HTTPHEADER, expect);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, notice);
		curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(notice));

		curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) ut->len);
		CURLcode res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			uwsgi_log_alarm("-curl] curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
		}
		free(notice);
	}
}