static IncState inc_pop3_session_do(IncSession *session) { Pop3Session *pop3_session = POP3_SESSION(session->session); IncProgressDialog *inc_dialog = (IncProgressDialog *)session->data; gchar *server; gchar *account_name; gushort port; gchar *buf; debug_print("getting new messages of account %s...\n", pop3_session->ac_prefs->account_name); pop3_session->ac_prefs->last_pop_login_time = time(NULL); buf = g_strdup_printf(_("%s: Retrieving new messages"), pop3_session->ac_prefs->recv_server); gtk_window_set_title(GTK_WINDOW(inc_dialog->dialog->window), buf); g_free(buf); server = pop3_session->ac_prefs->recv_server; account_name = pop3_session->ac_prefs->account_name; #ifdef USE_GNUTLS port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : pop3_session->ac_prefs->ssl_pop == SSL_TUNNEL ? 995 : 110; SESSION(pop3_session)->ssl_type = pop3_session->ac_prefs->ssl_pop; if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) SESSION(pop3_session)->nonblocking = pop3_session->ac_prefs->use_nonblocking_ssl; #else if (pop3_session->ac_prefs->ssl_pop != SSL_NONE) { if (alertpanel_full(_("Insecure connection"), _("This connection is configured to be secured " "using SSL, but SSL is not available in this " "build of Claws Mail. \n\n" "Do you want to continue connecting to this " "server? The communication would not be " "secure."), GTK_STOCK_CANCEL, _("Con_tinue connecting"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) return INC_CANCEL; } port = pop3_session->ac_prefs->set_popport ? pop3_session->ac_prefs->popport : 110; #endif buf = g_strdup_printf(_("Account '%s': Connecting to POP3 server: %s:%d..."), account_name, server, port); statuswindow_print_all("%s", buf); log_message(LOG_PROTOCOL, "%s\n", buf); progress_dialog_set_label(inc_dialog->dialog, buf); GTK_EVENTS_FLUSH(); g_free(buf); session_set_timeout(SESSION(pop3_session), prefs_common.io_timeout_secs * 1000); if (session_connect(SESSION(pop3_session), server, port) < 0) { if(!prefs_common.no_recv_err_panel) { if((prefs_common.recv_dialog_mode == RECV_DIALOG_ALWAYS) || ((prefs_common.recv_dialog_mode == RECV_DIALOG_MANUAL) && focus_window)) { manage_window_focus_in(inc_dialog->dialog->window, NULL, NULL); } alertpanel_error(_("Can't connect to POP3 server: %s:%d"), server, port); manage_window_focus_out(inc_dialog->dialog->window, NULL, NULL); } else { log_error(LOG_PROTOCOL, _("Can't connect to POP3 server: %s:%d\n"), server, port); } session->inc_state = INC_CONNECT_ERROR; statuswindow_pop_all(); return INC_CONNECT_ERROR; } while (session_is_running(SESSION(pop3_session)) && session->inc_state != INC_CANCEL) gtk_main_iteration(); if (session->inc_state == INC_SUCCESS) { switch (pop3_session->error_val) { case PS_SUCCESS: switch (SESSION(pop3_session)->state) { case SESSION_ERROR: if (pop3_session->state == POP3_READY) session->inc_state = INC_CONNECT_ERROR; else session->inc_state = INC_ERROR; break; case SESSION_EOF: session->inc_state = INC_EOF; break; case SESSION_TIMEOUT: session->inc_state = INC_TIMEOUT; break; default: session->inc_state = INC_SUCCESS; break; } break; case PS_AUTHFAIL: session->inc_state = INC_AUTH_FAILED; break; case PS_IOERR: session->inc_state = INC_IO_ERROR; break; case PS_SOCKET: session->inc_state = INC_SOCKET_ERROR; break; case PS_LOCKBUSY: session->inc_state = INC_LOCKED; break; default: session->inc_state = INC_ERROR; break; } } session_disconnect(SESSION(pop3_session)); statusbar_pop_all(); return session->inc_state; }
gint lock_mbox(const gchar *base, LockType type) { #ifdef G_OS_UNIX gint retval = 0; if (type == LOCK_FILE) { gchar *lockfile, *locklink; gint retry = 0; FILE *lockfp; lockfile = g_strdup_printf("%s.%d", base, getpid()); if ((lockfp = g_fopen(lockfile, "wb")) == NULL) { FILE_OP_ERROR(lockfile, "fopen"); g_warning("can't create lock file %s\n", lockfile); g_warning("use 'flock' instead of 'file' if possible.\n"); g_free(lockfile); return -1; } if (fprintf(lockfp, "%d\n", getpid()) < 0) { FILE_OP_ERROR(lockfile, "fprintf"); g_free(lockfile); fclose(lockfp); return -1; } if (fclose(lockfp) == EOF) { FILE_OP_ERROR(lockfile, "fclose"); g_free(lockfile); return -1; } locklink = g_strconcat(base, ".lock", NULL); while (link(lockfile, locklink) < 0) { FILE_OP_ERROR(lockfile, "link"); if (retry >= 5) { g_warning("can't create %s\n", lockfile); claws_unlink(lockfile); g_free(lockfile); return -1; } if (retry == 0) g_warning("mailbox is owned by another" " process, waiting...\n"); retry++; sleep(5); } claws_unlink(lockfile); g_free(lockfile); } else if (type == LOCK_FLOCK) { gint lockfd; gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; #endif #if HAVE_FLOCK if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #else if ((lockfd = g_open(base, O_RDWR, 0)) < 0) { #endif FILE_OP_ERROR(base, "open"); return -1; } #if HAVE_FCNTL_H && !defined(G_OS_WIN32) if (fcntl(lockfd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s (%s)", base, strerror(errno)); return -1; } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(lockfd, LOCK_EX|LOCK_NB) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(lockfd, F_TLOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't lock %s\n", base); if (close(lockfd) < 0) perror("close"); return -1; } retval = lockfd; } else { g_warning("invalid lock type\n"); return -1; } return retval; #else return -1; #endif /* G_OS_UNIX */ } gint unlock_mbox(const gchar *base, gint fd, LockType type) { if (type == LOCK_FILE) { gchar *lockfile; lockfile = g_strconcat(base, ".lock", NULL); if (claws_unlink(lockfile) < 0) { FILE_OP_ERROR(lockfile, "unlink"); g_free(lockfile); return -1; } g_free(lockfile); return 0; } else if (type == LOCK_FLOCK) { gboolean fcntled = FALSE; #if HAVE_FCNTL_H && !defined(G_OS_WIN32) struct flock fl; fl.l_type = F_UNLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; if (fcntl(fd, F_SETLK, &fl) == -1) { g_warning("can't fnctl %s", base); } else { fcntled = TRUE; } #endif #if HAVE_FLOCK if (flock(fd, LOCK_UN) < 0 && !fcntled) { perror("flock"); #else #if HAVE_LOCKF if (lockf(fd, F_ULOCK, 0) < 0 && !fcntled) { perror("lockf"); #else { #endif #endif /* HAVE_FLOCK */ g_warning("can't unlock %s\n", base); if (close(fd) < 0) perror("close"); return -1; } if (close(fd) < 0) { perror("close"); return -1; } return 0; } g_warning("invalid lock type\n"); return -1; } gint copy_mbox(gint srcfd, const gchar *dest) { FILE *dest_fp; ssize_t n_read; gchar buf[BUFSIZ]; gboolean err = FALSE; int save_errno = 0; if (srcfd < 0) { return -1; } if ((dest_fp = g_fopen(dest, "wb")) == NULL) { FILE_OP_ERROR(dest, "fopen"); return -1; } if (change_file_mode_rw(dest_fp, dest) < 0) { FILE_OP_ERROR(dest, "chmod"); g_warning("can't change file mode\n"); } while ((n_read = read(srcfd, buf, sizeof(buf))) > 0) { if (n_read == -1 && errno != 0) { save_errno = errno; break; } if (fwrite(buf, 1, n_read, dest_fp) < n_read) { g_warning("writing to %s failed.\n", dest); fclose(dest_fp); claws_unlink(dest); return -1; } } if (save_errno != 0) { g_warning("error %d reading mbox: %s\n", save_errno, strerror(save_errno)); err = TRUE; } if (fclose(dest_fp) == EOF) { FILE_OP_ERROR(dest, "fclose"); err = TRUE; } if (err) { claws_unlink(dest); return -1; } return 0; } void empty_mbox(const gchar *mbox) { FILE *fp; if ((fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); g_warning("can't truncate mailbox to zero.\n"); return; } fclose(fp); } gint export_list_to_mbox(GSList *mlist, const gchar *mbox) /* return values: -2 skipped, -1 error, 0 OK */ { GSList *cur; MsgInfo *msginfo; FILE *msg_fp; FILE *mbox_fp; gchar buf[BUFFSIZE]; int err = 0; gint msgs = 1, total = g_slist_length(mlist); if (g_file_test(mbox, G_FILE_TEST_EXISTS) == TRUE) { if (alertpanel_full(_("Overwrite mbox file"), _("This file already exists. Do you want to overwrite it?"), GTK_STOCK_CANCEL, _("Overwrite"), NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT) != G_ALERTALTERNATE) { return -2; } } if ((mbox_fp = g_fopen(mbox, "wb")) == NULL) { FILE_OP_ERROR(mbox, "fopen"); alertpanel_error(_("Could not create mbox file:\n%s\n"), mbox); return -1; } #ifdef HAVE_FGETS_UNLOCKED flockfile(mbox_fp); #endif statuswindow_print_all(_("Exporting to mbox...")); for (cur = mlist; cur != NULL; cur = cur->next) { int len; gchar buft[BUFFSIZE]; msginfo = (MsgInfo *)cur->data; msg_fp = procmsg_open_message(msginfo); if (!msg_fp) { continue; } #ifdef HAVE_FGETS_UNLOCKED flockfile(msg_fp); #endif strncpy2(buf, msginfo->from ? msginfo->from : cur_account && cur_account->address ? cur_account->address : "unknown", sizeof(buf)); extract_address(buf); if (fprintf(mbox_fp, "From %s %s", buf, ctime_r(&msginfo->date_t, buft)) < 0) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } buf[0] = '\0'; /* write email to mboxrc */ while (SC_FGETS(buf, sizeof(buf), msg_fp) != NULL) { /* quote any From, >From, >>From, etc., according to mbox format specs */ int offset; offset = 0; /* detect leading '>' char(s) */ while ((buf[offset] == '>')) { offset++; } if (!strncmp(buf+offset, "From ", 5)) { if (SC_FPUTC('>', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } if (SC_FPUTS(buf, mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } /* force last line to end w/ a newline */ len = strlen(buf); if (len > 0) { len--; if ((buf[len] != '\n') && (buf[len] != '\r')) { if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } } } /* add a trailing empty line */ if (SC_FPUTC('\n', mbox_fp) == EOF) { err = -1; #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); goto out; } #ifdef HAVE_FGETS_UNLOCKED funlockfile(msg_fp); #endif fclose(msg_fp); statusbar_progress_all(msgs++,total, 500); if (msgs%500 == 0) GTK_EVENTS_FLUSH(); } out: statusbar_progress_all(0,0,0); statuswindow_pop_all(); #ifdef HAVE_FGETS_UNLOCKED funlockfile(mbox_fp); #endif fclose(mbox_fp); return err; }