📄 mail.c
字号:
if (mp->pipe >= 0) { if (close(mp->pipe) < 0 && errno == EINTR) close(mp->pipe); } mp->pipe = -1; if (mp->read_gstring) g_string_free(mp->read_gstring, TRUE); mp->read_gstring = NULL; mail_fetch->mail_count = 0; mail_fetch->new_mail_count = 0; mail_fetch->old_mail_count = 0; mail_fetch->need_animation = FALSE; mail_fetch->busy = FALSE; force_mail_check = TRUE; }static gbooleanrun_fetch_program(void) { Mailbox *mbox; Mailproc *mp = (Mailproc *) mail_fetch->private; GList *list; if ( !mail_fetch->busy && !mp->read_gstring && mp->command && *(mp->command) != '\0' ) { mail_fetch->busy = TRUE; for (list = mailbox_list; list; list = list->next) { mbox = (Mailbox *) list->data; if ( mbox->account->mboxtype == MBOX_FETCH || mbox->account->mboxtype == MBOX_FETCH_TOOLTIP ) { mbox->mail_count = 0; mbox->new_mail_count = 0; mbox->old_mail_count = 0; } } pipe_command(mp); if (mp->pipe >= 0) return TRUE; } return FALSE; }static gpointermail_check_thread(void *data) { Mailbox *mbox = (Mailbox *) data; gchar buf[256]; gint external; buf[0] = '\0'; if (_GK.debug_level & DEBUG_MAIL) { format_remote_mbox_name(mbox, buf, sizeof(buf)); printf("Start mail_check_thread: %s at %d:%d\n", buf, gkrellm_get_current_time()->tm_min, gkrellm_get_current_time()->tm_sec); } external = mbox->account->mboxtype & MBOX_EXTERNAL; if ( (*(mbox->check_func))(external ? mbox->data : mbox) == FALSE) { mbox->mail_count = 0; mbox->new_mail_count = 0; mbox->need_animation = FALSE; } else mbox_set_animation_state(mbox); if (_GK.debug_level & DEBUG_MAIL) printf("Stop mail_check_thread: %s at %d:%d\n", buf, gkrellm_get_current_time()->tm_min, gkrellm_get_current_time()->tm_sec); mbox->busy = FALSE; mbox->thread = NULL; return NULL; }static voidupdate_mail(void) { Mailbox *mbox; GList *list; gint external, prev_new_mail_count, any_busy; gint local_check = FALSE, remote_check = FALSE, fetch_check; static gint second_count, minute_count, sound_inhibit; if (!enable_mail || !mailbox_list) return; if (GK.minute_tick && (++minute_count % remote_check_timeout) == 0) remote_check = TRUE; if (GK.second_tick && (++second_count % local_check_timeout) == 0) local_check = TRUE; fetch_check = fetch_check_is_local ? local_check : remote_check; if (remote_check || local_check) mua_is_launched(); /* update pipe, avoid lingering zombie */ if ( force_mail_check || ( GK.second_tick && !(mute_mode && super_mute_mode) && !(mua_inhibit_mode && mail_user_agent.pipe >= 0) ) ) { prev_new_mail_count = new_mail_count; total_mail_count = 0; new_mail_count = 0; run_animation = FALSE; remote_check |= force_mail_check; local_check |= force_mail_check; fetch_check |= force_mail_check; if (force_mail_check) minute_count = second_count = 0; any_busy = FALSE; for (list = mailbox_list; list; list = list->next) { mbox = (Mailbox *) list->data; external = mbox->account->mboxtype & MBOX_EXTERNAL; switch (mbox->account->mboxtype & MBOX_CHECK_TYPE_MASK) { case MBOX_CHECK_FETCH: if (((Mailproc *)(mail_fetch->private))->read_gstring) read_mail_fetch(); if (fetch_check) (*mbox->check_func)(mbox); break; case MBOX_CHECK_INLINE: /* Local mailbox or maildir check */ if (local_check) { if (mbox->check_func) (*mbox->check_func)(external ? mbox->data : mbox); mbox_set_animation_state(mbox); } break; case MBOX_CHECK_THREADED: if (remote_check && !mbox->busy && mbox->check_func) { mbox->busy = TRUE; mbox->thread = g_thread_create(mail_check_thread, mbox, FALSE, NULL); } else if ( (_GK.debug_level & DEBUG_MAIL) && remote_check && mbox->busy ) printf(" %s thread busy\n", mbox->account->server); break; default: /* Unknown or pseudo mail box type */ continue; } /* If a mailbox check is busy (thread or remote fetch program | running), use previous counts until the check is done. */ if (mbox->busy) { total_mail_count += mbox->prev_mail_count; new_mail_count += mbox->prev_new_mail_count; run_animation |= mbox->prev_need_animation; any_busy = TRUE; } else { total_mail_count += mbox->mail_count; new_mail_count += mbox->new_mail_count; if (mbox->new_mail_count && cont_animation_mode) mbox->need_animation = TRUE; run_animation |= mbox->need_animation; mbox->prev_mail_count = mbox->mail_count; mbox->prev_new_mail_count = mbox->new_mail_count; mbox->prev_need_animation = mbox->need_animation; if (mbox->warn_msg && !mbox->warned) { gkrellm_message_dialog(NULL, mbox->warn_msg); mbox->warned = TRUE; } } } force_mail_check = FALSE; if ((_GK.debug_level & DEBUG_MAIL) && (local_check || remote_check)) g_print("Mail check totals: total=%d new=%d anim=%d [%d,%d,%d]\n", total_mail_count, new_mail_count, run_animation, local_check, remote_check, fetch_check); if ( prev_new_mail_count != new_mail_count || tooltip->active_tips_data == NULL ) update_tooltip(); /* Run the notify (sound) command if the new mail count goes up, | and if the various modes permit. Ensure a sound command is | issued only once per remote check interval by locking it out | if a new mail count triggers the sound and there are other | remote threads still busy. */ if ( !sound_inhibit && !mute_mode && new_mail_count > prev_new_mail_count && mail_notify && mail_notify[0] != '\0' ) { g_spawn_command_line_async(mail_notify, NULL /* GError */); if (any_busy) sound_inhibit = TRUE; } if (!any_busy) sound_inhibit = FALSE; } if (mute_mode && (GK.timer_ticks % 15) < 3) /* Asymmetric blink */ draw_mail_text_decal(MUTE_FLAG, MUTE_FLAG); else draw_mail_text_decal(new_mail_count, total_mail_count); if (run_animation && (animation_mode & ANIMATION_PENGUIN)) update_krell_animation_frame(); else anim_frame = 0; if ((GK.timer_ticks % _GK.decal_mail_delay) == 0) { if (run_animation) { if (animation_mode & ANIMATION_ENVELOPE) { ++decal_frame; if (decal_frame >= _GK.decal_mail_frames) decal_frame = 1; } else decal_frame = 0; } else decal_frame = 1; } gkrellm_draw_decal_pixmap(mail, DECAL(mail), decal_frame); /* All the animation frame drawing is done with the general krell code. */ KRELL(mail)->previous = 0; gkrellm_update_krell(mail, KRELL(mail), anim_frame); gkrellm_draw_panel_layers(mail); }static gintmail_expose_event(GtkWidget *widget, GdkEventExpose *ev) { if (widget == mail->drawing_area) gdk_draw_drawable(widget->window, gkrellm_draw_GC(1), mail->pixmap, ev->area.x, ev->area.y, ev->area.x, ev->area.y, ev->area.width, ev->area.height); return FALSE; } /* The mua launch button also optionally stops animations and resets | remote mail counts. So this routine decides if it should be enabled. */static voidset_mua_button_sensitivity(void) { if ( *(mail_user_agent.command) || reset_remote_mode || (animation_mode && !cont_animation_mode) ) gkrellm_set_button_sensitive(mua_button, TRUE); else gkrellm_set_button_sensitive(mua_button, FALSE); } /* Callback for the message count decal button. */static voidcb_mail_button(GkrellmDecalbutton *button) { GList *list; Mailbox *mbox; if (reset_remote_mode) { for (list = mailbox_list; list; list = list->next) { mbox = (Mailbox *) list->data; if ( (mbox->account->mboxtype & MBOX_CHECK_THREADED) || (mbox->account->mboxtype & MBOX_CHECK_FETCH) || mbox->account->mboxtype == MBOX_FETCH_TOOLTIP ) { GDK_THREADS_ENTER(); mbox->mail_count = 0; mbox->new_mail_count = 0; mbox->old_mail_count = 0; mbox->need_animation = FALSE; GDK_THREADS_LEAVE(); } } } if (!cont_animation_mode) { for (list = mailbox_list; list; list = list->next) { mbox = (Mailbox *) list->data; mbox->need_animation = FALSE; } run_animation = FALSE; } if (enable_multimua) { if (mail_user_agent.command && *mail_user_agent.command != '\0') g_spawn_command_line_async(mail_user_agent.command, NULL); } else if (!mua_is_launched()) pipe_command(&mail_user_agent); else { check_timeout = 0; if (_GK.debug_level & DEBUG_MAIL) g_print("Mail user agent is already running.\n"); } } /* Callback for any button clicks on the Mail panel. Must exclude | button 1 clicks on the message decal button. */static gintcb_panel_press(GtkWidget *widget, GdkEventButton *ev) { GkrellmDecal *d = mail_icon_decal; if (ev->button == 3) gkrellm_open_config_window(mon_mail); /* button 2 anywhere in the panel toggles the mute mode. */ if (ev->button == 2) { mute_mode = !mute_mode; /* If coming out of mute mode and mail checking was inhibited, | force a check. */ if ( ! mute_mode && super_mute_mode && (! mua_is_launched() || ! mua_inhibit_mode) ) force_mail_check = TRUE; } /* Button 1 press on the envelope - must exclude the message count button. */ if (ev->button == 1 && ev->x >= d->x && ev->x < d->x + d->w) force_mail_check = TRUE; return FALSE; } static voiddup_account(MailAccount *dst, MailAccount *src) { dst->path = g_strdup(src->path); dst->homedir_path = g_strdup(src->homedir_path); dst->server = g_strdup(src->server); dst->username = g_strdup(src->username); dst->password = g_strdup(src->password); dst->imapfolder = g_strdup(src->imapfolder); dst->mboxtype = src->mboxtype; dst->protocol = src->protocol; dst->authmech = src->authmech; dst->port = src->port; dst->use_ssl = src->use_ssl; }static gbooleanget_local_mboxtype(MailAccount *account) { gchar *path; if (!account->path) return FALSE; if (*(account->path) == '~') { account->homedir_path = account->path; account->path = g_strdup_printf("%s%s", gkrellm_homedir(), account->homedir_path + 1); } if (g_file_test(account->path, G_FILE_TEST_IS_DIR)) { path = g_build_path(G_DIR_SEPARATOR_S, account->path, "new", NULL); if (g_file_test(path, G_FILE_TEST_IS_DIR)) account->mboxtype = MBOX_MAILDIR; else account->mboxtype = MBOX_MH_DIR; g_free(path); } else account->mboxtype = MBOX_MBOX; return TRUE; }static Mailbox *add_mailbox(MailAccount *account) { Mailbox *mbox; if (!account) return NULL; mbox = g_new0(Mailbox, 1); mbox->account = account; if (account->path) { if (*(account->path) == '~') { account->homedir_path = account->path; account->path = g_strdup_printf("%s%s", gkrellm_homedir(), account->homedir_path + 1); } if (account->mboxtype == MBOX_MAILDIR) mbox->check_func = check_maildir; else if (account->mboxtype == MBOX_MH_DIR) { mbox->check_func = check_mh_dir; checking_mh_mail = TRUE; } else mbox->check_func = check_mbox; } else if (account->mboxtype == MBOX_REMOTE) { switch (account->protocol) { case PROTO_POP3: mbox->check_func = check_pop3; break; case PROTO_IMAP: mbox->check_func = check_imap; break; default: g_free(mbox); mbox = NULL; } } else { g_free(mbox); mbox = NULL; } if (mbox) mailbox_list = g_list_append(mailbox_list, mbox); return mbox; } /* Pre 1.2.7 mailbox config parsing. */static Mailbox *old_add_mailbox(gchar *arg) { Mailbox *mbox; MailAccount *account; gchar parms[4][CFG_BUFSIZE]; gint n; gchar *p; account = g_new0(MailAccount, 1); n = sscanf(arg, "%s %s %s %s", parms[0], parms[1], parms[2], parms[3]); if (n == 1) { account->path = g_strdup(parms[0]); get_local_mboxtype(account); mbox = add_mailbox(account); return mbox; } mbox = g_new0(Mailbox, 1); mbox->account = account; switch (n) { case 3: account->mboxtype = MBOX_REMOTE; if ((p = strchr(parms[0], ':')) != NULL) *p++ = '\0'; account->server = g_strdup(parms[0]); account->port = (p && *p) ? atoi(p) : atoi(DEFAULT_POP3_PORT); account->protocol = PROTO_POP3; if ((p = strchr(parms[1], '/')) != NULL) { *p++ = '\0'; if (strcasecmp(p, "user") == 0) account->authmech = AUTH_USER; else if (strcasecmp(p, "apop") == 0) account->authmech = AUTH_APOP; else { g_free(account); g_free(mbox); return NULL; } } else account->authmech = AUTH_USER; account->username = g_strdup(parms[1]); account->password = g_strdup(parms[2]); account->use_ssl = SSL_NONE; mbox->check_func = check_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -