📄 mail.c
字号:
/* * Copyright (C) 2001 Dizzy * Copyright (C) 2004 Donny Redmond (dredmond@linuxmail.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#define MAIL_INTERNAL_ACCESS#include "common/setup_before.h"#include <stdio.h>#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include "compat/strcasecmp.h"#include <ctype.h>#include <errno.h>#include "compat/strerror.h"#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_SYS_STAT_H# include <sys/stat.h>#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include "compat/statmacros.h"#include "compat/mkdir.h"#include "compat/pdir.h"#ifdef HAVE_FCNTL_H# include <fcntl.h>#else# ifdef HAVE_SYS_FILE_H# include <sys/file.h># endif#endif#include "message.h"#include "connection.h"#include "common/util.h"#include "common/eventlog.h"#include "common/xalloc.h"#include "account.h"#include "prefs.h"#include "mail.h"#include "common/setup_after.h"static int identify_mail_function(const char *);static void mail_usage(t_connection*);static void mail_func_send(t_connection*,const char *);static void mail_func_read(t_connection*,const char *);static void mail_func_delete(t_connection*,const char *);static int get_mail_quota(t_account *);/* Mail API *//* for now this functions are only for internal use */static t_mailbox * mailbox_open(t_account *, t_mbox_mode mode);static int mailbox_count(t_mailbox *);static int mailbox_deliver(t_mailbox *, const char *, const char *);static t_mail * mailbox_read(t_mailbox *, unsigned int);static void mailbox_unread(t_mail*);static struct maillist_struct * mailbox_get_list(t_mailbox *);static void mailbox_unget_list(struct maillist_struct *);static int mailbox_delete(t_mailbox *, unsigned int);static int mailbox_delete_all(t_mailbox *);static void mailbox_close(t_mailbox *);static char * clean_str(char *);static t_mailbox * mailbox_open(t_account * user, t_mbox_mode mode) { t_mailbox * rez; char * path; char const * maildir; rez=xmalloc(sizeof(t_mailbox)); maildir=prefs_get_maildir(); if (mode & mbox_mode_write) p_mkdir(maildir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); path=xmalloc(strlen(maildir)+1+8+1); if (maildir[0]!='\0' && maildir[strlen(maildir)-1]=='/') sprintf(path,"%s%06u",maildir,account_get_uid(user)); else sprintf(path,"%s/%06u",maildir,account_get_uid(user)); if (mode & mbox_mode_write) p_mkdir(path,S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH); if ((rez->maildir=p_opendir(path))==NULL) { if (mode & mbox_mode_write) eventlog(eventlog_level_error,__FUNCTION__,"error opening maildir"); xfree(path); xfree(rez); return NULL; } rez->uid=account_get_uid(user); rez->path=path; return rez;}static int mailbox_count(t_mailbox *mailbox) { char const * dentry; int count=0; /* consider NULL mailbox as empty mailbox */ if (mailbox==NULL) return 0; if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return -1; } p_rewinddir(mailbox->maildir); while ((dentry=p_readdir(mailbox->maildir))!=NULL) if (dentry[0]!='.') count++; return count;}static int mailbox_deliver(t_mailbox * mailbox, const char * sender, const char * message) { FILE * fd; char * filename; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return -1; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return -1; } if (mailbox->path==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL path"); return -1; } filename=xmalloc(strlen(mailbox->path)+1+15+1); sprintf(filename,"%s/%015lu",mailbox->path,(unsigned long)time(NULL)); if ((fd=fopen(filename,"wb"))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL file descriptor. check permissions"); xfree(filename); return -1; } fprintf(fd,"%s\n",sender); /* write the sender on the first line of message */ fprintf(fd,"%s\n",message); /* then write the actual message */ fclose(fd); xfree(filename); return 0;}static t_mail * mailbox_read(t_mailbox * mailbox, unsigned int idx) { char const * dentry; unsigned int i; t_mail * rez; FILE * fd; char * filename; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return NULL; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return NULL; } rez=xmalloc(sizeof(t_mail)); p_rewinddir(mailbox->maildir); dentry = NULL; /* if idx < 1 we should not crash :) */ for(i=0;i<idx && (dentry=p_readdir(mailbox->maildir))!=NULL;i++) if (dentry[0]=='.') i--; if (dentry==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"index out of range"); xfree(rez); return NULL; } rez->timestamp=atoi(dentry); filename=xmalloc(strlen(dentry)+1+strlen(mailbox->path)+1); sprintf(filename,"%s/%s",mailbox->path,dentry); if ((fd=fopen(filename,"rb"))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"error while opening message"); xfree(rez); xfree(filename); return NULL; } xfree(filename); rez->sender=xmalloc(256); fgets(rez->sender,256,fd); /* maybe 256 isnt the right value to bound a line but right now its all i have :) */ clean_str(rez->sender); rez->message=xmalloc(256); fgets(rez->message,256,fd); clean_str(rez->message); fclose(fd); rez->timestamp=atoi(dentry); return rez;}static void mailbox_unread(t_mail * mail) { if (mail==NULL) eventlog(eventlog_level_error,__FUNCTION__,"got NULL mail"); else { if (mail->sender==NULL) eventlog(eventlog_level_error,__FUNCTION__,"got NULL sender"); else xfree(mail->sender); if (mail->message==NULL) eventlog(eventlog_level_error,__FUNCTION__,"got NULL message"); else xfree(mail->message); xfree(mail); }}static struct maillist_struct * mailbox_get_list(t_mailbox *mailbox) { char const * dentry; FILE * fd; struct maillist_struct *rez=NULL, *p=NULL,*q; char *sender,*filename; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return NULL; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return NULL; } filename=xmalloc(strlen(mailbox->path)+1+15+1); p_rewinddir(mailbox->maildir); for(;(dentry=p_readdir(mailbox->maildir))!=NULL;) if (dentry[0]!='.') { q=xmalloc(sizeof(struct maillist_struct)); sprintf(filename,"%s/%s",mailbox->path,dentry); if ((fd=fopen(filename,"rb"))==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"error while opening message file"); xfree(filename); xfree(q); return rez; } sender=xmalloc(256); fgets(sender,256,fd); clean_str(sender); fclose(fd); q->sender=sender; q->timestamp=atoi(dentry); q->next=NULL; if (p==NULL) rez=q; else p->next=q; p=q; } xfree(filename); return rez;}static void mailbox_unget_list(struct maillist_struct * maill) { struct maillist_struct *p, *q; for(p=maill;p!=NULL;p=q) { if (p->sender!=NULL) xfree(p->sender); q=p->next; xfree(p); }}static int mailbox_delete(t_mailbox * mailbox, unsigned int idx) { char * filename; char const * dentry; unsigned int i; int rez; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return -1; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return -1; } p_rewinddir(mailbox->maildir); dentry = NULL; /* if idx < 1 we should not crash :) */ for(i=0;i<idx && (dentry=p_readdir(mailbox->maildir))!=NULL;i++) if (dentry[0]=='.') i--; if (dentry==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"index out of range"); return -1; } filename=xmalloc(strlen(dentry)+1+strlen(mailbox->path)+1); sprintf(filename,"%s/%s",mailbox->path,dentry); rez=remove(filename); if (rez<0) { eventlog(eventlog_level_info,__FUNCTION__,"could not remove file \"%s\" (remove: %s)",filename,pstrerror(errno)); } xfree(filename); return rez;}static int mailbox_delete_all(t_mailbox * mailbox) { char * filename; char const * dentry; int count; if (mailbox==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL mailbox"); return -1; } if (mailbox->maildir==NULL) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL maildir"); return -1; } filename=xmalloc(strlen(mailbox->path)+1+15+1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -