static int start_ss_plugin(const char *plugin, const char *plugin_opts, const char *remote_host, const char *remote_port, const char *local_host, const char *local_port, enum plugin_mode mode) { cork_env_add(env, "SS_REMOTE_HOST", remote_host); cork_env_add(env, "SS_REMOTE_PORT", remote_port); cork_env_add(env, "SS_LOCAL_HOST", local_host); cork_env_add(env, "SS_LOCAL_PORT", local_port); if (plugin_opts != NULL) cork_env_add(env, "SS_PLUGIN_OPTIONS", plugin_opts); #ifdef __ANDROID__ exec = cork_exec_new_with_params("sh", "-c", plugin, NULL); #else exec = cork_exec_new_with_params(plugin, NULL); #endif cork_exec_set_env(exec, env); sub = cork_subprocess_new_exec(exec, NULL, NULL, &exit_code); #ifdef __MINGW32__ cork_subprocess_set_control(sub, sub_control_port); #endif return cork_subprocess_start(sub); }
int start_plugin(const char *plugin, const char *plugin_opts, const char *remote_host, const char *remote_port, const char *local_host, const char *local_port) { char *new_path = NULL; char *cmd = NULL; if (plugin == NULL) return -1; if (strlen(plugin) == 0) return 0; size_t plugin_len = strlen(plugin); size_t cmd_len = plugin_len + CMD_RESRV_LEN; cmd = ss_malloc(cmd_len); snprintf(cmd, cmd_len, "exec %s", plugin); env = cork_env_clone_current(); const char *path = cork_env_get(env, "PATH"); if (path != NULL) { #ifdef __GLIBC__ char *cwd = get_current_dir_name(); if (cwd) { #else char cwd[PATH_MAX]; if (!getcwd(cwd, PATH_MAX)) { #endif size_t path_len = strlen(path) + strlen(cwd) + 2; new_path = ss_malloc(path_len); snprintf(new_path, path_len, "%s:%s", cwd, path); #ifdef __GLIBC__ free(cwd); #endif } } if (new_path != NULL) cork_env_add(env, "PATH", new_path); cork_env_add(env, "SS_REMOTE_HOST", remote_host); cork_env_add(env, "SS_REMOTE_PORT", remote_port); cork_env_add(env, "SS_LOCAL_HOST", local_host); cork_env_add(env, "SS_LOCAL_PORT", local_port); if (plugin_opts != NULL) cork_env_add(env, "SS_PLUGIN_OPTIONS", plugin_opts); exec = cork_exec_new_with_params("sh", "-c", cmd, NULL); cork_exec_set_env(exec, env); sub = cork_subprocess_new_exec(exec, NULL, NULL, &exit_code); int err = cork_subprocess_start(sub); ss_free(cmd); if (new_path != NULL) ss_free(new_path); return err; } uint16_t get_local_port() { int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { return 0; } struct sockaddr_in serv_addr; bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = 0; if (bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { return 0; } socklen_t len = sizeof(serv_addr); if (getsockname(sock, (struct sockaddr *)&serv_addr, &len) == -1) { return 0; } if (close (sock) < 0) { return 0; } return ntohs(serv_addr.sin_port); } void stop_plugin() { if (sub != NULL) { cork_subprocess_abort(sub); cork_subprocess_free(sub); } } int is_plugin_running() { if (sub != NULL) { return cork_subprocess_is_finished(sub); } return 0; }
static int bz_pacman__package(void *user_data) { struct bz_env *env = user_data; struct bz_value *ctx = bz_env_as_value(env); struct cork_path *staging_dir; struct cork_path *binary_package_dir; struct cork_path *package_build_dir; struct cork_path *pkgbuild; struct cork_path *package_file; const char *package_name; const char *version; const char *pkgrel; const char *pkgext; const char *architecture; const char *license; bool verbose; struct cork_env *exec_env; struct cork_exec *exec; struct cork_buffer buf = CORK_BUFFER_INIT(); bool staging_exists; rii_check(bz_install_dependency_string("pacman", ctx)); rii_check(bz_package_message(env, "pacman")); rip_check(package_name = bz_env_get_string(env, "name", true)); clog_info("(%s) Package using pacman", package_name); rip_check(staging_dir = bz_env_get_path(env, "staging_dir", true)); rip_check(binary_package_dir = bz_env_get_path(env, "binary_package_dir", true)); rip_check(package_build_dir = bz_env_get_path(env, "package_build_dir", true)); rip_check(pkgbuild = bz_env_get_path(env, "pacman.pkgbuild", true)); rip_check(package_file = bz_env_get_path(env, "pacman.package_file", true)); rip_check(version = bz_env_get_string(env, "pacman.version", true)); rip_check(pkgrel = bz_env_get_string(env, "pacman.pkgrel", true)); rip_check(pkgext = bz_env_get_string(env, "pacman.pkgext", true)); rip_check(architecture = bz_env_get_string(env, "pacman.arch", true)); rip_check(license = bz_env_get_string(env, "license", true)); rie_check(verbose = bz_env_get_bool(env, "verbose", true)); rii_check(bz_file_exists(cork_path_get(staging_dir), &staging_exists)); if (CORK_UNLIKELY(!staging_exists)) { cork_error_set_printf (ENOENT, "Staging directory %s does not exist", cork_path_get(staging_dir)); return -1; } /* NOTE: pacman runs ldconfig automatically, so unlike the other packagers, * we do NOT need to add an ldconfig call to the post-install and * post-remove scripts. */ /* Create the temporary directory and the packaging destination */ rii_check(bz_create_directory(cork_path_get(package_build_dir), 0750)); rii_check(bz_create_directory(cork_path_get(binary_package_dir), 0750)); /* Create a PKGBUILD file for this package */ cork_buffer_append_printf(&buf, "pkgname='%s'\n", package_name); cork_buffer_append_printf(&buf, "pkgver='%s'\n", version); cork_buffer_append_printf(&buf, "pkgrel='%s'\n", pkgrel); cork_buffer_append_printf(&buf, "arch=('%s')\n", architecture); cork_buffer_append_printf(&buf, "license=('%s')\n", license); rii_check(bz_pacman_fill_deps(env, &buf, "depends", "dependencies")); cork_buffer_append_printf(&buf, "package () {\n" " rm -rf \"${pkgdir}\"\n" " cp -a '%s' \"${pkgdir}\"\n" "}\n", cork_path_get(staging_dir) ); /* Add pre- and post-install scripts, if necessary. */ rii_check(bz_pacman_add_install_scripts(env, &buf)); ei_check(bz_create_file(cork_path_get(pkgbuild), &buf, 0640)); cork_buffer_done(&buf); exec_env = cork_env_clone_current(); cork_env_add(exec_env, "PKGDEST", cork_path_get(binary_package_dir)); cork_env_add(exec_env, "PKGEXT", pkgext); exec = cork_exec_new_with_params("makepkg", "-sf", NULL); cork_exec_set_cwd(exec, cork_path_get(package_build_dir)); cork_exec_set_env(exec, exec_env); clog_info("(%s) Create %s using pacman", package_name, cork_path_get(package_file)); return bz_subprocess_run_exec(verbose, NULL, exec); error: cork_buffer_done(&buf); return -1; }