예제 #1
0
파일: error.c 프로젝트: liuxfiu/primogeni
void x_msg (const unsigned int flags, const char *format, ...)
{
  struct gc_arena gc;
  va_list arglist;
#if SYSLOG_CAPABILITY
  int level;
#endif
  char *m1;
  char *m2;
  char *tmp;
  int e;
  const char *prefix;
  const char *prefix_sep;

  void usage_small (void);

#ifndef HAVE_VARARG_MACROS
  /* the macro has checked this otherwise */
  if (!MSG_TEST (flags))
    return;
#endif

  if (flags & M_ERRNO_SOCK)
    e = openvpn_errno_socket ();
  else
    e = openvpn_errno ();

  /*
   * Apply muting filter.
   */
#ifndef HAVE_VARARG_MACROS
  /* the macro has checked this otherwise */
  if (!dont_mute (flags))
    return;
#endif

  gc_init (&gc);

  mutex_lock_static (L_MSG);

  m1 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc);
  m2 = (char *) gc_malloc (ERR_BUF_SIZE, false, &gc);

  va_start (arglist, format);
  vsnprintf (m1, ERR_BUF_SIZE, format, arglist);
  va_end (arglist);
  m1[ERR_BUF_SIZE - 1] = 0; /* windows vsnprintf needs this */

  if ((flags & (M_ERRNO|M_ERRNO_SOCK)) && e)
    {
      openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s (errno=%d)",
			m1, strerror_ts (e, &gc), e);
      SWAP;
    }

#ifdef USE_CRYPTO
  if (flags & M_SSL)
    {
      int nerrs = 0;
      int err;
      while ((err = ERR_get_error ()))
	{
	  openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s",
			    m1, ERR_error_string (err, NULL));
	  SWAP;
	  ++nerrs;
	}
      if (!nerrs)
	{
	  openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1);
	  SWAP;
	}
    }
#endif

  if (flags & M_OPTERR)
    {
      openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1);
      SWAP;
    }

#if SYSLOG_CAPABILITY
  if (flags & (M_FATAL|M_NONFATAL|M_USAGE_SMALL))
    level = LOG_ERR;
  else if (flags & M_WARN)
    level = LOG_WARNING;
  else
    level = LOG_NOTICE;
#endif

  /* set up client prefix */
  prefix = msg_get_prefix ();
  prefix_sep = " ";
  if (!prefix)
    prefix_sep = prefix = "";

  /* virtual output capability used to copy output to management subsystem */
  if (!forked)
    {
      const struct virtual_output *vo = msg_get_virtual_output ();
      if (vo)
	{
	  openvpn_snprintf (m2, ERR_BUF_SIZE, "%s%s%s",
			    prefix,
			    prefix_sep,
			    m1);
	  virtual_output_print (vo, flags, m2);
	}
    }

  if (!(flags & M_MSG_VIRT_OUT))
    {
      if (use_syslog && !std_redir && !forked)
	{
#if SYSLOG_CAPABILITY
	  syslog (level, "%s%s%s",
		  prefix,
		  prefix_sep,
		  m1);
#endif
	}
      else
	{
	  FILE *fp = msg_fp();
	  const bool show_usec = check_debug_level (DEBUG_LEVEL_USEC_TIME);

	  if ((flags & M_NOPREFIX) || suppress_timestamps)
	    {
	      fprintf (fp, "%s%s%s%s",
		       prefix,
		       prefix_sep,
		       m1,
		       (flags&M_NOLF) ? "" : "\n");
	    }
	  else
	    {
#ifdef USE_PTHREAD
	      fprintf (fp, "%s [%d] %s%s%s%s",
		       time_string (0, 0, show_usec, &gc),
		       (int) openvpn_thread_self (),
		       prefix,
		       prefix_sep,
		       m1,
		       (flags&M_NOLF) ? "" : "\n");
#else
	      fprintf (fp, "%s %s%s%s%s",
		       time_string (0, 0, show_usec, &gc),
		       prefix,
		       prefix_sep,
		       m1,
		       (flags&M_NOLF) ? "" : "\n");
#endif
	    }
	  fflush(fp);
	  ++x_msg_line_num;
	}
    }

  if (flags & M_FATAL)
    msg (M_INFO, "Exiting");

  mutex_unlock_static (L_MSG);
  
  if (flags & M_FATAL)
    openvpn_exit (OPENVPN_EXIT_STATUS_ERROR); /* exit point */

  if (flags & M_USAGE_SMALL)
    usage_small ();

  gc_free (&gc);
}
예제 #2
0
int
plugin_call (const struct plugin_list *pl,
	     const int type,
	     const struct argv *av,
	     struct plugin_return *pr,
	     struct env_set *es)
{
  if (pr)
    plugin_return_init (pr);

  if (plugin_defined (pl, type))
    {
      struct gc_arena gc = gc_new ();
      int i;
      const char **envp;
      const int n = plugin_n (pl);
      bool success = false;
      bool error = false;
      bool deferred = false;
      
      mutex_lock_static (L_PLUGIN);

      setenv_del (es, "script_type");
      envp = make_env_array (es, false, &gc);

      for (i = 0; i < n; ++i)
	{
	  const int status = plugin_call_item (&pl->common->plugins[i],
					       pl->per_client.per_client_context[i],
					       type,
					       av,
					       pr ? &pr->list[i] : NULL,
					       envp);
	  switch (status)
	    {
	    case OPENVPN_PLUGIN_FUNC_SUCCESS:
	      success = true;
	      break;
	    case OPENVPN_PLUGIN_FUNC_DEFERRED:
	      deferred = true;
	      break;
	    default:
	      error = true;
	      break;
	    }
	}

      if (pr)
	pr->n = i;

      mutex_unlock_static (L_PLUGIN);

      gc_free (&gc);

      if (type == OPENVPN_PLUGIN_ENABLE_PF && success)
	return OPENVPN_PLUGIN_FUNC_SUCCESS;
      else if (error)
	return OPENVPN_PLUGIN_FUNC_ERROR;
      else if (deferred)
	return OPENVPN_PLUGIN_FUNC_DEFERRED;
    }

  return OPENVPN_PLUGIN_FUNC_SUCCESS;
}