static void send_receive (EMailSession *session, gboolean allow_send) { CamelFolder *local_outbox; struct _send_data *data; GList *scan; if (send_data) /* Send Receive is already in progress */ return; if (!camel_session_get_online (CAMEL_SESSION (session))) return; local_outbox = e_mail_session_get_local_folder ( session, E_MAIL_LOCAL_FOLDER_OUTBOX); data = build_infra (session, allow_send); for (scan = data->infos; scan != NULL; scan = scan->next) { struct _send_info *info = scan->data; if (!CAMEL_IS_SERVICE (info->service)) continue; switch (info->type) { case SEND_RECEIVE: mail_fetch_mail ( CAMEL_STORE (info->service), CAMEL_FETCH_OLD_MESSAGES, -1, E_FILTER_SOURCE_INCOMING, mail_provider_fetch_lock, mail_provider_fetch_unlock, mail_provider_fetch_inbox_folder, info->cancellable, receive_get_folder, info, receive_status, info, receive_done, info); break; case SEND_SEND: /* todo, store the folder in info? */ mail_send_queue ( session, local_outbox, CAMEL_TRANSPORT (info->service), E_FILTER_SOURCE_OUTGOING, info->cancellable, receive_get_folder, info, receive_status, info, send_done, info); break; case SEND_UPDATE: receive_update_got_store ( CAMEL_STORE (info->service), info); break; default: break; } } return ; }
static gboolean auto_timeout (gpointer data) { EMailSession *session; struct _auto_data *info = data; CamelService *service; const char *uid; session = info->session; uid = e_source_get_uid (info->account); service = camel_session_ref_service ( CAMEL_SESSION (session), uid); printf("Timeout for %s: %p\n", uid, service); g_return_val_if_fail (CAMEL_IS_SERVICE (service), TRUE); if (camel_session_get_online (CAMEL_SESSION (session))) mail_receive_service (service); return TRUE; }
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; }
static gboolean pop3_store_connect_sync (CamelService *service, GCancellable *cancellable, GError **error) { CamelPOP3Store *store = (CamelPOP3Store *) service; CamelPOP3Engine *pop3_engine; CamelSettings *settings; CamelSession *session; const gchar *user_data_dir; gboolean success = TRUE; gchar *mechanism; session = camel_service_ref_session (service); user_data_dir = camel_service_get_user_data_dir (service); settings = camel_service_ref_settings (service); mechanism = camel_network_settings_dup_auth_mechanism ( CAMEL_NETWORK_SETTINGS (settings)); g_object_unref (settings); if (!camel_session_get_online (session)) { g_set_error ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, _("You must be working online to complete this operation")); success = FALSE; goto exit; } g_mutex_lock (&store->priv->property_lock); if (store->priv->cache == NULL) { CamelDataCache *cache; cache = camel_data_cache_new (user_data_dir, error); if (cache != NULL) { /* Ensure cache will never expire, otherwise * it causes redownload of messages. */ camel_data_cache_set_expire_age (cache, -1); camel_data_cache_set_expire_access (cache, -1); store->priv->cache = g_object_ref (cache); g_object_unref (cache); } } g_mutex_unlock (&store->priv->property_lock); success = connect_to_server (service, cancellable, error); if (!success) goto exit; success = camel_session_authenticate_sync ( session, service, mechanism, cancellable, error); if (!success) goto exit; /* Now that we are in the TRANSACTION state, * try regetting the capabilities */ pop3_engine = camel_pop3_store_ref_engine (store); if (pop3_engine) { pop3_engine->state = CAMEL_POP3_ENGINE_TRANSACTION; if (!camel_pop3_engine_reget_capabilities (pop3_engine, cancellable, error)) success = FALSE; g_clear_object (&pop3_engine); } else { g_set_error_literal ( error, CAMEL_SERVICE_ERROR, CAMEL_SERVICE_ERROR_UNAVAILABLE, _("You must be working online to complete this operation")); success = FALSE; } exit: g_free (mechanism); g_object_unref (session); if (!success) { /* to not leak possible connection to the server */ g_mutex_lock (&store->priv->property_lock); g_clear_object (&store->priv->engine); g_mutex_unlock (&store->priv->property_lock); } return success; }