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

📄 mail.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 5 页
字号:
					    TRUE);			}		*(p + 1) = '\0';		snprintf(line, sizeof(line), "%s%s", key, account->password);		g_free(challenge);		MD5Init(&ctx);		MD5Update(&ctx, line, strlen(line));		MD5Final(digest, &ctx);		for (i = 0;  i < 16;  i++)			{			ascii_digest[i + i] = hex[digest[i] >> 4];			ascii_digest[i + i + 1] = hex[digest[i] & 0x0f];			}		ascii_digest[i + i] = '\0';		snprintf(line, sizeof(line),			 "APOP %s %s\r\n", account->username, ascii_digest);		server_command(&conn, mbox, line);		}	else if (account->authmech == AUTH_CRAM_MD5)		{		if (!do_cram_md5(&conn, "AUTH", mbox, NULL))			{			/* SASL cancellation of authentication */			server_command(&conn, mbox, "*\r\n");			return tcp_shutdown(&conn, mbox, tcp_error_message[7], TRUE);			}		}	else if (account->authmech == AUTH_NTLM)		{		if (!do_ntlm(&conn, "AUTH", mbox))			{			/* SASL cancellation of authentication */			server_command(&conn, mbox, "*\r\n");			return tcp_shutdown(&conn, mbox, tcp_error_message[7], TRUE);			}		}	else	/* AUTH_USER */		{		snprintf (line, sizeof (line), "USER %s\r\n", account->username);		server_command(&conn, mbox, line);		if (! server_response(&conn, mbox, "+OK"))			return tcp_shutdown(&conn, mbox, tcp_error_message[2], TRUE);		snprintf (line, sizeof (line), "PASS %s\r\n", account->password);		tcp_putline(&conn, line);		if (_GK.debug_level & DEBUG_MAIL)			{			hide_password(mbox, line, 5);			format_remote_mbox_name(mbox, buf, sizeof(buf));			printf("server_command( %s ):%s", buf, line);			}		}	if (! server_response(&conn, mbox, "+OK"))		return tcp_shutdown(&conn, mbox, tcp_error_message[3], TRUE);	server_command(&conn, mbox, "STAT\r\n");	if (! server_response(&conn, mbox, "+OK"))		return tcp_shutdown(&conn, mbox, tcp_error_message[4], FALSE);	sscanf(mbox->tcp_in->str, "+OK %d", &mbox->mail_count);   	snprintf (line, sizeof (line), "UIDL %d\r\n", mbox->mail_count);	server_command(&conn, mbox, line);	if (! server_response(&conn, mbox, "+OK"))		mbox->new_mail_count = mbox->mail_count;	else		/* Set the new_mail_count only if the UIDL is changed to avoid		|  re-reporting mail is new after MUA button has been clicked.		*/		if (   sscanf(mbox->tcp_in->str, "+OK %*d %127s", line) == 1			&& (   gkrellm_dup_string((gchar **) (&mbox->private), line)				|| unseen_is_new			   )		   )			mbox->new_mail_count = mbox->mail_count;	server_command(&conn, mbox, "QUIT\r\n");	tcp_close(&conn);	return TRUE;	}static gbooleancheck_imap(Mailbox *mbox)	{	MailAccount		*account = mbox->account;	ConnInfo		conn;	gint			messages = 0;	gint			unseen = 0;	gint			seq = 0;	gchar			line[128], *ss;	gchar			buf[128];	if (!tcp_connect(&conn, mbox))		return FALSE;	/* Is the machine we are connected to really a IMAP server?	*/	if (! server_response(&conn, mbox, "* OK"))		return tcp_shutdown(&conn, mbox, tcp_error_message[1], FALSE);#ifdef HAVE_SSL	if (account->use_ssl == SSL_STARTTLS)		{		snprintf(line, sizeof(line), "a%03d STARTTLS\r\n", ++seq);		server_command(&conn, mbox, line);		snprintf(line, sizeof(line), "a%03d OK", seq);		if (!imap_completion_result(&conn, mbox, line))			return tcp_shutdown(&conn, mbox,					    N_("Bad response after STARTTLS."),					    TRUE);		if (!ssl_negotiate(&conn, mbox))			return FALSE;		}#endif	if (account->authmech == AUTH_CRAM_MD5)		{		snprintf(line, sizeof(line), "a%03d AUTHENTICATE", ++seq);		if (!do_cram_md5(&conn, line, mbox, NULL))			{			/* SASL cancellation of authentication */			server_command(&conn, mbox, "*\r\n");			return tcp_shutdown(&conn, mbox, tcp_error_message[7], TRUE);			}		}	else if (account->authmech == AUTH_NTLM)		{		snprintf(line, sizeof(line), "a%03d AUTHENTICATE", ++seq);		if (!do_ntlm(&conn, line, mbox))			{			/* SASL cancellation of authentication */			server_command(&conn, mbox, "*\r\n");			return tcp_shutdown(&conn, mbox, tcp_error_message[7], TRUE);			}		}	else	/* AUTH_LOGIN */		{		snprintf(line, sizeof(line), "a%03d LOGIN \"%s\" \"%s\"\r\n",			 ++seq, account->username, account->password);		tcp_putline(&conn, line);		if (_GK.debug_level & DEBUG_MAIL)			{			line[10 + 2 + strlen(account->username)] = '\0';			hide_password(mbox, line, 11 + 2 + strlen(account->username));			format_remote_mbox_name(mbox, buf, sizeof(buf));			printf("server_command( %s ):%s", buf, line);			}		}	snprintf(line, sizeof(line), "a%03d OK", seq);	if (! imap_completion_result(&conn, mbox, line))		return tcp_shutdown(&conn, mbox, tcp_error_message[2], TRUE);	/* I expect the only untagged response to STATUS will be "* STATUS ..."	*/	snprintf(line, sizeof(line),		 "a%03d STATUS \"%s\" (MESSAGES UNSEEN)\r\n",		 ++seq, account->imapfolder);	server_command(&conn, mbox, line);	if (! server_response(&conn, mbox, "*"))		return tcp_shutdown(&conn, mbox, tcp_error_message[4], FALSE);	if ((ss = strstr(mbox->tcp_in->str, "MESSAGES")) == NULL)		{		if (strrchr(mbox->tcp_in->str, '}'))			{			if (! server_response(&conn, mbox, ""))				return tcp_shutdown(&conn, mbox, tcp_error_message[4], FALSE);			if ((ss = strstr(mbox->tcp_in->str, "MESSAGES")) == NULL)				return tcp_shutdown(&conn, mbox, tcp_error_message[4], FALSE);			} 		else			return tcp_shutdown(&conn, mbox, tcp_error_message[4], FALSE);		}	if (sscanf(ss, "MESSAGES %d", &messages) == 1)		{		if ((ss = strstr(mbox->tcp_in->str, "UNSEEN")) != NULL)			sscanf(ss, "UNSEEN %d", &unseen);		if (_GK.debug_level & DEBUG_MAIL)			g_print(_("Messages: %d\nUnseen: %d\n"), messages, unseen);		}	mbox->mail_count = messages;	mbox->new_mail_count = unseen;	snprintf(line, sizeof(line), "a%03d OK", seq);	imap_completion_result(&conn, mbox, line);	snprintf(line, sizeof(line), "a%03d LOGOUT\r\n", ++seq);	server_command(&conn, mbox, line);	snprintf(line, sizeof(line), "a%03d OK", seq);	imap_completion_result(&conn, mbox, line);	tcp_close(&conn);	return TRUE;	}static gbooleanmh_sequences_new_count(Mailbox *mbox)	{	FILE	*f;	gchar	buf[1024];	gchar	*path, *tok;	gint	n0, n1;	path = g_strconcat(mbox->account->path, G_DIR_SEPARATOR_S,				".mh_sequences", NULL);	f = fopen(path, "r");	g_free(path);	if (!f)		return FALSE;	have_mh_sequences = TRUE;	if (mh_seq_ignore)		{		fclose(f);		return FALSE;		}	while (fgets(buf, sizeof(buf), f))		{		/* Look for unseen sequence like "unseen: 4 7-9 23"		*/		if (strncmp(buf, "unseen:", 7))			continue;		tok = strtok(buf, " \t\n");		while ((tok = strtok(NULL, " \t\n")) != NULL)			{			if (sscanf(tok, "%d-%d", &n0, &n1) == 2)				mbox->new_mail_count += n1 - n0 + 1;			else				mbox->new_mail_count++;			}		break;		}	fclose(f);	return TRUE;	}  /* Sylpheed procmsg.h enums MSG_NEW as (1 << 0) and MSG_UNREAD as (1 << 1)  |  And procmsg_write_flags() in Sylpheeds procmsg.c writes a mail record as  |  a pair of ints with msgnum first followed by flags.  */#define SYLPHEED_MSG_NEW		1#define SYLPHEED_MSG_UNREAD		2#define SYLPHEED_MARK_VERSION	2static gbooleansylpheed_mark_new_count(Mailbox *mbox)	{	FILE	*f;	gchar	*path;	gint	msgnum, flags, ver, mark_files = 0;	path = g_strconcat(mbox->account->path, G_DIR_SEPARATOR_S,				".sylpheed_mark", NULL);	f = fopen(path, "rb");	g_free(path);	if (!f)		return FALSE;	if (   fread(&ver, sizeof(ver), 1, f) == 1		&& SYLPHEED_MARK_VERSION == ver	   )		{		while (   fread(&msgnum, sizeof(msgnum), 1, f) == 1			   && fread(&flags, sizeof(flags), 1, f) == 1			  )			{			if (   (flags & SYLPHEED_MSG_NEW)				|| ((flags & SYLPHEED_MSG_UNREAD) && unseen_is_new)			   )				mbox->new_mail_count += 1;			++mark_files;			}		if (mark_files < mbox->mail_count)			mbox->new_mail_count += mbox->mail_count - mark_files;		}	fclose(f);	return TRUE;	}  /* Check a mh directory for mail. The way that messages are marked as new  |  depends on the MUA being using.  Only .mh_sequences and .sylpheed_mark  |  are currently checked, otherwise all mail found is considered new mail.  */static gbooleancheck_mh_dir(Mailbox *mbox)	{	GDir	*dir;	gchar	*name;	mbox->mail_count = mbox->new_mail_count = 0;	if ((dir = g_dir_open(mbox->account->path, 0, NULL)) == NULL)		return FALSE;	while ((name = (gchar *) g_dir_read_name(dir)) != NULL)		{		/* Files starting with a digit are messages. */		if (isdigit(name[0]))			mbox->mail_count++;		}	g_dir_close(dir);	/* Some MH dir clients use .mh_sequences, others such as mutt or gnus	|  do not.  For mixed cases, it's a user option to ignore .mh_sequences.	|  Sylpheed uses .sylpheed_mark.	*/	if (   !mh_sequences_new_count(mbox)		&& !sylpheed_mark_new_count(mbox)	   )		mbox->new_mail_count = mbox->mail_count;	return TRUE;	}  /* A maildir has new, cur, and tmp subdirectories.  Any file in new  |  or cur that does not begin with a '.' is a mail message.  It is  |  suggested that messages begin with the output of time() (9 digits)  |  but while mutt and qmail use this standard, procmail does not.  |  maildir(5) says:  |      It is a good idea for readers to skip all filenames in  |      new and cur starting with a dot.  Other than this,  |      readers should not attempt to parse filenames.  |  So check_maildir() simply looks for files in new and cur.  |  But if unseen_is_new flag is set, look for ":2,*S" file suffix where  |  the 'S' indicates the mail is seen.  |  See http://cr.yp.to/proto/maildir.html  */static gbooleancheck_maildir(Mailbox *mbox)	{	gchar	path[256], *s;	gchar	*name;	GDir	*dir;	mbox->new_mail_count = 0;	snprintf(path, sizeof(path), "%s%cnew", mbox->account->path,				G_DIR_SEPARATOR);	if ((dir = g_dir_open(path, 0, NULL)) != NULL)		{		while ((name = (gchar *) g_dir_read_name(dir)) != NULL)			mbox->new_mail_count++;		g_dir_close(dir);		}	mbox->mail_count = mbox->new_mail_count;	snprintf(path, sizeof(path), "%s%ccur", mbox->account->path,				G_DIR_SEPARATOR);	if ((dir = g_dir_open(path, 0, NULL)) != NULL)		{		while ((name = (gchar *) g_dir_read_name(dir)) != NULL)			{			mbox->mail_count++;			if (   unseen_is_new				&& (   (s = strchr(name, ':')) == NULL					|| !strchr(s, 'S')				   )			   )				mbox->new_mail_count++;			}		g_dir_close(dir);		}	if (_GK.debug_level & DEBUG_MAIL)		g_print("check_maildir %s: total=%d old=%d new=%d\n",				mbox->account->path, mbox->mail_count,				mbox->old_mail_count, mbox->new_mail_count);    return TRUE;	}  /* Count total mail and old mail in a mailbox.  Old mail can be read  |  with a Status: R0, or can be accessed and not read with Status: O  |  So, new mail will be the diff - note that unread mail is not  |  necessarily new mail.  According to stat() man page:  |  st_atime is changed by mknod(), utime(), read(), write(), truncate()  |  st_mtime is changed by mknod(), utime(), write()  |  But, new mail arriving (writing mailbox) sets st_mtime while reading  |  the mailbox (mail program reading) sets st_atime.  So the test  |  st_atime > st_mtime is testing if mbox has been read since last new mail.  |  Mail readers may restore st_mtime after writting status.  |  And Netscape mail does status with X-Mozilla-Status: xxxS  |    where S is bitwise or of status flags:  |    1: read  2: replied  4: marked  8: deleted  |    |  Evolution uses status with X-Evolution: 00000000-xxxx where xxxx status is  |  a bitfield in hexadecimal (see enum _CamelMessageFlags in evolution/camel  |  source) and most importantly CAMEL_MESSAGE_SEEN = 1<<4.  */  /* test if buf is a status for standard mail, mozilla or evolution   */static gbooleanis_status(gchar *buf)	{	if (buf[0] != 'S' && buf[0] != 'X')		return FALSE;	if ( !strncmp(buf, "Status:", 7)  /* Standard mail clients */	     || !strncmp(buf, "X-Mozilla-Status:", 17) /* Netscape */	     || !strncmp(buf, "X-Evolution:", 12) )     /* Mozilla */	    return TRUE;	else	    return FALSE;	}static gbooleanstatus_is_old(gchar *buf)	{	gchar	c;	int tmp;	/* Standard mail clients	*/	if (   !strncmp(buf, "Status:", 7)		&& (strchr(buf, 'R') || (!unseen_is_new && strchr(buf, 'O')))	   )		return TRUE;	/* Netscape	*/	if (!strncmp(buf, "X-Mozilla-Status:", 17))		{		c = buf[21];		if (c < '8')	/* Not deleted */			c -= '0';		if (c >= '8' || (c & 0x1))			return TRUE;		}	/* Evolution	*/	if (!strncmp(buf, "X-Evolution:", 12))		{		sscanf(buf+22, "%04x", &tmp);		if (tmp & (1<<4))			return TRUE;		}	return FALSE;	}  /* test if a mail is marked as deleted    |  Evolution uses status with X-Evolution: 00000000-xxxx where xxxx status is  |  a bitfield in hexadecimal (see enum _CamelMessageFlags in evolution/camel source)  |  and most importantly CAMEL_MESSAGE_DELETED = 1<<1.  */static gbooleanstatus_is_deleted(gchar *buf)	{	gint	tmp;	/* Standard mail clients	if (   !strncmp(buf, "Status:", 7) )	*/	/* Netscape	if (!strncmp(buf, "X-Mozilla-Status:", 17))	*/	/* Evolution	*/	if (!strncmp(buf, "X-Evolution:", 12))		{		sscanf(buf+22, "%04x", &tmp);		if (tmp & (1<<1))			return TRUE;		/* Junk is not explicitly marked as deleted but is shown as if		|  where in evolution		*/		if (tmp & (1<<7))			return TRUE;		}	return FALSE;	}static gbooleancheck_mbox(Mailbox *mbox)	{	FILE			*f;	struct utimbuf	ut;	struct stat		s;	gchar			buf[1024];	gchar			mpart_sep[1024];	gint			in_header	= FALSE;	gint			marked_read = FALSE;	gint			is_multipart = FALSE;	if (stat(mbox->account->path, &s) != 0)		{		mbox->mail_count = mbox->old_mail_count = mbox->new_mail_count = 0;		mbox->last_mtime = 0;		mbox->last_size = 0;		if (_GK.debug_level & DEBUG_MAIL)			printf("check_mbox can't stat(%s): %s\n", mbox->account->path,					g_strerror(errno));		return FALSE;		}	/* Message no-counting mode reports new mail based on mailbox	|  modified time and size.	*/	if (count_mode == MSG_NO_COUNT)		{		if (   s.st_size > 0			&& s.st_size >= mbox->last_size			&& s.st_mtime >= s.st_atime		   )			mbox->new_mail_count = TRUE;		else			mbox->new_mail_count = FALSE;		mbox->mail_count = (s.st_size > 0) ? 1 : 0;	/* boolean, not used */		mbox->old_mail_count = 0;			/* not used */		mbox->last_size = s.st_size;		mbox->last_mtime = s.st_mtime;		return TRUE;

⌨️ 快捷键说明

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