Пример #1
0
static void
signal_handler (int signo)
{
	static gboolean in_loop = FALSE;

	/* Die if we get re-entrant signals handler calls */
	if (in_loop) {
		_exit (EXIT_FAILURE);
	}

	switch (signo) {
	case SIGTERM:
	case SIGINT:
		in_loop = TRUE;
		if (main_loop != NULL) {
			g_main_loop_quit (main_loop);
		} else {
			exit (0);
		}
		/* Fall through */
	default:
		if (g_strsignal (signo)) {
			g_print ("\n");
			g_print ("Received signal:%d->'%s'\n",
			         signo,
			         g_strsignal (signo));
		}
		break;
	}
}
Пример #2
0
static gboolean
signal_handler (gpointer user_data)
{
	int signo = GPOINTER_TO_INT (user_data);

	static gboolean in_loop = FALSE;

	/* Die if we get re-entrant signals handler calls */
	if (in_loop) {
		_exit (EXIT_FAILURE);
	}

	switch (signo) {
	case SIGTERM:
	case SIGINT:
		in_loop = TRUE;
		g_main_loop_quit (main_loop);

		/* Fall through */
	default:
		if (g_strsignal (signo)) {
			g_print ("\n");
			g_print ("Received signal:%d->'%s'\n",
			         signo,
			         g_strsignal (signo));
		}
		break;
	}

	return G_SOURCE_CONTINUE;
}
Пример #3
0
static void
rspamd_worker_term_handler (struct rspamd_worker_signal_handler *sigh, void *arg)
{
	struct timeval tv;

	if (!sigh->worker->wanna_die) {
		rspamd_default_log_function (G_LOG_LEVEL_INFO,
				sigh->worker->srv->server_pool->tag.tagname,
				sigh->worker->srv->server_pool->tag.uid,
				G_STRFUNC,
				"terminating after receiving signal %s",
				g_strsignal (sigh->signo));

		tv.tv_usec = 0;
		if (rspamd_worker_terminate_handlers (sigh->worker)) {
			tv.tv_sec =  SOFT_SHUTDOWN_TIME;
		}
		else {
			tv.tv_sec = 0;
		}

		sigh->worker->wanna_die = 1;
		event_base_loopexit (sigh->base, &tv);
#ifdef WITH_GPERF_TOOLS
		ProfilerStop ();
#endif
		rspamd_worker_stop_accept (sigh->worker);
	}
}
Пример #4
0
static void sig_pidwait(void *pid, void *statusp)
{
	PROCESS_REC *rec;
        char *str;
	int status = GPOINTER_TO_INT(statusp);

        rec = process_find_pid(GPOINTER_TO_INT(pid));
	if (rec == NULL) return;

	/* process exited - print the last line if
	   there wasn't a newline at end. */
	if (line_split("\n", 1, &str, &rec->databuf) > 0 && *str != '\0')
		signal_emit_id(signal_exec_input, 2, rec, str);

	if (!rec->silent) {
		if (WIFSIGNALED(status)) {
			status = WTERMSIG(status);
			printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
				  "process %d (%s) terminated with signal %d (%s)",
				  rec->id, rec->args,
				  status, g_strsignal(status));
		} else {
                        status = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
			printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
				  "process %d (%s) terminated with return code %d",
				  rec->id, rec->args, status);
		}
	}
	process_destroy(rec, status);
}
Пример #5
0
static void sig_pidwait(void *pid, void *statusp)
{
	PROCESS_REC *rec;
	int status = GPOINTER_TO_INT(statusp);

        rec = process_find_pid(GPOINTER_TO_INT(pid));
	if (rec == NULL) return;

	/* process exited */
	if (!rec->silent) {
		if (WIFSIGNALED(status)) {
			status = WTERMSIG(status);
			printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
				  "process %d (%s) terminated with signal %d (%s)",
				  rec->id, rec->args,
				  status, g_strsignal(status));
		} else {
                        status = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
			printtext(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
				  "process %d (%s) terminated with return code %d",
				  rec->id, rec->args, status);
		}
	}
	process_destroy(rec, status);
}
static void
on_session_died (MdmSession *session,
                 int         signal_number)
{
        g_print ("session died with signal %d, (%s)\n",
                 signal_number,
                 g_strsignal (signal_number));
        exit (1);
}
Пример #7
0
static void
gimp_sigfatal_handler (gint sig_num)
{
  switch (sig_num)
    {
    case SIGHUP:
    case SIGINT:
    case SIGQUIT:
    case SIGABRT:
    case SIGTERM:
      gimp_terminate (g_strsignal (sig_num));
      break;

    case SIGBUS:
    case SIGSEGV:
    case SIGFPE:
    default:
      gimp_fatal_error (g_strsignal (sig_num));
      break;
    }
}
Пример #8
0
static void G_GNUC_NORETURN fatal_signal_handler(int sig) {
	sigset_t sigset;

	sigemptyset(&sigset);
	sigprocmask(SIG_SETMASK, &sigset, NULL);

	g_print("\nLiferea did receive signal %d (%s).\n", sig, g_strsignal(sig));

	g_print("You have probably triggered a program bug. I will now try to \n");
	g_print("create a backtrace which you can attach to any support requests.\n\n");
	g_on_error_stack_trace(PACKAGE);

	_exit(1);
}
Пример #9
0
static void
panel_signal_handler (gint signum)
{
  static gboolean was_triggered = FALSE;

  /* avoid recursing this handler if we receive a
   * signal before the mainloop is started */
  if (was_triggered)
    return;
  was_triggered = TRUE;

  panel_debug (PANEL_DEBUG_MAIN,
               "received signal %s <%d>, %s panel",
               g_strsignal (signum), signum,
               signum == SIGUSR1 ? "restarting" : "quiting");

  panel_dbus_service_exit_panel (signum == SIGUSR1);
}
Пример #10
0
static void signal_handler(int signum) {
    switch(signum) {
    case SIGINT:
        rm_session_abort();
        break;
    case SIGFPE:
    case SIGABRT:
    case SIGSEGV:
        /* logging messages might have unexpected effects in a signal handler,
         * but that's probably the least thing we have to worry about in case of 
         * a segmentation fault.
         */
        rm_log_error_line(_("Aborting due to a fatal error. (signal received: %s)"),
                          g_strsignal(signum));
        rm_log_error_line(_("Please file a bug report (See rmlint -h)"));
        exit(1);
    default:
        break;
    }
}
Пример #11
0
/* Main Entry Point for this Daemon */
extern int main (int argc, char *argv[])
{
	sigset_t   signal_set;
	GMainLoop *main_loop  = NULL;
	GError    *gerror     = NULL;
	GThread   *sig_thread = NULL;
	GOptionContext *context = NULL;
	gpointer   trc = NULL;

	uid_t     real_user_id = 0;
	uid_t     effective_user_id = 0;
	gint      rc = 0;
	struct    passwd *userinfo = NULL;

	/* initialize threading and mainloop */
	g_type_init();
	main_loop = g_main_loop_new (NULL, FALSE);

	/* handle command line arguments */
	if ((rc = _handle_command_line( argc, argv, &context)) != EXIT_SUCCESS) {
		g_main_loop_unref (main_loop);
		exit (rc);
	}

	/* remember real and effective userid to restore them on shutdown */
	real_user_id = getuid ();
	if (gd_pch_effective_userid != NULL) {
		userinfo = getpwnam(gd_pch_effective_userid);
		effective_user_id = userinfo->pw_uid;
	}
	else {
		effective_user_id = geteuid();
		userinfo = getpwuid(effective_user_id);
		gd_pch_effective_userid = userinfo->pw_name;
	}

	g_message("%s-%s is in startup mode as user(%s)",
		PACKAGE_NAME, PACKAGE_VERSION, gd_pch_effective_userid);

	/* daemonize */
	if (!i_debug) {
		switch (_daemonize(gd_pch_pid_filename)) {
		case EXIT_SUCCESS:  /* grandchild */
			break;
		case EXIT_ERROR:    /* any error */
			exit (EXIT_FAILURE);
			break;
		default:            /* parent or child pids */
			exit (EXIT_SUCCESS);
			break;
		}
	}
	else {
		g_message("Skipping daemonizing process");
	}

	/* become the requested user */
	seteuid (effective_user_id);

	if (!i_debug) {
		/* block all signals */
		sigfillset (&signal_set);
		pthread_sigmask (SIG_BLOCK, &signal_set, NULL);

		/* create the signal handling thread */
		sig_thread = g_thread_create ((GThreadFunc)_thread_handle_signals,
				main_loop, TRUE, &gerror);
		if (gerror != NULL) {
			g_message("Create signal thread failed: %s", gerror->message);
			g_error_free(gerror);
			g_option_context_free(context);
			g_main_loop_unref (main_loop);
			exit (EXIT_FAILURE);
		}
	}

	_load_config();

	if (!phonefsod_dbus_setup()) {
		g_option_context_free(context);
		g_main_loop_unref(main_loop);
		exit(EXIT_FAILURE);
	}


	//notify = inotify_init();
	//inotify_add_watch(notify, PHONEFSOD_CONFIG, IN_MODIFY);

	/* Start glib main loop and run list_resources() */
	g_debug("entering glib main loop");
	g_timeout_add_seconds(1, fso_startup, NULL);
	g_main_loop_run(main_loop);

	phonefsod_dbus_shutdown();

	/* Cleanup and exit */
	if (!i_debug) {
		trc = g_thread_join(sig_thread);
		g_message("Signal thread was ended by a %s signal.",
				g_strsignal(GPOINTER_TO_INT(trc)) );

		pthread_sigmask (SIG_UNBLOCK, &signal_set, NULL);
		g_option_context_free (context);
	}
	g_main_loop_unref (main_loop);

//	if (incoming_calls)
//		free(incoming_calls);
//	if (outgoing_calls)
//		free(outgoing_calls);
	if (sim_pin)
		free(sim_pin);
	if (pdp_apn)
		free(pdp_apn);
	if (pdp_user)
		free(pdp_user);
	if (pdp_password)
		free(pdp_password);

	/* become the privledged user again */
	seteuid (real_user_id);

	/* Remove the PID File to show we are inactive */
	if (!i_debug) {
		if (g_unlink(gd_pch_pid_filename) != 0) {
			g_warning("Main Error: cannot unlink/remove pidfile %s: %s",
					gd_pch_pid_filename, strerror(errno));
		}
	}

	/* write shutdown messages */
	g_message("%s-%s clean shutdown", PACKAGE_NAME, PACKAGE_VERSION);

	exit (EXIT_SUCCESS);
}
Пример #12
0
/*
 * _process_signals()
 *
 * Handle/Process linux signals for the whole multi-threaded application.
 *
 * Params:
 *    sig -- current linux signal
 *
 * Returns/Affects:
 *   returns current value of the atomic int gd_flag_exit
 *   returns true (or current value) if nothing needs done
 *   returns 0 or false if exit is required
*/
static gint _process_signals ( siginfo_t *signal_info)
{
	int rval = g_atomic_int_get(&gd_flag_exit); /* use existing value */
	gint sig = 0;
	gchar *pch = "<unknown>";

	g_return_val_if_fail (signal_info != NULL, 0);
	sig = signal_info->si_signo;

	/* look to see what signal has been caught */
	switch ( sig ) {
	case SIGHUP:    /* often used to reload configuration */
        case SIGUSR1:   /* Any user function */
		switch (signal_info->si_code) {
		case SI_USER:  pch="kill(2) or raise(3)"; break;
		case SI_KERNEL:  pch="Sent by the kernel."; break;
		case SI_QUEUE:  pch="sigqueue(2)"; break;
		case SI_TIMER:  pch="POSIX timer expired"; break;
		case SI_MESGQ:  pch="POSIX message queue state changed"; break;
		case SI_ASYNCIO:  pch="AIO completed"; break;
		case SI_SIGIO:  pch="queued SIGIO"; break;
		case SI_TKILL:  pch="tkill(2) or tgkill(2)"; break;
		default: pch = "<unknown>"; break;
		}
		g_debug("%s received from => %s ?[pid=%d, uid=%d]{Ignored}",
                  g_strsignal(sig), pch, signal_info->si_pid,signal_info->si_uid);
		break;
	case SIGCHLD:   /* some child ended */
		switch (signal_info->si_code) {
		case CLD_EXITED: pch = "child has exited"; break;
		case CLD_KILLED: pch = "child was killed"; break;
		case CLD_DUMPED: pch = "child terminated abnormally"; break;
		case CLD_TRAPPED: pch = "traced child has trapped"; break;
		case CLD_STOPPED: pch = "child has stopped"; break;
		case CLD_CONTINUED: pch = "stopped child has continued"; break;
		default: pch = "<unknown>"; break;
		}
		g_debug("%s received for pid => %d, w/rc => %d for this reason => %s {Ignored}",
                    g_strsignal(sig), signal_info->si_pid, signal_info->si_status, pch);
		break;
	case SIGQUIT:   /* often used to signal an orderly shutdown */
	case SIGINT:    /* often used to signal an orderly shutdown */
	case SIGPWR:    /* Power Failure */
	case SIGKILL:   /* Fatal Exit flag */
	case SIGTERM:   /* Immediately Fatal Exit flag */
		switch (signal_info->si_code) {
		case SI_USER:  pch="kill(2) or raise(3)"; break;
		case SI_KERNEL:  pch="Sent by the kernel."; break;
		case SI_QUEUE:  pch="sigqueue(2)"; break;
		case SI_TIMER:  pch="POSIX timer expired"; break;
		case SI_MESGQ:  pch="POSIX message queue state changed"; break;
		case SI_ASYNCIO:  pch="AIO completed"; break;
		case SI_SIGIO:  pch="queued SIGIO"; break;
		case SI_TKILL:  pch="tkill(2) or tgkill(2)"; break;
		default: pch = "<unknown>"; break;
		}
		g_debug("%s received from => %s ?[pid=%d, uid=%d]{Exiting}",
			g_strsignal(sig), pch, signal_info->si_pid,
			signal_info->si_uid);
		rval = 0;
		break;
	default:
		g_debug("%s received => {Ignored}", g_strsignal(sig));
		break;
	} /* end switch */

	return (rval);
}
static gboolean
sendmail_send_to_sync (CamelTransport *transport,
                       CamelMimeMessage *message,
                       CamelAddress *from,
                       CamelAddress *recipients,
		       gboolean *out_sent_message_saved,
                       GCancellable *cancellable,
                       GError **error)
{
	CamelHeaderRaw *header, *savedbcc, *n, *tail;
	const gchar *from_addr, *addr;
	GPtrArray *argv_arr;
	gint i, len, fd[2], nullfd, wstat;
	CamelStream *filter;
	CamelMimeFilter *crlf;
	sigset_t mask, omask;
	CamelStream *out;
	CamelSendmailSettings *settings;
	const gchar *binary = SENDMAIL_PATH;
	gchar *custom_binary = NULL, *custom_args = NULL;
	gboolean success;
	pid_t pid;

	success = camel_internet_address_get (
		CAMEL_INTERNET_ADDRESS (from), 0, NULL, &from_addr);

	if (!success) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Failed to read From address"));
		return FALSE;
	}

	settings = CAMEL_SENDMAIL_SETTINGS (camel_service_ref_settings (CAMEL_SERVICE (transport)));

	if (!camel_sendmail_settings_get_send_in_offline (settings)) {
		CamelSession *session;
		gboolean is_online;

		session = camel_service_ref_session (CAMEL_SERVICE (transport));
		is_online = session && camel_session_get_online (session);
		g_clear_object (&session);

		if (!is_online) {
			g_set_error (
				error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE,
				_("Message send in offline mode is disabled"));
			return FALSE;
		}
	}

	if (camel_sendmail_settings_get_use_custom_binary (settings)) {
		custom_binary = camel_sendmail_settings_dup_custom_binary (settings);
		if (custom_binary && *custom_binary)
			binary = custom_binary;
	}

	if (camel_sendmail_settings_get_use_custom_args (settings)) {
		custom_args = camel_sendmail_settings_dup_custom_args (settings);
		/* means no arguments used */
		if (!custom_args)
			custom_args = g_strdup ("");
	}

	g_object_unref (settings);

	len = camel_address_length (recipients);
	for (i = 0; i < len; i++) {
		success = camel_internet_address_get (
			CAMEL_INTERNET_ADDRESS (recipients), i, NULL, &addr);

		if (!success) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not parse recipient list"));
			g_free (custom_binary);
			g_free (custom_args);

			return FALSE;
		}
	}

	argv_arr = parse_sendmail_args (
		binary,
		custom_args ? custom_args : "-i -f %F -- %R",
		from_addr,
		recipients);

	if (!argv_arr) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Could not parse arguments"));

		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	/* unlink the bcc headers */
	savedbcc = NULL;
	tail = (CamelHeaderRaw *) &savedbcc;

	header = (CamelHeaderRaw *) &CAMEL_MIME_PART (message)->headers;
	n = header->next;
	while (n != NULL) {
		if (!g_ascii_strcasecmp (n->name, "Bcc")) {
			header->next = n->next;
			tail->next = n;
			n->next = NULL;
			tail = n;
		} else {
			header = n;
		}

		n = header->next;
	}

	if (pipe (fd) == -1) {
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not create pipe to '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	}

	/* Block SIGCHLD so the calling application doesn't notice
	 * sendmail exiting before we do.
	 */
	sigemptyset (&mask);
	sigaddset (&mask, SIGCHLD);
	sigprocmask (SIG_BLOCK, &mask, &omask);

	pid = fork ();
	switch (pid) {
	case -1:
		g_set_error (
			error, G_IO_ERROR,
			g_io_error_from_errno (errno),
			_("Could not fork '%s': %s: "
			"mail not sent"), binary, g_strerror (errno));
		close (fd[0]);
		close (fd[1]);
		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);
		g_ptr_array_free (argv_arr, TRUE);

		return FALSE;
	case 0:
		/* Child process */
		nullfd = open ("/dev/null", O_RDWR);
		dup2 (fd[0], STDIN_FILENO);
		if (nullfd != -1) {
			/*dup2 (nullfd, STDOUT_FILENO);
			  dup2 (nullfd, STDERR_FILENO);*/
			close (nullfd);
		}
		close (fd[1]);

		execv (binary, (gchar **) argv_arr->pdata);
		_exit (255);
	}

	g_ptr_array_free (argv_arr, TRUE);

	/* Parent process. Write the message out. */
	close (fd[0]);
	out = camel_stream_fs_new_with_fd (fd[1]);

	/* XXX Workaround for lame sendmail implementations
	 *     that can't handle CRLF eoln sequences. */
	filter = camel_stream_filter_new (out);
	crlf = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_DECODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_ONLY);
	camel_stream_filter_add (CAMEL_STREAM_FILTER (filter), crlf);
	g_object_unref (crlf);
	g_object_unref (out);

	out = (CamelStream *) filter;
	if (camel_data_wrapper_write_to_stream_sync (
		CAMEL_DATA_WRAPPER (message), out, cancellable, error) == -1
	    || camel_stream_close (out, cancellable, error) == -1) {
		g_object_unref (out);
		g_prefix_error (error, _("Could not send message: "));

		/* Wait for sendmail to exit. */
		while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
			;

		sigprocmask (SIG_SETMASK, &omask, NULL);

		/* restore the bcc headers */
		header->next = savedbcc;
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_object_unref (out);

	/* Wait for sendmail to exit. */
	while (waitpid (pid, &wstat, 0) == -1 && errno == EINTR)
		;

	sigprocmask (SIG_SETMASK, &omask, NULL);

	/* restore the bcc headers */
	header->next = savedbcc;

	if (!WIFEXITED (wstat)) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("'%s' exited with signal %s: mail not sent."),
			binary, g_strsignal (WTERMSIG (wstat)));
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	} else if (WEXITSTATUS (wstat) != 0) {
		if (WEXITSTATUS (wstat) == 255) {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("Could not execute '%s': mail not sent."),
				binary);
		} else {
			g_set_error (
				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				_("'%s' exited with status %d: "
				"mail not sent."),
				binary, WEXITSTATUS (wstat));
		}
		g_free (custom_binary);
		g_free (custom_args);

		return FALSE;
	}

	g_free (custom_binary);
	g_free (custom_args);

	return TRUE;
}