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

📄 main.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * main.c :  Main control function for svnserve
 *
 * ====================================================================
 * Copyright (c) 2000-2004 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */



#define APR_WANT_STRFUNC
#include <apr_want.h>
#include <apr_general.h>
#include <apr_lib.h>
#include <apr_strings.h>
#include <apr_getopt.h>
#include <apr_network_io.h>
#include <apr_signal.h>
#include <apr_thread_proc.h>

#include "svn_cmdline.h"
#include "svn_types.h"
#include "svn_string.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_ra_svn.h"
#include "svn_utf.h"
#include "svn_path.h"
#include "svn_opt.h"
#include "svn_repos.h"
#include "svn_version.h"

#include "server.h"

/* The strategy for handling incoming connections.  Some of these may be
   unavailable due to platform limitations. */
enum connection_handling_mode {
  connection_mode_fork,   /* Create a process per connection */
  connection_mode_thread, /* Create a thread per connection */
  connection_mode_single  /* One connection at a time in this process */
};

/* The mode in which to run svnserve */
enum run_mode {
  run_mode_none,
  run_mode_inetd,
  run_mode_daemon,
  run_mode_tunnel,
  run_mode_listen_once
};

#if APR_HAS_FORK
#if APR_HAS_THREADS

#define CONNECTION_DEFAULT connection_mode_fork
#define CONNECTION_HAVE_THREAD_OPTION

#else /* ! APR_HAS_THREADS */

#define CONNECTION_DEFAULT connection_mode_fork

#endif /* ! APR_HAS_THREADS */
#elif APR_HAS_THREADS /* and ! APR_HAS_FORK */

#define CONNECTION_DEFAULT connection_mode_thread

#else /* ! APR_HAS_THREADS and ! APR_HAS_FORK */

#define CONNECTION_DEFAULT connection_mode_single

#endif

/* Option codes and descriptions for svnserve.
 *
 * This must not have more than SVN_OPT_MAX_OPTIONS entries; if you
 * need more, increase that limit first.
 *
 * The entire list must be terminated with an entry of nulls.
 *
 * APR requires that options without abbreviations
 * have codes greater than 255.
 */
#define SVNSERVE_OPT_LISTEN_PORT 256
#define SVNSERVE_OPT_LISTEN_HOST 257
#define SVNSERVE_OPT_FOREGROUND  258
#define SVNSERVE_OPT_TUNNEL_USER 259
#define SVNSERVE_OPT_VERSION     260

static const apr_getopt_option_t svnserve__options[] =
  {
    {"daemon",           'd', 0, "daemon mode"},
    {"listen-port",       SVNSERVE_OPT_LISTEN_PORT, 1,
     "listen port (for daemon mode)"},
    {"listen-host",       SVNSERVE_OPT_LISTEN_HOST, 1,
     "listen hostname or IP address (for daemon mode)"},
    {"foreground",        SVNSERVE_OPT_FOREGROUND, 0,
     "run in foreground (useful for debugging)"},
    {"help",             'h', 0, "display this help"},
    {"version",           SVNSERVE_OPT_VERSION, 0,
     "show version information"},
    {"inetd",            'i', 0, "inetd mode"},
    {"root",             'r', 1, "root of directory to serve"},
    {"read-only",        'R', 0, "deprecated; use repository config file"},
    {"tunnel",           't', 0, "tunnel mode"},
    {"tunnel-user",      SVNSERVE_OPT_TUNNEL_USER, 1,
     "tunnel username (default is current uid's name)"},
#ifdef CONNECTION_HAVE_THREAD_OPTION
    {"threads",          'T', 0, "use threads instead of fork"},
#endif
    {"listen-once",      'X', 0, "listen once (useful for debugging)"},
    {0,                  0,   0, 0}
  };


static void usage(const char *progname)
{
  if (!progname)
    progname = "svnserve";

  fprintf(stderr, "Type '%s --help' for usage.\n", progname);
  exit(1);
}

static void help(apr_pool_t *pool)
{
  apr_size_t i;

  svn_error_clear (svn_cmdline_fputs("Usage: svnserve [options]\n"
                                     "\n"
                                     "Valid options:\n",
                                     stdout, pool));
  for (i = 0; svnserve__options[i].name && svnserve__options[i].optch; i++)
    {
      const char *optstr;
      svn_opt_format_option(&optstr, svnserve__options + i, TRUE, pool);
      svn_error_clear (svn_cmdline_fprintf(stdout, pool, "  %s\n", optstr));
    }
  svn_error_clear (svn_cmdline_fprintf(stdout, pool, "\n"));
  exit(1);
}

static svn_error_t * version(apr_getopt_t *os, apr_pool_t *pool)
{
  return svn_opt_print_help(os, "svnserve", TRUE, FALSE, NULL, NULL,
                            NULL, NULL, NULL, pool);
}
  

#if APR_HAS_FORK
static void sigchld_handler(int signo)
{
  /* Nothing to do; we just need to interrupt the accept(). */
}
#endif

/* In tunnel or inetd mode, we don't want hook scripts corrupting the
 * data stream by sending data to stdout, so we need to redirect
 * stdout somewhere else.  Sending it to stderr is acceptable; sending
 * it to /dev/null is another option, but apr doesn't provide a way to
 * do that without also detaching from the controlling terminal.
 */
static apr_status_t redirect_stdout(void *arg)
{
  apr_pool_t *pool = arg;
  apr_file_t *out_file, *err_file;

  apr_file_open_stdout(&out_file, pool);
  apr_file_open_stderr(&err_file, pool);
  return apr_file_dup2(out_file, err_file, pool);
}

/* "Arguments" passed from the main thread to the connection thread */
struct serve_thread_t {
  svn_ra_svn_conn_t *conn;
  serve_params_t *params;
  apr_pool_t *pool;
};

#if APR_HAS_THREADS
static void * APR_THREAD_FUNC serve_thread(apr_thread_t *tid, void *data)
{
  struct serve_thread_t *d = data;

  svn_error_clear(serve(d->conn, d->params, d->pool));
  svn_pool_destroy(d->pool);

  return NULL;
}
#endif

/* Version compatibility check */
static svn_error_t *
check_lib_versions (void)
{
  static const svn_version_checklist_t checklist[] =
    {
      { "svn_subr",  svn_subr_version },
      { "svn_repos", svn_repos_version },
      { "svn_fs",    svn_fs_version },
      { "svn_delta", svn_delta_version },
      { "svn_ra_svn", svn_ra_svn_version },
      { NULL, NULL }
    };

   SVN_VERSION_DEFINE (my_version);
   return svn_ver_check_list (&my_version, checklist);
}


int main(int argc, const char *const *argv)
{
  enum run_mode run_mode = run_mode_none;
  svn_boolean_t foreground = FALSE;
  apr_socket_t *sock, *usock;
  apr_file_t *in_file, *out_file;
  apr_sockaddr_t *sa;
  apr_pool_t *pool;
  apr_pool_t *connection_pool;
  svn_error_t *err;
  apr_getopt_t *os;
  char errbuf[256];
  int opt;
  serve_params_t params;
  const char *arg;
  apr_status_t status;
  svn_ra_svn_conn_t *conn;
  apr_proc_t proc;
#if APR_HAS_THREADS
  apr_threadattr_t *tattr;
  apr_thread_t *tid;
  struct serve_thread_t *thread_data;
#endif
  enum connection_handling_mode handling_mode = CONNECTION_DEFAULT;
  apr_uint16_t port = SVN_RA_SVN_PORT;
  const char *host = NULL;

  /* Initialize the app. */
  if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  /* Create our top-level pool. */
  pool = svn_pool_create(NULL);

  /* Check library versions */
  err = check_lib_versions ();
  if (err)
    {
      svn_handle_error (err, stderr, FALSE);
      svn_error_clear (err);
      svn_pool_destroy (pool);
      return EXIT_FAILURE;
    }

  apr_getopt_init(&os, pool, argc, argv);

⌨️ 快捷键说明

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