⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mail.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that license as published by the Free Software Foundation; either|  version 2 of the License, or (at your option) any later version.||  This program is distributed in the hope that it will be useful,|  but WITHOUT ANY WARRANTY; without even the implied warranty of|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the|  GNU General Public License for more details.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include "gkrellm.h"#include "gkrellm-private.h"#ifdef WIN32#include <winsock2.h>#else#include <utime.h>#include <sys/time.h>#endif#include <errno.h>#include	"pixmaps/mail/decal_mail.xpm"#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)#define HAVE_MD5_H#endif#if defined(HAVE_GNUTLS)#include <gnutls/openssl.h>#include <pthread.h>#define MD5Init		MD5_Init#define MD5Update	MD5_Update#define MD5Final	MD5_FinalGCRY_THREAD_OPTION_PTHREAD_IMPL;#else#if defined(HAVE_SSL)#include <openssl/ssl.h>#include <openssl/md5.h>#define MD5Init		MD5_Init#define MD5Update	MD5_Update#define MD5Final	MD5_Final#else#if defined(HAVE_MD5_H)#include <md5.h>#else#include "md5.h"#endif#endif#endif#include "ntlm.h"#define MUTE_FLAG	-1/* msg_count_mode has 3 states*/#define	MSG_NEW_TOTAL_COUNT	0#define	MSG_NEW_COUNT		1#define	MSG_NO_COUNT		2/* animation_mode states*/#define	ANIMATION_NONE			0#define	ANIMATION_ENVELOPE		1#define	ANIMATION_PENGUIN		2#define	ANIMATION_BOTH			3/* # of seconds to wait for a response from a POP3 or IMAP server*/#define TCP_TIMEOUT			30#define	DEFAULT_POP3_PORT	"110"#define	DEFAULT_IMAP_PORT	"143"#define	DEFAULT_IMAPS_PORT	"993"#define	DEFAULT_POP3S_PORT	"995"  /* A mailbox type has bits encoding how to check the mailbox (inline code  |  check or threaded check).  |  Threaded checks and the fetch program are remote checks  */#define	MBOX_CHECK_FETCH		0x1000#define	MBOX_CHECK_INLINE		0x2000#define	MBOX_CHECK_THREADED		0x4000#define MBOX_CHECK_TYPE_MASK	0xf000  /* Counts for mailboxes created and checked in other plugins can be shown */#define	MBOX_EXTERNAL		0x10  /* Mailboxes internally checked and created via the Mail->Mailboxes config */#define MBOX_INTERNAL		0x20  /* Here's the list of all the mailbox types the Mail monitor knows about.  |  The MBOX_FETCH is a pseudo internal mailbox where the counts read from  |  the fetch program are kept.  Additionally MBOX_FETCH_TOOLTIP types  |  are constructed just so the fetch programs output lines can be   |  reported in a tooltip.  Real mailboxes that GKrellM creates in its  |  config and knows how to check have MBOX_INTERNAL set.  And  |  finally there can be external (plugin) mailboxes created which  |  can have their check function called at the update intervals.  If the  |  plugin reports back the count results, the animation/sound can be  |  triggered for the plugin.  (Don't know if EXTERNAL guys will ever be used)  |  Internal mailboxes can be remote or local.  Remote mailboxes have an  |  authorization protocol that subdivides them into types.  Local mailboxes  |  currently have separate mboxtype values but I may later group them  |  into a MBOX_LOCAL type with a subdivision protocol like is currently  |  done for remote mailboxes.  */#define	MBOX_FETCH		(MBOX_CHECK_FETCH)#define	MBOX_MBOX		(MBOX_CHECK_INLINE   | MBOX_INTERNAL | 0)#define	MBOX_MAILDIR	(MBOX_CHECK_INLINE   | MBOX_INTERNAL | 1)#define	MBOX_MH_DIR		(MBOX_CHECK_INLINE   | MBOX_INTERNAL | 2)#define	MBOX_REMOTE		(MBOX_CHECK_THREADED | MBOX_INTERNAL | 3)#define	MBOX_FETCH_TOOLTIP	(6)#define	MBOX_LOCAL_PLUGIN	(MBOX_CHECK_INLINE   | MBOX_EXTERNAL)#define	MBOX_REMOTE_PLUGIN	(MBOX_CHECK_THREADED | MBOX_EXTERNAL)#define	PROTO_POP3		0#define	PROTO_IMAP		1#define	AUTH_PLAINTEXT		0#define	AUTH_USER		AUTH_PLAINTEXT		/* POP3 only */#define	AUTH_APOP		1			/* POP3 only */#define	AUTH_LOGIN		AUTH_PLAINTEXT		/* IMAP4 only */#define	AUTH_CRAM_MD5		2#define	AUTH_NTLM		3#define	SSL_NONE		0#define	SSL_TRANSPORT		1#define	SSL_STARTTLS		2  /* Authorization protocol strings to write into the config for remote  |  mailboxes.  */typedef struct	{	gchar	*string;	gint	protocol;	gint	authmech;	}	AuthType;static AuthType	auth_strings[] =	{	{ "POP3",		PROTO_POP3,	AUTH_USER },	{ "POP3_(APOP)",	PROTO_POP3,	AUTH_APOP },	{ "POP3_(CRAM-MD5)",	PROTO_POP3,	AUTH_CRAM_MD5 },	{ "POP3_(NTLM)",	PROTO_POP3,	AUTH_NTLM },	{ "IMAP",		PROTO_IMAP,	AUTH_LOGIN },	{ "IMAP_(CRAM-MD5)",	PROTO_IMAP,	AUTH_CRAM_MD5 },	{ "IMAP_(NTLM)",	PROTO_IMAP,	AUTH_NTLM },	{ NULL,			-1,		-1 }	};  /* Save local mailbox type strings in the config in case I later change  |  to an option_menu selection for subdividing a MBOX_LOCAL type.  |  Currently local mailbox types are determined in get_local_mboxtype().  */static gchar	*mbox_strings[3] =	{	"mbox",	"Maildir",	"MH_mail"	};static GkrellmMonitor	*mon_mail;typedef struct	{	gchar		*path,				*homedir_path;	gchar		*server;	gchar		*username;	gchar		*password;	gchar		*imapfolder;	gint		mboxtype;	gint		protocol;	gint		authmech;	gint		port;	gint		use_ssl;		/* Always SSL_NONE if !HAVE_SSL */	}	MailAccount;typedef struct	{	MailAccount	*account;	gboolean	busy;	GString		*tcp_in;	gboolean	(*check_func)();	gpointer	data;			/* For external mailboxes (in plugins) */	GThread*	thread;	gint		mail_count;	gint		new_mail_count;	gint		old_mail_count;	gint		prev_mail_count,				prev_new_mail_count;	time_t		last_mtime;	off_t		last_size;	gboolean	is_internal;	/* Internal mail message (ie: localmachine) */	gboolean	need_animation,				prev_need_animation;	gchar		*warn_msg;	gboolean	warned;	void		*private;	}	Mailbox;static GList	*mailbox_list;typedef struct	{	gchar	*command;	GString	*read_gstring;			/* Bytes read from pipe stored here */	gint	pipe;	}	Mailproc;typedef struct	{	gint	fd;#ifdef HAVE_SSL	SSL	*ssl;	SSL_CTX	*ssl_ctx;#endif	}	ConnInfo;Mailbox			*mail_fetch;		/* Internal mailbox: fetch command */static Mailproc	mail_user_agent;static gchar	*mail_notify;		/* Sound		*/static GkrellmPiximage *decal_mail_piximage;static gint		run_animation,				decal_frame;static gint		remote_check_timeout = 5;			/* Minutes */static gint		local_check_timeout = 4;			/* Seconds */static gboolean	fetch_check_is_local;static GkrellmPanel	*mail;static GtkTooltips	*tooltip;static GkrellmDecalbutton	*mua_button;static gboolean	enable_mail,				mute_mode,				super_mute_mode,				cont_animation_mode,				mua_inhibit_mode,		/* Inhibit checking if MUA launched */				enable_multimua,		/* allow multiple MUA instances */				count_mode,				fetch_check_only_mode,				reset_remote_mode,				unseen_is_new,			/* Accessed but unread */				local_supported = TRUE;static gboolean	mh_seq_ignore,				have_mh_sequences,				checking_mh_mail;static gint		animation_mode	= ANIMATION_BOTH;static gboolean	force_mail_check;static gint		new_mail_count, total_mail_count;static gint		check_timeout;static gint		show_tooltip = FALSE;static gint		anim_frame,				anim_dir,				anim_pause;static gint		style_id;  /* This may be called from gkrellm_sys_main_init()  */voidgkrellm_mail_local_unsupported(void)	{	local_supported = FALSE;	}GThread *gkrellm_mail_get_active_thread(void)	{	GList	*list;	Mailbox	*mbox;	GThread	*thread;	for (list = mailbox_list; list; list = list->next)		{		mbox = (Mailbox *) list->data;		thread = mbox->thread;		if (thread)			return thread;		}	return NULL;	}static voidfree_account(MailAccount *account)	{	if (!account)		return;	g_free(account->path);	g_free(account->homedir_path);	g_free(account->server);	g_free(account->username);	g_free(account->password);	g_free(account->imapfolder);	g_free(account);	}static voidfree_mailbox(Mailbox *mbox)	{	/* If user changes mailbox config list while a mailbox thread is busy,	|  freeing the mbox can cause a segfault.   Rare, so allow the leak.	*/	if (mbox->busy)		return;	free_account(mbox->account);	g_free(mbox->warn_msg);	g_free(mbox);	}static gbooleanformat_remote_mbox_name(Mailbox *mbox, gchar *buf, size_t len)	{	MailAccount	*account = mbox->account;	if (account->imapfolder && *account->imapfolder)		snprintf(buf, len, "%s-%s@%s", account->username,			account->imapfolder, account->server);	else if (account->server)		snprintf(buf, len, "%s@%s", account->username, account->server);	else if (account->username)		snprintf(buf, len, "%s", account->username);	else		{		snprintf(buf, len, "??");		return FALSE;		}	return TRUE;	}  /* Make tooltip visible/invisible and fill it with mailbox names  |  containing new mail.  */static voidupdate_tooltip(void)	{	GList		*list;	Mailbox		*mbox;	MailAccount	*account;	GString		*mboxes = NULL;	gchar		buf[128];   	if (show_tooltip)		{		mboxes = g_string_sized_new(512);		for (list = mailbox_list; list; list = list->next)			{			mbox = (Mailbox *) list->data;			account = mbox->account;			if (mbox->new_mail_count > 0)				{				if ((    account->mboxtype == MBOX_MBOX					  || account->mboxtype == MBOX_MAILDIR					  || account->mboxtype == MBOX_MH_DIR					  || account->mboxtype == MBOX_LOCAL_PLUGIN					  || account->mboxtype == MBOX_REMOTE_PLUGIN					) && account->path				   )					snprintf(buf, sizeof(buf), "%s", account->homedir_path ?								account->homedir_path : account->path);				else if (! format_remote_mbox_name(mbox, buf, sizeof(buf)))					continue;	/* Can't get a name, so no tooltip for you! */				if (mboxes->len > 0) 					g_string_append_c(mboxes, '\n');				g_string_append(mboxes, buf);											if (count_mode == MSG_NEW_TOTAL_COUNT)					snprintf(buf, sizeof(buf), "(%d/%d)",						mbox->new_mail_count, mbox->mail_count);				else					snprintf(buf, sizeof(buf), "(%d)", mbox->new_mail_count);				g_string_append(mboxes, buf); 				}			}		}	if (show_tooltip && mboxes && mboxes->len > 0)		{		gtk_tooltips_set_tip(tooltip, mail->drawing_area, mboxes->str, "");		gtk_tooltips_enable(tooltip);		}	else		gtk_tooltips_disable(tooltip);	if (mboxes)		g_string_free(mboxes, TRUE);	}		  /* Look at a From line to see if it is valid, lines look like:  |  From sending_address dayofweek month dayofmonth timeofday year  |  eg: From billw@gkrellm.net Fri Oct 22 13:52:49 2010  */static gintis_From_line(Mailbox *mbox, gchar *buf)	{	gchar	sender[512];	gint	dayofmonth = 0;	if (strncmp(buf, "From ", 5))		return FALSE;	/* In case sending address missing, look for a day of month	|  number in field 3 or 4 (0 based).	*/	sender[0] = '\0';	if (sscanf(buf, "%*s %*s %*s %d", &dayofmonth) != 1)		{		if (sscanf(buf, "%*s %511s %*s %*s %d", sender, &dayofmonth) != 2)			return FALSE;		}	if (dayofmonth < 1 || dayofmonth > 31)		return FALSE;	if (strcmp(sender, "MAILER-DAEMON") == 0)		mbox->is_internal = TRUE;	return TRUE;	}  /* Check if this is a Content-Type-line. If it contains a boundary  |  field, copy boundary string to buffer (including two leading and  |  trailing dashes marking the end of a multipart mail) and return  |  true. Otherwise, return false.  */static gintis_multipart_mail(gchar *buf, gchar *separator)	{	gchar *fieldstart;	gchar *sepstart;	gint  seplen;		if (strncmp(buf, "Content-Type: ", 14) != 0)		return FALSE;	if (strncmp(&buf[14], "multipart/", 10) != 0)		return FALSE;	fieldstart = &buf[14];	while (*fieldstart!=0)		{		while (*fieldstart!=0 && *fieldstart!=';')			fieldstart++;		if (*fieldstart==';') fieldstart++;		while (*fieldstart!=0 && *fieldstart==' ')			fieldstart++;		if (strncmp(fieldstart, "boundary=", 9) == 0)			{			sepstart = fieldstart + 9;			if (sepstart[0]=='"')				{				sepstart++;				seplen = 0;				while (sepstart[seplen]!='"' && sepstart[seplen]>=32)					seplen++;				}			else				{				seplen = 0;				while (sepstart[seplen]!=';' && sepstart[seplen]>32)					seplen++;				}			strcpy(separator,"--");			strncpy(&separator[2],sepstart,seplen);			strcpy(&separator[seplen+2],"--");			return TRUE;			}		}	return FALSE;	}  /* Hide a password that is embedded in a string.  */static voidhide_password(Mailbox *mbox, gchar *line, gint offset)	{	gint    n;	n = strlen(mbox->account->password);	while (n--)		line[offset + n] = '*';	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -