📄 passthrough.c
字号:
/* create a process and pass the left-over pipe ends to it */#ifndef __MINGW32__ if ((pid = fork ()) == 0) { svz_process_create_child (file, dir, in, out, argv, envp, app); exit (0); } else if (pid == -1) { svz_log (LOG_ERROR, "fork: %s\n", SYS_ERROR); return -1; }#else /* __MINGW32__ */ pid = svz_process_create_child (file, dir, in, out, argv, envp, app); return pid;#endif /* __MINGW32__ */ return 0;}/* * Fork the current process and execute the program @var{file} in the * working directory @var{dir}. Pass the descriptors @var{in} and @var{out} * to stdin and stdout of the child process. Additional arguments to * @var{file} can be passed via the NULL terminated array of strings * @var{argv}. The environment is setup by @var{envp} which can be NULL to * enforce the environment of the parent process. Returns -1 on errors * and the child's process id on success. */intsvz_process_fork (char *file, char *dir, HANDLE in, HANDLE out, char **argv, svz_envblock_t *envp, char *app){#ifdef __MINGW32__ svz_log (LOG_FATAL, "fork() and exec() not supported\n"); return -1;#else /* __MINGW32__ */ int pid; /* The child process here. */ if ((pid = fork ()) == 0) { svz_process_create_child (file, dir, in, out, argv, envp, app); } else if (pid == -1) { svz_log (LOG_ERROR, "fork: %s\n", SYS_ERROR); return -1; } /* The parent process: Destroy the given socket object. */#if ENABLE_DEBUG svz_log (LOG_DEBUG, "process `%s' got pid %d\n", file, pid);#endif return pid;#endif /* __MINGW32__ */}/* * Check if the given binary @var{file} is an executable. If it is script * the routine returns a application able to execute the script in * @var{app}. Return zero on success. */intsvz_process_check_executable (char *file, char **app){ struct stat buf;#ifdef __MINGW32__ char *suffix;#endif /* Check the existence of the file. */ if (stat (file, &buf) < 0) { svz_log (LOG_ERROR, "stat: %s\n", SYS_ERROR); return -1; } *app = NULL;#ifndef __MINGW32__ if (!(buf.st_mode & S_IFREG) || !(buf.st_mode & S_IXUSR) || !(buf.st_mode & S_IRUSR))#else if (!(buf.st_mode & S_IFREG))#endif { svz_log (LOG_ERROR, "no executable: %s\n", file); return -1; }#ifdef __MINGW32__ suffix = file + strlen (file) - 1; while (suffix > file && *suffix != '.') suffix--; if (suffix > file) suffix++; if (!svz_strcasecmp (suffix, "com") || !svz_strcasecmp (suffix, "exe") || !svz_strcasecmp (suffix, "bat")) return 0; *app = svz_malloc (MAX_PATH); if (FindExecutable (file, NULL, *app) <= (HINSTANCE) 32) { svz_log (LOG_ERROR, "FindExecutable: %s\n", SYS_ERROR); svz_free (*app); *app = NULL; return -1; }#endif /* __MINGW32__ */ return 0;}/* * Try setting the process permissions specified by the given executable * file @var{file}. Return zero on success. */intsvz_process_check_access (char *file){ struct stat buf; /* get the executable permissions */ if (stat (file, &buf) == -1) { svz_log (LOG_ERROR, "stat: %s\n", SYS_ERROR); return -1; }#ifndef __MINGW32__ /* set the appropriate user permissions */ if (setgid (buf.st_gid) == -1) { svz_log (LOG_ERROR, "setgid: %s\n", SYS_ERROR); return -1; } if (setuid (buf.st_uid) == -1) { svz_log (LOG_ERROR, "setuid: %s\n", SYS_ERROR); return -1; }#endif /* not __MINGW32__ */ return 0;}/* * Insert a new environment variable into the given environment block * @var{env}. The @var{format} argument is a printf()-style format string * describing how to format the optional arguments. */intsvz_envblock_add (svz_envblock_t *env, char *format, ...){ static char buffer[VSNPRINTF_BUF_SIZE]; int n, len; va_list args; va_start (args, format); svz_vsnprintf (buffer, VSNPRINTF_BUF_SIZE, format, args); va_end (args); /* Check for duplicate entry. */ len = strchr (buffer, '=') - buffer; for (n = 0; n < env->size; n++) if (!memcmp (buffer, env->entry[n], len)) { svz_free (env->entry[n]); env->entry[n] = svz_strdup (buffer); return env->size; } env->size++; env->entry = svz_realloc (env->entry, sizeof (char *) * (env->size + 1)); env->entry[env->size - 1] = svz_strdup (buffer); env->entry[env->size] = NULL; return env->size;}/* * Create a fresh environment block. The returned pointer can be used to pass * it to @code{svz_envblock_default()} and @code{svz_envblock_add()}. Its * size is initially set to zero. */svz_envblock_t *svz_envblock_create (void){ svz_envblock_t *env; env = svz_malloc (sizeof (svz_envblock_t)); memset (env, 0, sizeof (svz_envblock_t)); return env;}/* * Fill the given environment block @var{env} with the current process'es * environment variables. If the environment @var{env} contained any * information before these will be overridden. */intsvz_envblock_default (svz_envblock_t *env){ int n; if (env == NULL) return -1; if (env->size) svz_envblock_free (env); for (n = 0; environ[n] != NULL; n++) { env->size++; env->entry = svz_realloc (env->entry, sizeof (char *) * (env->size + 1)); env->entry[env->size - 1] = svz_strdup (environ[n]); } env->entry[env->size] = NULL; return 0;}#ifdef __MINGW32__/* * Win9x and WinNT systems use sorted environment. That is why we will sort * each environment block passed to @code{CreateProcess()}. The following * routine is the comparison routine for the @code{qsort()} call. */static intsvz_envblock_sort (const void *data1, const void *data2){ char *entry1 = * (char **) data1; char *entry2 = * (char **) data2; return strcmp (entry1, entry2);}#endif /* __MINGW32__ *//* * Unfortunately the layout of environment blocks in Unices and Windows * differ. On Unices you have a NULL terminated array of character strings * and on Windows systems you have a simple character string containing * the environment variables in the format VAR=VALUE each seperated by a * zero byte. The end of the list is indicated by a further zero byte. * The following routine converts the given environment block @var{env} * into something which can be passed to @code{exeve()} (Unix) or * @code{CreateProcess()} (Windows). The routine additionally sort the * environment block on Windows systems since it is using sorted environments. */svz_envp_tsvz_envblock_get (svz_envblock_t *env){ char *dir; int len = 32;#ifdef __MINGW32__ svz_envp_t block = NULL; int n, size;#endif /* Setup the PWD environment variable correctly. */ dir = svz_getcwd (); svz_envblock_add (env, "PWD=%s", dir); svz_free (dir);#ifdef __MINGW32__ if (env->block) svz_free_and_zero (env->block); qsort ((void *) env->entry, env->size, sizeof (char *), svz_envblock_sort); for (size = 1, n = 0; n < env->size; n++) { len = strlen (env->entry[n]) + 1; block = svz_realloc (block, size + len); memcpy (&block[size - 1], env->entry[n], len); size += len; } block[size] = '\0'; env->block = block; return block;#else /* !__MINGW32__ */ return env->entry;#endif /* !__MINGW32__ */}/* * This function releases all environment variables currently stored in the * given enviroment block @var{env}. The block will be as clean as returned * by @code{svz_envblock_create()} afterwards. */intsvz_envblock_free (svz_envblock_t *env){ int n; if (env == NULL) return -1; for (n = 0; n < env->size; n++) svz_free (env->entry[n]); if (env->block) svz_free_and_zero (env->block); svz_free_and_zero (env->entry); env->size = 0; return 0;}/* * Destroys the given environment block @var{env} completely. The @var{env} * argument is invalid afterwards and should therefore not be referenced then. */voidsvz_envblock_destroy (svz_envblock_t *env){ svz_envblock_free (env); svz_free (env);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -