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

📄 pop3.c

📁 GNOME下的短信息发送中心
💻 C
字号:
/* * libsms pop3 * * Authors:     Michael Jochum <e9725005@stud3.tuwien.ac.at> * * TODO:         * * Fixes:       Michael Jochum  :       Rewrite for new socket functions *                                      and new interface  * * For license terms, see the file COPYING in the project directory. */#include <config.h>#include <gnome.h>#include <stdio.h>#include <string.h>#include <glib.h>#include "sock.h"#include "mail.h"#include "misc.h"#include "pop3.h"static GSmsPop3Error pop3_get_ok(const GSmsSocket * s, gchar * par){	gchar buf[POP3_BUFSIZE + 1];	if (gsms_socket_read_line(s, buf, sizeof(buf)) < 0)		return GSMS_POP3_ERROR_NET;	if (strncmp(buf, "+OK", 3) == 0) {		if (buf[3] == ' ' && par != NULL)			strcpy(par, buf + 4);	} else if (strncmp(buf, "-ERR", 4) == 0)		return GSMS_POP3_ERR;	else		return GSMS_POP3_ERROR_PROTO;	return GSMS_POP3_OK;}static GSmsMail *find_uidl(GList * mails, const gchar * uid){	GList *mailent;	GSmsMail *mail;	mailent = g_list_first(mails);	while (mailent != NULL) {		mail = mailent->data;		if (strcmp(mail->uid, uid) == 0)			return mail;		mailent = g_list_next(mailent);	}	return NULL;}static GList *pop3_expire(GList * mails){	GList *mailent;	GList *mailexp;	GSmsMail *mail;	mailent = g_list_first(mails);	while (mailent != NULL) {		mail = mailent->data;		mailent = g_list_next(mailexp = mailent);		if (!mail->on_server) {			mails = g_list_remove_link(mails, mailexp);			mail_destructor(mail);		}	}	return mails;}static gint pop3_get_uidl(const GSmsSocket * s, GList ** mails){	gint ok;	gchar buf[POP3_BUFSIZE];	gchar uid[POP3_BUFSIZE];	gint num;	GList *mailent;	GSmsMail *mail;	/* set on_server=FALSE for all GSmsMails */	mailent = g_list_first(*mails);	while (mailent != NULL) {		mail = mailent->data;		mail->on_server = FALSE;		mailent = g_list_next(mailent);	}	gsms_socket_write_str(s, "UIDL\n");	/* TODO: Error check */	ok = pop3_get_ok(s, NULL);	if (ok == GSMS_POP3_OK) {		while ((ok = gsms_socket_read_line(s, buf, sizeof(buf))) >		       0) {			if (buf[0] == '.')				break;			if (sscanf(buf, "%d %s", &num, uid) == 2) {				if ((mail = find_uidl(*mails, uid)) ==				    NULL) {					mail = g_new0(GSmsMail, 1);					mail->uid = g_strdup(uid);					mail->new = TRUE;					*mails =					    g_list_append(*mails, mail);				}				mail->on_server = TRUE;				mail->msg_num = num;			}		}		ok = ok > 0 ? GSMS_POP3_OK : GSMS_POP3_ERROR_NET;	} else if (ok == GSMS_POP3_ERR) {		/* implement alternativ method */		g_log(NULL, G_LOG_LEVEL_CRITICAL, _("Error: Your POP3 server does not implement the UIDL command!"));	}	/* remove mesages from the list which are no longer on the server */	*mails = pop3_expire(*mails);	/*  TODO: get headers for new mails */	return ok;}static GSmsPop3Error pop3_get_header(const GSmsSocket * s, GSmsMail * mail){	gint length;	GString *head;	gchar buf[POP3_BUFSIZE];	GSmsPop3Error ok;	gsms_socket_printf(s, "TOP %d 0\n", mail->msg_num);	if ((ok = pop3_get_ok(s, NULL)) != GSMS_POP3_OK) {		/* if the command is not supported (ok == POP3_ERR)		   we could write a slow method wich would download		   the whole email => verrrrry slow => so we return		   an error code for now */		return ok;	}	head = g_string_sized_new(POP3_BUFSIZE);	while ((length = gsms_socket_read_line(s, buf, sizeof(buf))) > 0) {		if (buf[0] == '.')			break;		head = g_string_append(head, buf);	}	if (length <= 0) {		g_string_free(head, TRUE);		return GSMS_POP3_ERROR_NET;	}	mail->head = g_strdup(head->str);	g_string_free(head, TRUE);	mail->from = mail_get_field(mail->head, "From:");	mail->to = mail_get_field(mail->head, "To:");	mail->subject = mail_get_field(mail->head, "Subject:");	return GSMS_POP3_OK;}static GSmsPop3Error pop3_get_all_new_headers(const GSmsSocket * s,					      GList * mails){	GList *mailent;	GSmsMail *mail;	GSmsPop3Error res;	mailent = g_list_first(mails);	while (mailent != NULL) {		mail = mailent->data;		mailent = g_list_next(mailent);		if (mail->new == TRUE) {			if ((res = pop3_get_header(s, mail)) < 0)				return res;		}	}	return GSMS_POP3_OK;}/********* public functions **********/GSmsPop3 *gsms_pop3_init(GSmsSocket * s){	GSmsPop3 *pd;	g_return_val_if_fail(s != NULL, NULL);	if (pop3_get_ok(s, NULL) != GSMS_POP3_OK)		return NULL;	pd = g_new(GSmsPop3, 1);	pd->state = GSMS_POP3_AUTHORIZATION;	pd->s = s;	pd->mails = NULL;	return pd;}GSmsPop3Error gsms_pop3_auth(GSmsPop3 * pd, const gchar * uname,			     const gchar * passwd){	GSmsPop3Error res;	g_return_val_if_fail(pd != NULL, GSMS_POP3_ERROR);	g_return_val_if_fail(uname != NULL, GSMS_POP3_ERROR);	g_return_val_if_fail(passwd != NULL, GSMS_POP3_ERROR);	if (pd->state != GSMS_POP3_AUTHORIZATION)		return GSMS_POP3_ERROR_STATE;	if (gsms_socket_printf(pd->s, "USER %s\n", uname) < 0)		return GSMS_POP3_ERROR_NET;	if ((res = pop3_get_ok(pd->s, NULL)) != GSMS_POP3_OK)		return res;	gsms_socket_printf(pd->s, "PASS %s\n", passwd);	res = pop3_get_ok(pd->s, NULL);	if (res == GSMS_POP3_OK)		pd->state = GSMS_POP3_TRANSACTION;	return res;}GSmsPop3Error gsms_pop3_mail_getnew(GSmsPop3 * pd){	GSmsPop3Error res;	g_return_val_if_fail(pd != NULL, GSMS_POP3_ERROR);	if ((res = pop3_get_uidl(pd->s, &pd->mails)) != GSMS_POP3_OK)		return res;	res = pop3_get_all_new_headers(pd->s, pd->mails);	return res;}GList *gsms_pop3_get_mailbox(GSmsPop3 * pd){	return pd->mails;}void gsms_pop3_set_mailbox(GSmsPop3 * pd, GList * mb){	pd->mails = mb;	return;}GSmsPop3Error gsms_pop3_load_headers(GSmsPop3 * pd, FILE * f){	GSmsMail *mail;	gchar buf[POP3_BUFSIZE];	GString *head;	gboolean done = FALSE;	gchar *p;	g_return_val_if_fail(pd != NULL, GSMS_POP3_ERROR);	g_return_val_if_fail(f != NULL, GSMS_POP3_ERROR);	/* TODO:   free_mailbox(pd->mails); */	pd->mails = NULL;	/* read file header */	if (fgets(buf, sizeof(buf), f) == NULL) {		return GSMS_POP3_ERROR;	}	if (strncmp(buf, "# GSMS POP3 Headers; Version 1", 29) != 0)		return GSMS_POP3_ERROR;	/* read mails */	if (fgets(buf, sizeof(buf), f) == NULL) {		return GSMS_POP3_ERROR;	}	if (buf[0] != '.')		return GSMS_POP3_ERROR;	while (!done) {		if (buf[1] != ' ')			return GSMS_POP3_ERROR;		mail = g_new0(GSmsMail, 1);		gsms_str_strip_crlf(buf);		mail->uid = g_strdup(buf + 2);		head = g_string_sized_new(POP3_BUFSIZE);		while ((p = fgets(buf, sizeof(buf), f)) != NULL) {			if (buf[0] == '.')				break;			head = g_string_append(head, buf);		}		if (p == NULL && !feof(f)) {			g_free(mail);			g_string_free(head, TRUE);			return GSMS_POP3_ERROR;		}		if (buf[0] != '.')			done = TRUE;		mail->head = g_strdup(head->str);		g_string_free(head, TRUE);		mail->from = mail_get_field(mail->head, "From:");		mail->to = mail_get_field(mail->head, "To:");		mail->subject = mail_get_field(mail->head, "Subject:");		pd->mails = g_list_append(pd->mails, mail);	}	return GSMS_POP3_OK;}GSmsPop3Error gsms_pop3_save_headers(GSmsPop3 * pd, FILE * f){	GList *mailent;	GSmsMail *mail;	g_return_val_if_fail(pd != NULL, GSMS_POP3_ERROR);	g_return_val_if_fail(f != NULL, GSMS_POP3_ERROR);	fprintf(f, "# GSMS POP3 Headers; Version 1\n");	mailent = g_list_first(pd->mails);	while (mailent != NULL) {		mail = mailent->data;		mailent = g_list_next(mailent);		if (mail->uid != NULL) {			if (fprintf(f, ". %s\n", mail->uid) <= 0)				return GSMS_POP3_ERROR;			if (fprintf(f, "%s", mail->head) <= 0)				return GSMS_POP3_ERROR;		}	}	return GSMS_POP3_OK;}GSmsPop3Error gsms_pop3_mail_delete(GSmsPop3 * pd, GSmsMail * m){	GSmsPop3Error res;	gchar buf[POP3_BUFSIZE];	gchar uid[POP3_BUFSIZE];	gint num;	g_return_val_if_fail(m != NULL, GSMS_POP3_ERROR);	if (pd->state != GSMS_POP3_TRANSACTION)		return GSMS_POP3_ERROR_STATE;	/* security check: */	/*   check if the mail on the server has the same uid */	if (gsms_socket_printf(pd->s, "UIDL %d\n", m->msg_num) < 0)		return GSMS_POP3_ERROR_NET;	if ((res = pop3_get_ok(pd->s, buf)) != GSMS_POP3_OK)		return res;	if (sscanf(buf, "%d %s", &num, uid) != 2)		return GSMS_POP3_ERROR_PROTO;	if (num != m->msg_num)		return GSMS_POP3_ERROR_PROTO;	if (strcmp(uid, m->uid) != 0)		return GSMS_POP3_ERROR;	if ((res = gsms_socket_printf(pd->s, "DELE %d\n", num)) < 0)		return res;	if ((res = pop3_get_ok(pd->s, buf)) != GSMS_POP3_OK)		return res;	m->on_server = FALSE;	pd->mails = pop3_expire(pd->mails);	return GSMS_POP3_OK;}GSmsPop3Error gsms_pop3_mail_get_body(GSmsPop3 * pd, GSmsMail * m){	GSmsPop3Error res;	gchar buf[POP3_BUFSIZE];	GString *body;	gint length;	g_return_val_if_fail(m != NULL, GSMS_POP3_ERROR);	if (pd->state != GSMS_POP3_TRANSACTION)		return GSMS_POP3_ERROR_STATE;	if (gsms_socket_printf(pd->s, "RETR %d\n", m->msg_num) < 0)		return GSMS_POP3_ERROR_NET;	if ((res = pop3_get_ok(pd->s, NULL)) != GSMS_POP3_OK)		return res;	body = g_string_sized_new(POP3_BUFSIZE);	while ((length = gsms_socket_read_line(pd->s, buf, sizeof(buf))) >	       0) {		if (buf[0] == '.' && buf[1] == '.') {			body = g_string_append(body, buf + 1);			continue;		} else {			break;		}		body = g_string_append(body, buf);	}	if (length <= 0) {		g_string_free(body, TRUE);		return -1;	/* TODO ERROR CODE */	}	m->body = g_strdup(body->str);	g_string_free(body, TRUE);	return GSMS_POP3_OK;}/* ATTN: You have to free your Mail list !!! */GSmsPop3Error gsms_pop3_close(GSmsPop3 * pd){	GSmsPop3Error res;	if (gsms_socket_write_str(pd->s, "QUIT\n") < 0)		return GSMS_POP3_ERROR_NET;	if ((res = pop3_get_ok(pd->s, NULL)) != GSMS_POP3_OK)		return res;	g_free(pd);	return GSMS_POP3_OK;}

⌨️ 快捷键说明

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