Exemplo n.º 1
0
/* handle all varieties of core dumping signals */
static void sig_coredump(int sig)
{
    apr_filepath_set(ap_coredump_dir, pconf);
    apr_signal(sig, SIG_DFL);
#if AP_ENABLE_EXCEPTION_HOOK
    run_fatal_exception_hook(sig);
#endif
    /* linuxthreads issue calling getpid() here:
     *   This comparison won't match if the crashing thread is
     *   some module's thread that runs in the parent process.
     *   The fallout, which is limited to linuxthreads:
     *   The special log message won't be written when such a
     *   thread in the parent causes the parent to crash.
     */
    if (getpid() == parent_pid) {
        ap_log_error(APLOG_MARK, APLOG_NOTICE,
                     0, ap_server_conf, APLOGNO(00060)
                     "seg fault or similar nasty error detected "
                     "in the parent process");
        /* XXX we can probably add some rudimentary cleanup code here,
         * like getting rid of the pid file.  If any additional bad stuff
         * happens, we are protected from recursive errors taking down the
         * system since this function is no longer the signal handler   GLA
         */
    }
    kill(getpid(), sig);
    /* At this point we've got sig blocked, because we're still inside
     * the signal handler.  When we leave the signal handler it will
     * be unblocked, and we'll take the signal... and coredump or whatever
     * is appropriate for this particular Unix.  In addition the parent
     * will see the real signal we received -- whereas if we called
     * abort() here, the parent would only see SIGABRT.
     */
}
Exemplo n.º 2
0
/* Use the visual editor to edit files. This requires that the file name itself
   be shell-safe, although the path to reach that file need not be shell-safe.
 */
svn_error_t *
svn_cl__edit_file_externally(const char *path,
                             const char *editor_cmd,
                             apr_hash_t *config,
                             apr_pool_t *pool)
{
  const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr;
  char *old_cwd;
  int sys_err;
  apr_status_t apr_err;

  svn_dirent_split(&base_dir, &file_name, path, pool);

  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));

  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));

  /* APR doesn't like "" directories */
  if (base_dir[0] == '\0')
    base_dir_apr = ".";
  else
    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));

  apr_err = apr_filepath_set(base_dir_apr, pool);
  if (apr_err)
    return svn_error_wrap_apr
      (apr_err, _("Can't change working directory to '%s'"), base_dir);

  cmd = apr_psprintf(pool, "%s %s", editor, file_name);
  sys_err = system(cmd);

  apr_err = apr_filepath_set(old_cwd, pool);
  if (apr_err)
    svn_handle_error2(svn_error_wrap_apr
                      (apr_err, _("Can't restore working directory")),
                      stderr, TRUE /* fatal */, "svn: ");

  if (sys_err)
    /* Extracting any meaning from sys_err is platform specific, so just
       use the raw value. */
    return svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
                             _("system('%s') returned %d"), cmd, sys_err);

  return SVN_NO_ERROR;
}
Exemplo n.º 3
0
static void test_rmkdir_nocwd(abts_case *tc, void *data)
{
    char *cwd, *path;

    APR_ASSERT_SUCCESS(tc, "make temp dir",
                       apr_dir_make("dir3", APR_OS_DEFAULT, p));

    APR_ASSERT_SUCCESS(tc, "obtain cwd", apr_filepath_get(&cwd, 0, p));

    APR_ASSERT_SUCCESS(tc, "determine path to temp dir",
                       apr_filepath_merge(&path, cwd, "dir3", 0, p));

    APR_ASSERT_SUCCESS(tc, "change to temp dir", apr_filepath_set(path, p));

    APR_ASSERT_SUCCESS(tc, "restore cwd", apr_filepath_set(cwd, p));

    APR_ASSERT_SUCCESS(tc, "remove cwd", apr_dir_remove(path, p));
}
Exemplo n.º 4
0
term_t bif_set_cwd1(term_t Dir, process_t *ctx)
{
	apr_status_t rs;
	apr_pool_t *p;
	const char *path;
	if (!is_string(Dir))
		return A_BADARG;
	apr_pool_create(&p, 0);
	path = ltoz(Dir, p);
	rs = apr_filepath_set(path, p);
	apr_pool_destroy(p);
	if (rs == 0)
		result(A_OK);
	else
		result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx)));
	return AI_OK;
}
Exemplo n.º 5
0
/*
 * main
 */
int main(int argc, const char * const argv[])
{
    apr_off_t max;
    apr_time_t current, repeat, delay, previous;
    apr_status_t status;
    apr_pool_t *pool, *instance;
    apr_getopt_t *o;
    apr_finfo_t info;
    int retries, isdaemon, limit_found, intelligent, dowork;
    char opt;
    const char *arg;
    char *proxypath, *path;

    interrupted = 0;
    repeat = 0;
    isdaemon = 0;
    dryrun = 0;
    limit_found = 0;
    max = 0;
    verbose = 0;
    realclean = 0;
    benice = 0;
    deldirs = 0;
    intelligent = 0;
    previous = 0; /* avoid compiler warning */
    proxypath = NULL;

    if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) {
        return 1;
    }
    atexit(apr_terminate);

    if (argc) {
        shortname = apr_filepath_name_get(argv[0]);
    }

    if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
        return 1;
    }
    apr_pool_abort_set(oom, pool);
    apr_file_open_stderr(&errfile, pool);
    apr_signal(SIGINT, setterm);
    apr_signal(SIGTERM, setterm);

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

    while (1) {
        status = apr_getopt(o, "iDnvrtd:l:L:p:", &opt, &arg);
        if (status == APR_EOF) {
            break;
        }
        else if (status != APR_SUCCESS) {
            usage();
        }
        else {
            switch (opt) {
            case 'i':
                if (intelligent) {
                    usage();
                }
                intelligent = 1;
                break;

            case 'D':
                if (dryrun) {
                    usage();
                }
                dryrun = 1;
                break;

            case 'n':
                if (benice) {
                    usage();
                }
                benice = 1;
                break;

            case 't':
                if (deldirs) {
                    usage();
                }
                deldirs = 1;
                break;

            case 'v':
                if (verbose) {
                    usage();
                }
                verbose = 1;
                break;

            case 'r':
                if (realclean) {
                    usage();
                }
                realclean = 1;
                deldirs = 1;
                break;

            case 'd':
                if (isdaemon) {
                    usage();
                }
                isdaemon = 1;
                repeat = apr_atoi64(arg);
                repeat *= SECS_PER_MIN;
                repeat *= APR_USEC_PER_SEC;
                break;

            case 'l':
                if (limit_found) {
                    usage();
                }
                limit_found = 1;

                do {
                    apr_status_t rv;
                    char *end;

                    rv = apr_strtoff(&max, arg, &end, 10);
                    if (rv == APR_SUCCESS) {
                        if ((*end == 'K' || *end == 'k') && !end[1]) {
                            max *= KBYTE;
                        }
                        else if ((*end == 'M' || *end == 'm') && !end[1]) {
                            max *= MBYTE;
                        }
                        else if ((*end == 'G' || *end == 'g') && !end[1]) {
                            max *= GBYTE;
                        }
                        else if (*end &&        /* neither empty nor [Bb] */
                                 ((*end != 'B' && *end != 'b') || end[1])) {
                            rv = APR_EGENERAL;
                        }
                    }
                    if (rv != APR_SUCCESS) {
                        apr_file_printf(errfile, "Invalid limit: %s"
                                                 APR_EOL_STR APR_EOL_STR, arg);
                        usage();
                    }
                } while(0);
                break;

            case 'p':
                if (proxypath) {
                    usage();
                }
                proxypath = apr_pstrdup(pool, arg);
                if (apr_filepath_set(proxypath, pool) != APR_SUCCESS) {
                    usage();
                }
                break;
            } /* switch */
        } /* else */
    } /* while */

    if (o->ind != argc) {
         usage();
    }

    if (isdaemon && (repeat <= 0 || verbose || realclean || dryrun)) {
         usage();
    }

    if (!isdaemon && intelligent) {
         usage();
    }

    if (!proxypath || max <= 0) {
         usage();
    }

    if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) {
        usage();
    }
    baselen = strlen(path);

#ifndef DEBUG
    if (isdaemon) {
        apr_file_close(errfile);
        apr_proc_detach(APR_PROC_DETACH_DAEMONIZE);
    }
#endif

    do {
        apr_pool_create(&instance, pool);

        now = apr_time_now();
        APR_RING_INIT(&root, _entry, link);
        delcount = 0;
        unsolicited = 0;
        dowork = 0;

        switch (intelligent) {
        case 0:
            dowork = 1;
            break;

        case 1:
            retries = STAT_ATTEMPTS;
            status = APR_SUCCESS;

            do {
                if (status != APR_SUCCESS) {
                    apr_sleep(STAT_DELAY);
                }
                status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
            } while (status != APR_SUCCESS && !interrupted && --retries);

            if (status == APR_SUCCESS) {
                previous = info.mtime;
                intelligent = 2;
            }
            dowork = 1;
            break;

        case 2:
            retries = STAT_ATTEMPTS;
            status = APR_SUCCESS;

            do {
                if (status != APR_SUCCESS) {
                    apr_sleep(STAT_DELAY);
                }
                status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
            } while (status != APR_SUCCESS && !interrupted && --retries);

            if (status == APR_SUCCESS) {
                if (previous != info.mtime) {
                    dowork = 1;
                }
                previous = info.mtime;
                break;
            }
            intelligent = 1;
            dowork = 1;
            break;
        }

        if (dowork && !interrupted) {
            if (!process_dir(path, instance) && !interrupted) {
                purge(path, instance, max);
            }
            else if (!isdaemon && !interrupted) {
                apr_file_printf(errfile, "An error occurred, cache cleaning "
                                         "aborted." APR_EOL_STR);
                return 1;
            }

            if (intelligent && !interrupted) {
                retries = STAT_ATTEMPTS;
                status = APR_SUCCESS;
                do {
                    if (status != APR_SUCCESS) {
                        apr_sleep(STAT_DELAY);
                    }
                    status = apr_stat(&info, path, APR_FINFO_MTIME, instance);
                } while (status != APR_SUCCESS && !interrupted && --retries);

                if (status == APR_SUCCESS) {
                    previous = info.mtime;
                    intelligent = 2;
                }
                else {
                    intelligent = 1;
                }
            }
        }

        apr_pool_destroy(instance);

        current = apr_time_now();
        if (current < now) {
            delay = repeat;
        }
        else if (current - now >= repeat) {
            delay = repeat;
        }
        else {
            delay = now + repeat - current;
        }

        /* we can't sleep the whole delay time here apiece as this is racy
         * with respect to interrupt delivery - think about what happens
         * if we have tested for an interrupt, then get scheduled
         * before the apr_sleep() call and while waiting for the cpu
         * we do get an interrupt
         */
        if (isdaemon) {
            while (delay && !interrupted) {
                if (delay > APR_USEC_PER_SEC) {
                    apr_sleep(APR_USEC_PER_SEC);
                    delay -= APR_USEC_PER_SEC;
                }
                else {
                    apr_sleep(delay);
                    delay = 0;
                }
            }
        }
    } while (isdaemon && !interrupted);

    if (!isdaemon && interrupted) {
        apr_file_printf(errfile, "Cache cleaning aborted due to user "
                                 "request." APR_EOL_STR);
        return 1;
    }

    return 0;
}
Exemplo n.º 6
0
svn_error_t *
svn_cl__edit_string_externally(svn_string_t **edited_contents /* UTF-8! */,
                               const char **tmpfile_left /* UTF-8! */,
                               const char *editor_cmd,
                               const char *base_dir /* UTF-8! */,
                               const svn_string_t *contents /* UTF-8! */,
                               const char *filename,
                               apr_hash_t *config,
                               svn_boolean_t as_text,
                               const char *encoding,
                               apr_pool_t *pool)
{
  const char *editor;
  const char *cmd;
  apr_file_t *tmp_file;
  const char *tmpfile_name;
  const char *tmpfile_native;
  const char *tmpfile_apr, *base_dir_apr;
  svn_string_t *translated_contents;
  apr_status_t apr_err, apr_err2;
  apr_size_t written;
  apr_finfo_t finfo_before, finfo_after;
  svn_error_t *err = SVN_NO_ERROR, *err2;
  char *old_cwd;
  int sys_err;
  svn_boolean_t remove_file = TRUE;

  SVN_ERR(find_editor_binary(&editor, editor_cmd, config));

  /* Convert file contents from UTF-8/LF if desired. */
  if (as_text)
    {
      const char *translated;
      SVN_ERR(svn_subst_translate_cstring2(contents->data, &translated,
                                           APR_EOL_STR, FALSE,
                                           NULL, FALSE, pool));
      translated_contents = svn_string_create("", pool);
      if (encoding)
        SVN_ERR(svn_utf_cstring_from_utf8_ex2(&translated_contents->data,
                                              translated, encoding, pool));
      else
        SVN_ERR(svn_utf_cstring_from_utf8(&translated_contents->data,
                                          translated, pool));
      translated_contents->len = strlen(translated_contents->data);
    }
  else
    translated_contents = svn_string_dup(contents, pool);

  /* Move to BASE_DIR to avoid getting characters that need quoting
     into tmpfile_name */
  apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool);
  if (apr_err)
    return svn_error_wrap_apr(apr_err, _("Can't get working directory"));

  /* APR doesn't like "" directories */
  if (base_dir[0] == '\0')
    base_dir_apr = ".";
  else
    SVN_ERR(svn_path_cstring_from_utf8(&base_dir_apr, base_dir, pool));
  apr_err = apr_filepath_set(base_dir_apr, pool);
  if (apr_err)
    {
      return svn_error_wrap_apr
        (apr_err, _("Can't change working directory to '%s'"), base_dir);
    }

  /*** From here on, any problems that occur require us to cd back!! ***/

  /* Ask the working copy for a temporary file named FILENAME-something. */
  err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                   "" /* dirpath */,
                                   filename,
                                   ".tmp",
                                   svn_io_file_del_none, pool, pool);

  if (err && (APR_STATUS_IS_EACCES(err->apr_err) || err->apr_err == EROFS))
    {
      const char *temp_dir_apr;

      svn_error_clear(err);

      SVN_ERR(svn_io_temp_dir(&base_dir, pool));

      SVN_ERR(svn_path_cstring_from_utf8(&temp_dir_apr, base_dir, pool));
      apr_err = apr_filepath_set(temp_dir_apr, pool);
      if (apr_err)
        {
          return svn_error_wrap_apr
            (apr_err, _("Can't change working directory to '%s'"), base_dir);
        }

      err = svn_io_open_uniquely_named(&tmp_file, &tmpfile_name,
                                       "" /* dirpath */,
                                       filename,
                                       ".tmp",
                                       svn_io_file_del_none, pool, pool);
    }

  if (err)
    goto cleanup2;

  /*** From here on, any problems that occur require us to cleanup
       the file we just created!! ***/

  /* Dump initial CONTENTS to TMP_FILE. */
  apr_err = apr_file_write_full(tmp_file, translated_contents->data,
                                translated_contents->len, &written);

  apr_err2 = apr_file_close(tmp_file);
  if (! apr_err)
    apr_err = apr_err2;

  /* Make sure the whole CONTENTS were written, else return an error. */
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't write to '%s'"),
                               tmpfile_name);
      goto cleanup;
    }

  err = svn_path_cstring_from_utf8(&tmpfile_apr, tmpfile_name, pool);
  if (err)
    goto cleanup;

  /* Get information about the temporary file before the user has
     been allowed to edit its contents. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Backdate the file a little bit in case the editor is very fast
     and doesn't change the size.  (Use two seconds, since some
     filesystems have coarse granularity.)  It's OK if this call
     fails, so we don't check its return value.*/
  apr_file_mtime_set(tmpfile_apr, finfo_before.mtime - 2000, pool);

  /* Stat it again to get the mtime we actually set. */
  apr_err = apr_stat(&finfo_before, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* Prepare the editor command line.  */
  err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
  if (err)
    goto cleanup;
  cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);

  /* If the caller wants us to leave the file around, return the path
     of the file we'll use, and make a note not to destroy it.  */
  if (tmpfile_left)
    {
      *tmpfile_left = svn_dirent_join(base_dir, tmpfile_name, pool);
      remove_file = FALSE;
    }

  /* Now, run the editor command line.  */
  sys_err = system(cmd);
  if (sys_err != 0)
    {
      /* Extracting any meaning from sys_err is platform specific, so just
         use the raw value. */
      err =  svn_error_createf(SVN_ERR_EXTERNAL_PROGRAM, NULL,
                               _("system('%s') returned %d"), cmd, sys_err);
      goto cleanup;
    }

  /* Get information about the temporary file after the assumed editing. */
  apr_err = apr_stat(&finfo_after, tmpfile_apr,
                     APR_FINFO_MTIME | APR_FINFO_SIZE, pool);
  if (apr_err)
    {
      err = svn_error_wrap_apr(apr_err, _("Can't stat '%s'"), tmpfile_name);
      goto cleanup;
    }

  /* If the file looks changed... */
  if ((finfo_before.mtime != finfo_after.mtime) ||
      (finfo_before.size != finfo_after.size))
    {
      svn_stringbuf_t *edited_contents_s;
      err = svn_stringbuf_from_file2(&edited_contents_s, tmpfile_name, pool);
      if (err)
        goto cleanup;

      *edited_contents = svn_stringbuf__morph_into_string(edited_contents_s);

      /* Translate back to UTF8/LF if desired. */
      if (as_text)
        {
          err = svn_subst_translate_string2(edited_contents, FALSE, FALSE,
                                            *edited_contents, encoding, FALSE,
                                            pool, pool);
          if (err)
            {
              err = svn_error_quick_wrap
                (err,
                 _("Error normalizing edited contents to internal format"));
              goto cleanup;
            }
        }
    }
  else
    {
      /* No edits seem to have been made */
      *edited_contents = NULL;
    }

 cleanup:
  if (remove_file)
    {
      /* Remove the file from disk.  */
      err2 = svn_io_remove_file2(tmpfile_name, FALSE, pool);

      /* Only report remove error if there was no previous error. */
      if (! err && err2)
        err = err2;
      else
        svn_error_clear(err2);
    }

 cleanup2:
  /* If we against all probability can't cd back, all further relative
     file references would be screwed up, so we have to abort. */
  apr_err = apr_filepath_set(old_cwd, pool);
  if (apr_err)
    {
      svn_handle_error2(svn_error_wrap_apr
                        (apr_err, _("Can't restore working directory")),
                        stderr, TRUE /* fatal */, "svn: ");
    }

  return svn_error_trace(err);
}
Exemplo n.º 7
0
int main(int argc, const char * const *argv, const char * const *env)
{
    DWORD dispmode;
    nx_exception_t e;

    ASSERT(nx_init(&argc, &argv, &env) == TRUE);

    nxlog_init(&nxlog);
    _nxlog_initializer = apr_os_thread_current();

    try
    {
        // read cmd line
        parse_cmd_line(argc, argv);
        /*
        	// reload switch?
        	if ( nxlog.do_restart == TRUE )
        	{
        	    //FIXME restart service; use custom control code?
        	}
        */
        // stop switch?
        if ( nxlog.do_stop == TRUE )
        {
            nx_win32_svc_stop();
            exit(0);
        }

        if ( do_install == TRUE )
        {
            nx_win32_svc_install();
            exit(0);
        }

        if ( do_uninstall == TRUE )
        {
            nx_win32_svc_uninstall();
            exit(0);
        }

        // load and parse config
        nx_ctx_parse_cfg(nxlog.ctx, nxlog.cfgfile);

        if ( nxlog.ctx->spooldir != NULL )
        {
            CHECKERR_MSG(apr_filepath_set(nxlog.ctx->spooldir, nxlog.pool),
                         "Couldn't change to SpoolDir '%s'", nxlog.ctx->spooldir);
        }

        nx_ctx_init_logging(nxlog.ctx);

        if ( nxlog.ctx->rootdir != NULL )
        {
            throw_msg("RootDir not supported on windows");
        }

        if ( nxlog.verify_conf == TRUE )
        {
            // load DSO and read and verify module config
            nx_ctx_config_modules(nxlog.ctx);
            nx_ctx_init_routes(nxlog.ctx);
            log_info("configuration OK");
            exit(0);
        }

        if ( nxlog.foreground == TRUE )
        {
            nx_win32_svc_main(argc, argv);
        }
        else
        {
            // detect wheter we are invoked by SVM or from the console
            if ( GetConsoleDisplayMode(&dispmode) == 0 )
            {
                nx_win32_svc_dispatch();
            }
            else
            {
                nx_win32_svc_start(argc, argv);
            }
        }
    }
    catch(e)
    {
        apr_file_t *f = NULL;
        apr_pool_t *pool;
        HKEY regkey;
        uint32_t regtype = 0;
        char regvalbuf[1024];
        uint32_t regvalbufsize = 1024;
        const char *logfile = "c:\\nxlog-service-error.txt";

        pool = nx_pool_create_core();

        // TODO: log to eventlog in addition?

        if ( RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\nxlog", &regkey) == ERROR_SUCCESS )
        {
            if ( RegQueryValueEx(regkey, "installdir", 0, &regtype,
                                 (unsigned char *) regvalbuf, &regvalbufsize) == ERROR_SUCCESS )
            {
                if ( regtype == REG_SZ )
                {
                    logfile = apr_psprintf(nxlog.pool, "%sdata\\nxlog.log", regvalbuf);
                }
            }
            RegCloseKey(regkey);
        }
        apr_file_open(&f, logfile, APR_READ | APR_WRITE | APR_CREATE | APR_APPEND,
                      APR_OS_DEFAULT, pool);
        // FXIME: check status code
        if ( f != NULL )
        {
            nx_string_t *tmpstr;
            int i;
            char errmsg[1024];

            tmpstr = nx_string_new();

            for ( i = ((int) e.num_throw) - 1; i >= 0; i-- )
            {
                if ( tmpstr->len > 0 )
                {
                    nx_string_append(tmpstr, NX_LINEFEED, -1);
                }
                nx_string_append(tmpstr, e.msgbuf + e.throwlist[i].msgoffs, -1);
            }
            nx_string_append(tmpstr, NX_LINEFEED, -1);
            if ( e.code != APR_SUCCESS )
            {
                apr_strerror(e.code, errmsg, sizeof(errmsg));
                nx_string_append(tmpstr, errmsg, -1);
                nx_string_append(tmpstr, NX_LINEFEED, -1);
            }
            apr_file_printf(f, "nxlog failed to start: %s\r\n", tmpstr->buf);
            apr_file_close(f);
            nx_string_free(tmpstr);
        }
        apr_pool_destroy(pool);
        log_exception(e);
        exit(e.code);
    }

    return ( 0 );
}