⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 passthrough.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * passthrough.c - pass through connections to processes * * Copyright (C) 2001 Stefan Jahn <stefan@lkcc.org> * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * $Id: passthrough.c,v 1.7 2001/09/13 13:28:54 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#define _GNU_SOURCE#include <assert.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/stat.h>#if HAVE_UNISTD_H# include <unistd.h>#endif#if !defined(__MINGW32__) && !defined(__CYGWIN__)extern char ** environ;#endif#ifdef __MINGW32__# include <winsock2.h># include <io.h># include <shellapi.h>#endif#include "libserveez/alloc.h"#include "libserveez/util.h"#include "libserveez/snprintf.h"#include "libserveez/socket.h"#include "libserveez/core.h"#include "libserveez/server-core.h"#include "libserveez/pipe-socket.h"#include "libserveez/passthrough.h"/* * This routine start a new program specified by @var{bin} passing the * socket descriptor in the socket structure @var{sock} to stdin and stdout. * The arguments and the environment of the new process can be passed by * @var{argv} and @var{envp}. The argument @var{flag} specifies the method * used to passthrough the connection. It can be either  * @code{SVZ_PROCESS_FORK} (pass pipes or socket directly through  * @code{fork()} and @code{exec()}) or @code{SVZ_PROCESS_SHUFFLE} (pass * socket transactions via a pair of pipes). */intsvz_sock_process (svz_socket_t *sock, char *bin, 		  char **argv, svz_envblock_t *envp, int flag){  HANDLE in, out;  char *dir = NULL, *p, *app, *file;  int len, ret = -1;  if (sock == NULL || bin == NULL)    return -1;  /* Setup descriptors depending on the type of socket structure. */  in = out = (HANDLE) sock->sock_desc;  if (sock->flags & SOCK_FLAG_PIPE)    {      in = sock->pipe_desc[READ];      out = sock->pipe_desc[WRITE];    }  /* Check executable. */  if (svz_process_check_executable (bin, &app) < 0)    return -1;  /* Extract the directory part of the binary. */  p = bin + strlen (bin) - 1;  while (p > bin && *p != '/' && *p != '\\')    p--;  if (p > bin)    {      file = svz_strdup (p + 1);      len = p - bin;      dir = svz_malloc (len + 1);      memcpy (dir, bin, len);      dir[len] = '\0';    }  else    {      file = svz_strdup (bin);    }  /* Depending on the given flag use different methods to passthrough     the connection. */  switch (flag)    {    case SVZ_PROCESS_FORK:      ret = svz_process_fork (file, dir, in, out, argv, envp, app);      break;    case SVZ_PROCESS_SHUFFLE:      ret = svz_process_shuffle (sock, file, dir, (SOCKET) in, argv, 				 envp, app);      break;    default:      svz_log (LOG_ERROR, "invalid flag (%d)\n", flag);      ret = -1;      break;    }  svz_free (file);  svz_free (dir);  return ret;}intsvz_process_send_pipe (svz_socket_t *sock){  return -1;}intsvz_process_recv_pipe (svz_socket_t *sock){  return -1;}intsvz_process_create_child (char *file, char *dir, HANDLE in, HANDLE out, 			  char **argv, svz_envblock_t *envp, char *app){  /* Change directory, make descriptors blocking, setup environment,     set permissions, duplicate descriptors and finally execute the      program. */#ifndef __MINGW32__        if (chdir (dir) < 0)    {      svz_log (LOG_ERROR, "chdir (%s): %s\n", dir, SYS_ERROR);      return -1;    }  if (svz_fd_block (out) < 0 || svz_fd_block (in) < 0)    return -1;  if (dup2 (out, 1) != 1 || dup2 (in, 0) != 0)    {      svz_log (LOG_ERROR, "unable to redirect: %s\n", SYS_ERROR);      return -1;    }  if (svz_process_check_access (file) < 0)    return -1;  /* Check the environment and create  a default one if necessary. */  if (envp == NULL)    {      envp = svz_envblock_create ();      svz_envblock_default (envp);    }  /* Execute the file itself here overwriting the current process. */  argv[0] = file;  if (execve (file, argv, svz_envblock_get (envp)) == -1)    {      svz_log (LOG_ERROR, "execve: %s\n", SYS_ERROR);      return -1;    }  return getpid ();#else /* __MINGW32__ */  STARTUPINFO startup_info;  PROCESS_INFORMATION process_info;  char *savedir, *application;  int pid, n;  /* Clean the Startup-Info, use the stdio handles, and store the pipe      handles there if necessary. */  memset (&startup_info, 0, sizeof (startup_info));  startup_info.cb = sizeof (startup_info);  startup_info.dwFlags = STARTF_USESTDHANDLES;  startup_info.hStdOutput = out;  startup_info.hStdInput = in;  /* Save current directory and change into application's. */  savedir = svz_getcwd ();  if (chdir (dir) < 0)    {      svz_log (LOG_ERROR, "getcwd: %s\n", SYS_ERROR);      svz_free (savedir);      return -1;    }  /* Check the access to the file. */  if (svz_process_check_access (file) < 0)    {      chdir (savedir);      svz_free (savedir);      return -1;    }  /* Create sane environment. */  if (envp == NULL)    {      envp = svz_envblock_create ();      svz_envblock_default (envp);    }  /* Concatenate application name. */  if (app != NULL)    {      application = svz_malloc (strlen (file) + strlen (app) + 2);      sprintf (application, "%s %s", app, file);    }  else    application = svz_strdup (file);  /* Append program arguments. */  for (n = 1; argv[n] != NULL; n++)    {      application = svz_realloc (application, strlen (application) + 				 strlen (argv[n]) + 2);      strcat (application, " ");      strcat (application, argv[n]);    }  if (!CreateProcess (NULL,                    /* application name */                      application,             /* command line */                      NULL,                    /* process attributes */                      NULL,                    /* thread attributes */                      TRUE,                    /* inherit handles */                      DETACHED_PROCESS,        /* creation flags */                      svz_envblock_get (envp), /* environment */                      NULL,                    /* current directory */                      &startup_info, &process_info))    {      svz_log (LOG_ERROR, "CreateProcess (%s): %s\n", application, SYS_ERROR);      chdir (savedir);      svz_free (savedir);      svz_free (application);      return -1;    }    chdir (savedir);  svz_free (savedir);  svz_free (application);  pid = (int) process_info.hProcess;#ifdef ENABLE_DEBUG  svz_log (LOG_DEBUG, "process `%s' got pid 0x%08X\n", file, 	   process_info.dwProcessId);#endif  return pid;#endif /* __MINGW32__ */}/* * Create two pairs of pipes in order to passthrough the transactions of the  * given socket descriptor @var{socket}. */intsvz_process_shuffle (svz_socket_t *sock, char *file, char *dir, SOCKET socket,		     char **argv, svz_envblock_t *envp, char *app){  HANDLE process_to_serveez[2];  HANDLE serveez_to_process[2];  HANDLE in, out;  svz_socket_t *xsock;  int pid;  /* create the pairs of pipes for the process */  if (svz_pipe_create_pair (process_to_serveez) == -1)    return -1;  if (svz_pipe_create_pair (serveez_to_process) == -1)    return -1;  /* create yet another socket structure */  if ((xsock = svz_sock_create (socket)) == NULL)    {      svz_log (LOG_ERROR, "failed to create passthrough socket\n");      return -1;    }  /* prepare everything for the pipe handling */  sock->pipe_desc[WRITE] = serveez_to_process[WRITE];  sock->flags |= SOCK_FLAG_SEND_PIPE;  sock->write_socket = svz_process_send_pipe;  svz_fd_cloexec ((int) serveez_to_process[WRITE]);  xsock->pipe_desc[READ] = process_to_serveez[READ];  xsock->flags |= SOCK_FLAG_RECV_PIPE;  xsock->read_socket = svz_process_recv_pipe;  svz_fd_cloexec ((int) process_to_serveez[READ]);  if (svz_sock_enqueue (xsock) < 0)    return -1;  in = serveez_to_process[READ];  out = process_to_serveez[WRITE];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -