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

📄 mail.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 5 页
字号:
		}	/* If the mailboxes have been modified since last check, count	|  the new/total messages.	*/	if (   s.st_mtime != mbox->last_mtime		|| s.st_size  != mbox->last_size		|| force_mail_check	   )		{		if ((f = fopen(mbox->account->path, "r")) == NULL)			{			if (_GK.debug_level & DEBUG_MAIL)				printf("check_mbox can't fopen(%s): %s\n", mbox->account->path,						g_strerror(errno));			return FALSE;			}		mbox->mail_count = 0;		mbox->old_mail_count = 0;		while(fgets(buf, sizeof(buf), f))			{			if (is_multipart && !in_header)				{				/* Skip to last line of multipart mail */				if (strncmp(buf,mpart_sep,strlen(mpart_sep))==0)					is_multipart = FALSE;				}			else if (buf[0] == '\n')				{				in_header = FALSE;				mbox->is_internal = FALSE;				}			else if (is_From_line(mbox, buf))				{				mbox->mail_count += 1;				in_header = TRUE;				marked_read = FALSE;				}			else if (in_header && is_status(buf))				{				if (status_is_old(buf) && !marked_read)					{					mbox->old_mail_count += 1;					marked_read = TRUE;				    }				if (status_is_deleted(buf))					{					if (marked_read)						mbox->old_mail_count -= 1;					mbox->mail_count -= 1;				    }				}			else if (in_header && mbox->is_internal)				{				if (strncmp(buf, "From: Mail System Internal Data", 31) == 0)					{					in_header = FALSE;					mbox->mail_count -= 1;					mbox->is_internal = FALSE;					}				}			else if (in_header && is_multipart_mail(buf,mpart_sep))				{				is_multipart = TRUE;				}			}		fclose(f);		/* Restore the mbox stat times for other mail checking programs and		|  so the (st_atime > st_mtime) animation override below will work.		*/		ut.actime = s.st_atime;		ut.modtime = s.st_mtime;		utime(mbox->account->path, &ut);		mbox->last_mtime = s.st_mtime;		mbox->last_size = s.st_size;		if (_GK.debug_level & DEBUG_MAIL)			g_print("check_mbox %s: total=%d old=%d\n",					mbox->account->path,					mbox->mail_count, mbox->old_mail_count);		}	/* Set the animation state when new mail count changes, and override	|  the animation to false if mbox has been accessed since last modify	|  (A MUA has probably read the mbox).	*/	mbox->new_mail_count = mbox->mail_count - mbox->old_mail_count;	if (s.st_atime > s.st_mtime)		{		mbox->need_animation = FALSE;		mbox->prev_new_mail_count = mbox->new_mail_count;		}    return TRUE;	}static GkrellmDecal	*mail_text_decal;static GkrellmDecal	*mail_icon_decal;static voiddraw_mail_text_decal(gint new_mail_count, gint mail_count)	{	GkrellmTextstyle	ts, ts_save;	gint				x, w;	GkrellmPanel		*p;	GkrellmDecal		*d;	GkrellmStyle		*style;	GkrellmMargin		*m;	gchar				buf[32], nbuf[16], tbuf[16];	p = mail;	d = mail_text_decal;	ts_save = d->text_style;	if (new_mail_count == MUTE_FLAG)		{		snprintf(buf, sizeof(buf), _("mute"));		ts = *gkrellm_meter_alt_textstyle(style_id);	/* Use the alt color */		ts.font = d->text_style.font;		}	else		{		ts = d->text_style;		if (count_mode == MSG_NO_COUNT)			buf[0] = '\0';		else if (count_mode == MSG_NEW_COUNT)			{			if (new_mail_count == 0)				strcpy(buf, "-");			else				snprintf(buf, sizeof(buf), "%d", new_mail_count);			}		else /* MSG_NEW_TOTAL_COUNT */			{			if (new_mail_count == 0)				strcpy(nbuf, "-");			else				snprintf(nbuf, sizeof(nbuf), "%d", new_mail_count);			if (mail_count == 0)				strcpy(tbuf, "-");			else				snprintf(tbuf, sizeof(tbuf), "%d", mail_count);			snprintf(buf, sizeof(buf), "%s/%s", nbuf, tbuf); 			}		}	w = gkrellm_gdk_string_width(ts.font, buf);	if (w > d->w)		{		ts.font = gkrellm_meter_alt_textstyle(style_id)->font;		w = gkrellm_gdk_string_width(ts.font, buf);		}	style = gkrellm_meter_style(style_id);	m = gkrellm_get_style_margins(style);	x = gkrellm_chart_width() * p->label->position / GKRELLM_LABEL_MAX;	x -= m->right + w / 2;	if (p->label->position >= 50)		x -= mail_icon_decal->w;	if (x > d->w - w)		x = d->w - w;	if (x < 0)		x = 0;	d->text_style = ts;	d->x_off = x;	gkrellm_draw_decal_text(p, d, buf, 0);	d->text_style = ts_save;	}static voidmbox_set_animation_state(Mailbox *mbox)	{	if (mbox->new_mail_count != mbox->prev_new_mail_count)		mbox->need_animation =				(mbox->new_mail_count > mbox->prev_new_mail_count);	}static voidupdate_krell_animation_frame(void)	{	/* Run the animation.  Just go back and forth with a pause on	|  frames 1 and full_scale - 1 (frames 0 and full_scale are cut off).	|  Frame 0 is blank anyway, and frame full_scale is just not used.	*/	if (anim_pause-- <= 0)		{		if (anim_frame <= 1)			anim_dir = 1;		if (anim_frame >= KRELL(mail)->full_scale - 1)			anim_dir = -1;		anim_frame += anim_dir;		anim_frame %= KRELL(mail)->full_scale;		if (anim_frame == 1 || anim_frame == KRELL(mail)->full_scale - 1)			anim_pause = 4;		}	}  /* I popen the mail_user_agent so I can know if it is running and  |  the mail_fetch so I can process fetchmail/flist/fetcho/...  output.  |  Reading the pipes need to not block so GKrellM won't freeze.  |  So, I need a special non-blocking pipe line reading routine.  */static voidpipe_command(Mailproc *mp)	{	gchar		**argv;	GError		*err = NULL;	gboolean	res;	if (mp->pipe >= 0)	/* Still running?  */		{		if (_GK.debug_level & DEBUG_MAIL)			g_print("mail pipe_command: <%s> still running.\n", mp->command);		return;		}	if (!mp->command || *mp->command == '\0')		return;	g_shell_parse_argv(mp->command, NULL, &argv, NULL);	if (_GK.debug_level & DEBUG_MAIL)		g_print("mail pipe_command <%s>\n", mp->command);	mp->pipe = -1;	res = g_spawn_async_with_pipes(NULL, argv, NULL,				G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,				NULL, NULL, NULL, NULL, &mp->pipe, NULL, &err);	if (!res && err)		{		gkrellm_message_dialog(NULL, err->message);		g_error_free(err);		}	if (mp->read_gstring)		mp->read_gstring = g_string_truncate(mp->read_gstring, 0);	else		mp->read_gstring = g_string_new("");	fcntl(mp->pipe, F_SETFL, O_NONBLOCK);	g_strfreev(argv);	}  /* Accumulate non-blocking reads from a pipe into a gstring.  Then  |  try to read a single line from the gstring.  If a line is read,  |  return the count of chars in the line.  But if no line can be read  |  and the other end of the pipe has exited (pipe eof), return -1.  |  Otherwise return 0 to indicate no line is available but the pipe  |  producer is still alive.  |  Why this trouble?: the stdio fgets() reading from a non-blocking  |  stream is not guaranteed to return complete '\n' delimited lines.  */static gintfgets_pipe(gchar *line, gint len, Mailproc *mp)	{	gchar	buf[512];	gint	n;	if (mp->pipe >= 0)		{		n = read(mp->pipe, buf, sizeof(buf) - 1);		if (n <= 0)			{			if (errno != EINTR && errno != EAGAIN)				{				if (close(mp->pipe) < 0 && errno == EINTR)					close(mp->pipe);				mp->pipe = -1;				}			}		else			{			buf[n] = '\0';			mp->read_gstring = g_string_append(mp->read_gstring, buf);			}		}	if (gkrellm_getline_from_gstring(&mp->read_gstring, line, len))		return strlen(line);	if (mp->pipe < 0)		{		if (mp->read_gstring)			g_string_free(mp->read_gstring, TRUE);		mp->read_gstring = NULL;		return -1;		}	return 0;	}static gbooleanmua_is_launched(void)	{	gchar	buf[128];	gint	n;	if (mail_user_agent.pipe == -1)		return FALSE;	while ((n = fgets_pipe(buf, sizeof(buf), &mail_user_agent)) > 0)		;	return (n < 0) ? FALSE : TRUE;	}  /* Read mail_fetch pipe and if fetch_check_only_mode, look for output  |  of fetchmail -c or flist so I can report mail from these programs.  |  | eg. for MH mail, the nmh program flist -all (from the man page):  |   /work/Mail  has  5 in sequence unseen (private); out of  46  |   inbox+      has 10 in sequence unseen          ; out of 153  |   junklist    has  0 in sequence unseen          ; out of  63  |  |  For fetchmail, if no remote mail, I get:  |		fetchmail: No mail for billw at mail.wt.net  |  If remote mail i will get lines like:  |		1 message for billw at mail.wt.net (32743 octets).  |	  or, as reported by a user, there could be:  |		26 messages (25 seen) for billw at mail.wt.net  |  If the remote mail is fetched, I get additional lines like:  |		reading message 1 of 1 (32743 octets) .................... flushed  |  Note: above 26 messages (25 seen) should show as 1/26 on panel.  |  |  And fetchmail can't make up its mind.  A user gets this with 5.2.0:  |  fetchmail: 5.2.0 querying xx.yy.net (protocol POP3) at Thu, 20 Jan 2000...  |  fetchmail: 2 messages for uuu at xx.yy.net (20509 octets).  */  /* Since there is now internal POP3 and IMAP checking, this will not be  |  used as much, but there is still flist, using fetchmail for ssl, etc.  |  Anyway, here's the code to grok the above mess!  */static gbooleanparse_fetch_line(gchar *line, gint *msg, gint *seen)	{	gchar	*s, *p, *buf;	gint	n, n1, n2;	gint	tok_count	= 0;	gint	state		= 0,			seen_flag	= FALSE,			unseen_flag	= FALSE;	*msg = 0;	*seen = 0;	n1 = n2 = 0;	buf = g_strdup(line);	s = strtok(buf, " \t()\n");	/* Trap out badly set Fetch/check option.	*/	if (!s || !strcmp(s, "reading") || !strcmp(s, "skipping"))		{		g_free(buf);		return FALSE;		}	if (_GK.debug_level & DEBUG_MAIL)		printf("  parse[");	while (s)		{		if (++tok_count > 3 && state == 0)	/* need a int within 3 tokens */			break;		n = strtol(s, &p, 0);		if (*p == ' ' || *p == '\t' || *p == '\0' || *p == '\n')			{		/* Have an integer, and not a x.y version number */			if (_GK.debug_level & DEBUG_MAIL)				printf("*<%s>,st=%d,", s, state);			if (state == 0)				n1 = n;			else if (state == 1)				n2 = n;			if (_GK.debug_level & DEBUG_MAIL)				printf("n1=%d,n2=%d state=%d*", n1, n2, state);			++state;			}		else if (!strcmp(s, "seen") || !strcmp(s, _("seen")))			seen_flag = TRUE;		else if (!strcmp(s, "unseen"))			unseen_flag = TRUE;		s = strtok(NULL, " \t()\n");		}	if (state > 1 && seen_flag)	/* 26 messages (25 seen) ... */		{		*msg = n1;		*seen = n2;		}	else if (state > 1 && unseen_flag)	/* /xxx has 5 in sequence unseen ... */		{		*msg = n2;		*seen = n2 - n1;		}	else if (state > 0)			/*     1 message for billw at ... */		*msg = n1;				/* or  Fetchmail: 1 message for .... */	if (_GK.debug_level & DEBUG_MAIL)		printf("]snf=%d sunf=%d msg=%d seen=%d STATE=%d\n",				seen_flag, unseen_flag, *msg, *seen, state);	g_free(buf);	return TRUE;	}static gintcompare_mailboxes(gconstpointer a, gconstpointer b)	{	gchar a_name[128];	gchar b_name[128];	format_remote_mbox_name((Mailbox *)a, a_name, sizeof(a_name));	format_remote_mbox_name((Mailbox *)b, b_name, sizeof(b_name));	return strcmp(a_name, b_name);	}static voidmake_fetch_tooltip(gchar *line, gint msg, gint seen)	{	Mailbox		*mbox;	MailAccount	*account;	GList		*old_mbox_pointer;	gchar		buf[64], *s;	mbox = g_new0(Mailbox, 1);	account = g_new0(MailAccount, 1);	mbox->account = account;	account->mboxtype = MBOX_FETCH_TOOLTIP;	if ((s = strstr(line, "sequence unseen")) != NULL)	/* flist */		{		sscanf(line, "%63s", buf);		account->username = g_strdup(buf);		}	else if ((s = strstr(line, " for ")) != NULL)		/* fetchmail */		{		sscanf(s + 5, "%63s", buf);		account->username = g_strdup(buf);		if ((s = strstr(line, " at ")) != NULL)			{			sscanf(s + 4, "%63s", buf);			account->server = g_strdup(buf);			}		if ((s = strstr(line, "(folder ")) != NULL)			{			sscanf(s + 8, "%63[^)]", buf);			account->imapfolder = g_strdup(buf);			}		}	else		{		free_mailbox(mbox);		return;		}	old_mbox_pointer = g_list_find_custom(mailbox_list, mbox,				(GCompareFunc) compare_mailboxes);	if (old_mbox_pointer)		{		free_mailbox(mbox);		mbox = (Mailbox *) old_mbox_pointer->data;		if (mbox->account->mboxtype == MBOX_FETCH_TOOLTIP)			{			mbox->mail_count = msg;			mbox->new_mail_count = msg - seen;			}		}	else		{		mbox->mail_count = msg;		mbox->new_mail_count = msg - seen;		mailbox_list = g_list_insert_sorted(mailbox_list, mbox,								(GCompareFunc)(compare_mailboxes));		}	}  /* Read output lines from the fetch/check program.  If fetch_check_only_mode  |  is set, parse the lines to try to read message counts so they can be  |  reported ("fetchmail -c" or equiv should be configured).  However, if  |  the mode is not set, then just read lines and waste them because mail  |  is presumably being downloaded into local mailboxes.  */static voidread_mail_fetch(void)	{	Mailproc	*mp		= (Mailproc *) mail_fetch->private;	gchar		buf[128];	gint		n, msg, seen;	while ((n = fgets_pipe(buf, sizeof(buf), mp)) > 0)	/* non-blocking */		{		if (_GK.debug_level & DEBUG_MAIL)			printf("read_mail_fetch(%d): %s\n", fetch_check_only_mode, buf);		if (fetch_check_only_mode)			{			if (parse_fetch_line(buf, &msg, &seen))				make_fetch_tooltip(buf, msg, seen);			if (msg > 0)				{				mail_fetch->mail_count += msg;				mail_fetch->old_mail_count += seen;				}			}		}	/* When fetch program is done, flag not busy so new counts will be used.	*/	if (n < 0)		{		if (fetch_check_only_mode)			{			mail_fetch->new_mail_count =					mail_fetch->mail_count - mail_fetch->old_mail_count;			mbox_set_animation_state(mail_fetch);			}		mail_fetch->busy = FALSE;		}	}static voidreset_mail_fetch(void)	{	Mailproc	*mp	= (Mailproc *) mail_fetch->private;

⌨️ 快捷键说明

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