mail.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:22k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2001  Dizzy (dizzy@roedu.net)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #define MAIL_INTERNAL_ACCESS
  19. #include "common/setup_before.h"
  20. #include <stdio.h>
  21. #ifdef HAVE_STDDEF_H
  22. # include <stddef.h>
  23. #else
  24. # ifndef NULL
  25. #  define NULL ((void *)0)
  26. # endif
  27. #endif
  28. #ifdef STDC_HEADERS
  29. # include <stdlib.h>
  30. #else
  31. # ifdef HAVE_MALLOC_H
  32. #  include <malloc.h>
  33. # endif
  34. #endif
  35. #ifdef HAVE_STRING_H
  36. # include <string.h>
  37. #else
  38. # ifdef HAVE_STRINGS_H
  39. #  include <strings.h>
  40. # endif
  41. #endif
  42. #include "compat/strcasecmp.h"
  43. #include <ctype.h>
  44. #include <errno.h>
  45. #include "compat/strerror.h"
  46. #ifdef TIME_WITH_SYS_TIME
  47. # include <sys/time.h>
  48. # include <time.h>
  49. #else
  50. # ifdef HAVE_SYS_TIME_H
  51. #  include <sys/time.h>
  52. # else
  53. #  include <time.h>
  54. # endif
  55. #endif
  56. #ifdef HAVE_SYS_TYPES_H
  57. # include <sys/types.h>
  58. #endif
  59. #ifdef HAVE_SYS_STAT_H
  60. # include <sys/stat.h>
  61. #endif
  62. #ifdef HAVE_UNISTD_H
  63. # include <unistd.h>
  64. #endif
  65. #include "compat/statmacros.h"
  66. #include "compat/mkdir.h"
  67. #include "compat/pdir.h"
  68. #ifdef HAVE_FCNTL_H
  69. # include <fcntl.h>
  70. #else
  71. # ifdef HAVE_SYS_FILE_H
  72. #  include <sys/file.h>
  73. # endif
  74. #endif
  75. #include "message.h"
  76. #include "connection.h"
  77. #include "common/util.h"
  78. #include "common/eventlog.h"
  79. #include "account.h"
  80. #include "prefs.h"
  81. #include "mail.h"
  82. #include "common/setup_after.h"
  83. static int identify_mail_function(const char *);
  84. static void mail_usage(t_connection*);
  85. static void mail_func_send(t_connection*,const char *);
  86. static void mail_func_read(t_connection*,const char *);
  87. static void mail_func_delete(t_connection*,const char *);
  88. static int get_mail_quota(t_account *);
  89. /* Mail API */
  90. /* for now this functions are only for internal use */
  91. static t_mailbox * mailbox_open(t_account *);
  92. static int mailbox_count(t_mailbox *);
  93. static int mailbox_deliver(t_mailbox *, const char *, const char *);
  94. static t_mail * mailbox_read(t_mailbox *, unsigned int);
  95. static void mailbox_unread(t_mail*);
  96. static struct maillist_struct * mailbox_get_list(t_mailbox *);
  97. static void mailbox_unget_list(struct maillist_struct *);
  98. static int mailbox_delete(t_mailbox *, unsigned int);
  99. static int mailbox_delete_all(t_mailbox *);
  100. static void mailbox_close(t_mailbox *);
  101. static char * clean_str(char *);
  102. static t_mailbox * mailbox_open(t_account * user) {
  103.    t_mailbox * rez;
  104.    char * path;
  105.    char const * maildir;
  106.    if ((rez=malloc(sizeof(t_mailbox)))==NULL) {
  107.       eventlog(eventlog_level_error,"mailbox_open","not enough memory");
  108.       return NULL;
  109.    }
  110.    maildir=prefs_get_maildir();
  111.    p_mkdir(maildir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
  112.    if ((path=malloc(strlen(maildir)+1+8+1))==NULL) {
  113.       eventlog(eventlog_level_error,"mailbox_open","not enough memory");
  114.       free(rez);
  115.       return NULL;
  116.    }
  117.    if (maildir[0]!='' && maildir[strlen(maildir)-1]=='/')
  118.       sprintf(path,"%s%06u",maildir,account_get_uid(user));
  119.    else
  120.       sprintf(path,"%s/%06u",maildir,account_get_uid(user));
  121.    p_mkdir(path,S_IRWXU | S_IXGRP | S_IRGRP | S_IROTH | S_IXOTH);
  122.    if ((rez->maildir=p_opendir(path))==NULL) {
  123.       eventlog(eventlog_level_error,"mailbox_open","error opening maildir");
  124.       free(path);
  125.       free(rez);
  126.       return NULL;
  127.    }
  128.    rez->uid=account_get_uid(user);
  129.    rez->path=path;
  130.    return rez;
  131. }
  132. static int mailbox_count(t_mailbox *mailbox) {
  133.    char const * dentry;
  134.    int count=0;
  135.    
  136.    if (mailbox==NULL) {
  137.       eventlog(eventlog_level_error,"mailbox_count","got NULL mailbox");
  138.       return -1;
  139.    }
  140.    if (mailbox->maildir==NULL) {
  141.       eventlog(eventlog_level_error,"mailbox_count","got NULL maildir");
  142.       return -1;
  143.    }
  144.    p_rewinddir(mailbox->maildir);
  145.    while ((dentry=p_readdir(mailbox->maildir))!=NULL) if (dentry[0]!='.') count++;
  146.    return count;
  147. }
  148. static int mailbox_deliver(t_mailbox * mailbox, const char * sender, const char * message) {
  149.    FILE * fd;
  150.    char * filename;
  151.    if (mailbox==NULL) {
  152.       eventlog(eventlog_level_error,"mailbox_deliver","got NULL mailbox");
  153.       return -1;
  154.    }
  155.    if (mailbox->maildir==NULL) {
  156.       eventlog(eventlog_level_error,"mailbox_deliver","got NULL maildir");
  157.       return -1;
  158.    }
  159.    if (mailbox->path==NULL) {
  160.       eventlog(eventlog_level_error,"mailbox_deliver","got NULL path");
  161.       return -1;
  162.    }
  163.    if ((filename=malloc(strlen(mailbox->path)+1+15+1))==NULL) {
  164.       eventlog(eventlog_level_error,"mailbox_deliver","not enough memory for filename");
  165.       return -1;
  166.    }
  167.    sprintf(filename,"%s/%015lu",mailbox->path,(unsigned long)time(NULL));
  168.    if ((fd=fopen(filename,"wb"))==NULL) {
  169.       eventlog(eventlog_level_error,"mailbox_deliver","got NULL file descriptor. check permissions");
  170.       free(filename);
  171.       return -1;
  172.    }
  173.    fprintf(fd,"%sn",sender); /* write the sender on the first line of message */
  174.    fprintf(fd,"%sn",message); /* then write the actual message */
  175.    fclose(fd);
  176.    free(filename);
  177.    return 0;
  178. }
  179. static t_mail * mailbox_read(t_mailbox * mailbox, unsigned int idx) {
  180.    char const * dentry;
  181.    unsigned int i;
  182.    t_mail *     rez;
  183.    FILE *       fd;
  184.    char *       filename;
  185.    
  186.    if (mailbox==NULL) {
  187.       eventlog(eventlog_level_error,"mailbox_read","got NULL mailbox");
  188.       return NULL;
  189.    }
  190.    if (mailbox->maildir==NULL) {
  191.       eventlog(eventlog_level_error,"mailbox_read","got NULL maildir");
  192.       return NULL;
  193.    }
  194.    if ((rez=malloc(sizeof(t_mail)))==NULL) {
  195.       eventlog(eventlog_level_error,"mailbox_read","not enough memory for message");
  196.       return NULL;
  197.    }
  198.    p_rewinddir(mailbox->maildir);
  199.    dentry = NULL; /* if idx < 1 we should not crash :) */
  200.    for(i=0;i<idx && (dentry=p_readdir(mailbox->maildir))!=NULL;i++)
  201.      if (dentry[0]=='.') i--;
  202.    if (dentry==NULL) {
  203.       eventlog(eventlog_level_error,"mailbox_read","index out of range");
  204.       free(rez);
  205.       return NULL;
  206.    }
  207.    rez->timestamp=atoi(dentry);
  208.    if ((filename=malloc(strlen(dentry)+1+strlen(mailbox->path)+1))==NULL) {
  209.       eventlog(eventlog_level_error,"mailbox_read","not enough memory for filename");
  210.       free(rez);
  211.       return NULL;
  212.    }
  213.    sprintf(filename,"%s/%s",mailbox->path,dentry);
  214.    if ((fd=fopen(filename,"rb"))==NULL) {
  215.       eventlog(eventlog_level_error,"mailbox_read","error while opening message");
  216.       free(rez);
  217.       free(filename);
  218.       return NULL;
  219.    }
  220.    free(filename);
  221.    if ((rez->sender=malloc(256))==NULL) {
  222.       eventlog(eventlog_level_error,"mailbox_read","not enough memory for storing sender");
  223.       fclose(fd);
  224.       free(rez);
  225.       return NULL;
  226.    }
  227.    fgets(rez->sender,256,fd); /* maybe 256 isnt the right value to bound a line but right now its all i have :) */
  228.    clean_str(rez->sender);
  229.    if ((rez->message=malloc(256))==NULL) {
  230.       eventlog(eventlog_level_error,"mailbox_read","not enough memory for storing message");
  231.       fclose(fd);
  232.       free(rez->sender);
  233.       free(rez);
  234.       return NULL;
  235.    }
  236.    fgets(rez->message,256,fd);
  237.    clean_str(rez->message);
  238.    fclose(fd);
  239.    rez->timestamp=atoi(dentry);
  240.    return rez;
  241. }
  242. static void mailbox_unread(t_mail * mail) {
  243.    if (mail==NULL)
  244.      eventlog(eventlog_level_error,"mailbox_unread","got NULL mail");
  245.    else {
  246.       if (mail->sender==NULL)
  247. eventlog(eventlog_level_error,"mailbox_unread","got NULL sender");
  248.       else free(mail->sender);
  249.       if (mail->message==NULL)
  250. eventlog(eventlog_level_error,"mailbox_unread","got NULL message");
  251.       else free(mail->message);
  252.       free(mail);
  253.    }
  254. }
  255. static struct maillist_struct * mailbox_get_list(t_mailbox *mailbox) {
  256.    char const * dentry;
  257.    FILE * fd;
  258.    struct maillist_struct *rez=NULL, *p=NULL,*q;
  259.    char *sender,*filename;
  260.    
  261.    if (mailbox==NULL) {
  262.       eventlog(eventlog_level_error,"mailbox_get_list","got NULL mailbox");
  263.       return NULL;
  264.    }
  265.    if (mailbox->maildir==NULL) {
  266.       eventlog(eventlog_level_error,"mailbox_get_list","got NULL maildir");
  267.       return NULL;
  268.    }
  269.    if ((filename=malloc(strlen(mailbox->path)+1+15+1))==NULL) {
  270.       eventlog(eventlog_level_error,"mailbox_get_list","not enough memory for filename");
  271.       return NULL;
  272.    }
  273.    p_rewinddir(mailbox->maildir);
  274.    for(;(dentry=p_readdir(mailbox->maildir))!=NULL;)
  275.      if (dentry[0]!='.') {
  276. q=malloc(sizeof(struct maillist_struct));
  277. if (q==NULL) {
  278.    eventlog(eventlog_level_error,"mailbox_get_list","not enough memory for list");
  279.    free(filename);
  280.    return rez;
  281. }
  282. sprintf(filename,"%s/%s",mailbox->path,dentry);
  283. if ((fd=fopen(filename,"rb"))==NULL) {
  284.    eventlog(eventlog_level_error,"mailbox_get_list","error while opening message file");
  285.    free(filename);
  286.    free(q);
  287.    return rez;
  288. }
  289. if ((sender=malloc(256))==NULL) {
  290.    eventlog(eventlog_level_error,"mailbox_get_list","not enough memory for sender");
  291.    fclose(fd);
  292.    free(filename);
  293.    free(q);
  294. }
  295. fgets(sender,256,fd);
  296. clean_str(sender);
  297. fclose(fd);
  298. q->sender=sender;
  299. q->timestamp=atoi(dentry);
  300. q->next=NULL;
  301. if (p==NULL) rez=q;
  302. else p->next=q;
  303. p=q;
  304.      }
  305.    free(filename);
  306.    return rez;
  307. }
  308. static void mailbox_unget_list(struct maillist_struct * maill) {
  309.    struct maillist_struct *p, *q;
  310.    
  311.    for(p=maill;p!=NULL;p=q) {
  312.       if (p->sender!=NULL) free(p->sender);
  313.       q=p->next;
  314.       free(p);
  315.    }
  316. }
  317. static int mailbox_delete(t_mailbox * mailbox, unsigned int idx) {
  318.    char *       filename;
  319.    char const * dentry;
  320.    unsigned int i;
  321.    int          rez;
  322.    
  323.    if (mailbox==NULL) {
  324.       eventlog(eventlog_level_error,"mailbox_delete","got NULL mailbox");
  325.       return -1;
  326.    }
  327.    if (mailbox->maildir==NULL) {
  328.       eventlog(eventlog_level_error,"mailbox_delete","got NULL maildir");
  329.       return -1;
  330.    }
  331.    p_rewinddir(mailbox->maildir);
  332.    dentry = NULL; /* if idx < 1 we should not crash :) */
  333.    for(i=0;i<idx && (dentry=p_readdir(mailbox->maildir))!=NULL;i++)
  334.      if (dentry[0]=='.') i--;
  335.    if (dentry==NULL) {
  336.       eventlog(eventlog_level_error,"mailbox_delete","index out of range");
  337.       return -1;
  338.    }
  339.    if ((filename=malloc(strlen(dentry)+1+strlen(mailbox->path)+1))==NULL) {
  340.       eventlog(eventlog_level_error,"mailbox_delete","not enough memory for filename");
  341.       return -1;
  342.    }
  343.    sprintf(filename,"%s/%s",mailbox->path,dentry);
  344.    rez=remove(filename);
  345.    if (rez<0) {
  346.        eventlog(eventlog_level_info,"mailbox_delete","could not remove file "%s" (remove: %s)",filename,strerror(errno));
  347.     }
  348.    free(filename);
  349.    return rez;
  350. }
  351. static int mailbox_delete_all(t_mailbox * mailbox) {
  352.    char *       filename;
  353.    char const * dentry;
  354.    int          count;
  355.    
  356.    if (mailbox==NULL) {
  357.       eventlog(eventlog_level_error,"mailbox_delete_all","got NULL mailbox");
  358.       return -1;
  359.    }
  360.    if (mailbox->maildir==NULL) {
  361.       eventlog(eventlog_level_error,"mailbox_delete_all","got NULL maildir");
  362.       return -1;
  363.    }
  364.    if ((filename=malloc(strlen(mailbox->path)+1+15+1))==NULL) {
  365.       eventlog(eventlog_level_error,"mailbox_delete_all","not enough memory for filename");
  366.       return -1;
  367.    }
  368.    p_rewinddir(mailbox->maildir);
  369.    count = 0;
  370.    while ((dentry=p_readdir(mailbox->maildir))!=NULL)
  371.      if (dentry[0]!='.') {
  372. sprintf(filename,"%s/%s",mailbox->path,dentry);
  373. if (!remove(filename)) count++;
  374.      }
  375.    free(filename);
  376.    return count;
  377. }
  378. static void mailbox_close(t_mailbox *mailbox) {
  379.    if (mailbox==NULL) {
  380.       eventlog(eventlog_level_error,"mailbox_close","got NULL mailbox");
  381.       return;
  382.    }
  383.    if (mailbox->maildir!=NULL) {
  384.       p_closedir(mailbox->maildir);
  385.    } else {
  386.       eventlog(eventlog_level_error,"mailbox_close","got NULL maildir");
  387.    }
  388.    if (mailbox->path) free(mailbox->path);
  389.    free(mailbox);
  390. }
  391. static char * clean_str(char * str) {
  392.    char *p;
  393.    
  394.    for(p=str;*p!='';p++)
  395.      if (*p=='n' || *p=='r') {
  396. *p=''; break;
  397.      }
  398.    return str;
  399. }
  400. extern int handle_mail_command(t_connection * c, char const * text)
  401. {
  402.    unsigned int i,j;
  403.    char         comm[MAX_FUNC_LEN];
  404.    
  405.    if (!prefs_get_mail_support()) { 
  406.       message_send_text(c,message_type_error,c,"This server has NO mail support.");
  407.       return -1;
  408.    }
  409.    
  410.    for (i=0; text[i]!=' ' && text[i]!=''; i++); /* skip /mail command */
  411.    for (; text[i]==' '; i++); /* skip any spaces after it */
  412.    
  413.    for (j=0; text[i]!=' ' && text[i]!='' && j<sizeof(comm)-1; i++) /* get function */
  414.      if (j<sizeof(comm)-1) comm[j++] = text[i];
  415.    comm[j] = '';
  416.    
  417.    switch (identify_mail_function(comm)) {
  418.     case MAIL_FUNC_SEND:
  419.       mail_func_send(c,text+i);
  420.       break;
  421.     case MAIL_FUNC_READ:
  422.       mail_func_read(c,text+i);
  423.       break;
  424.     case MAIL_FUNC_DELETE:
  425.       mail_func_delete(c,text+i);
  426.       break;
  427.     case MAIL_FUNC_HELP:
  428.       message_send_text(c,message_type_info,c,"The mail command supports the following patterns.");
  429.       mail_usage(c);
  430.       break;
  431.     default:
  432.       message_send_text(c,message_type_error,c,"The command its incorrect. Use one of the following patterns.");
  433.       mail_usage(c);
  434.    }
  435.    return 0;
  436. }
  437. static int identify_mail_function(const char *funcstr) {
  438.     if (strcasecmp(funcstr,"send")==0 ||
  439.         strcasecmp(funcstr,"s")==0)
  440. return MAIL_FUNC_SEND;
  441.     if (strcasecmp(funcstr,"read")==0 ||
  442.         strcasecmp(funcstr,"r")==0 ||
  443.         strcasecmp(funcstr,"")==0)
  444. return MAIL_FUNC_READ;
  445.     if (strcasecmp(funcstr,"delete")==0 ||
  446.         strcasecmp(funcstr,"del")==0)
  447. return MAIL_FUNC_DELETE;
  448.     if (strcasecmp(funcstr,"help")==0 ||
  449.         strcasecmp(funcstr,"h")==0)
  450. return MAIL_FUNC_HELP;
  451.     return MAIL_FUNC_UNKNOWN;
  452. }
  453. static int get_mail_quota(t_account * user) {
  454.    int quota;
  455.    char const * user_quota;
  456.    user_quota=account_get_strattr(user,"BNET\auth\mailquota");
  457.    if (user_quota==NULL) quota=prefs_get_mail_quota();
  458.    else {
  459.       quota=atoi(user_quota);
  460.       if (quota<1) quota=1;
  461.       if (quota>MAX_MAIL_QUOTA) quota=MAX_MAIL_QUOTA;
  462.    }
  463.    return quota;
  464. }
  465. static void mail_func_send(t_connection * c, const char * str) {
  466.    int i;
  467.    char *dest;
  468.    char const *p,*myname;   
  469.    t_account * recv;
  470.    t_mailbox * mailbox;
  471.    
  472.    if (c==NULL) {
  473.       eventlog(eventlog_level_error,"mail_func_send","got NULL connection");
  474.       return;
  475.    }
  476.    if (str==NULL) {
  477.       eventlog(eventlog_level_error,"mail_func_send","got NULL command string");
  478.       return;
  479.    }
  480.    for(i=0;str[i]==' ';i++); /* skip any spaces */
  481.    if (str[i]=='') { /* the %mail send command has no receiver */
  482.       message_send_text(c,message_type_error,c,"You must specify the receiver");
  483.       message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>");
  484.       return;
  485.    }
  486.    p=str+i; /* set ip at the start of receiver string */
  487.    for(i=1;p[i]!=' ' && p[i]!='';i++); /* skip the receiver string */
  488.    if (p[i]=='') { /* it seems user forgot to write any message */
  489.       message_send_text(c,message_type_error,c,"Your message is empty!");
  490.       message_send_text(c,message_type_error,c,"Syntax: /mail send <receiver> <message>");
  491.       return;
  492.    }
  493.    if ((dest=malloc(i+1))==NULL) {
  494.       eventlog(eventlog_level_error,"mail_func_send","not enough memory for receiver");
  495.       message_send_text(c,message_type_error,c,"Not enough resources to complete request!");
  496.       return;
  497.    }
  498.    memmove(dest,p,i); dest[i]=''; /* copy receiver in his separate string */
  499.    if ((recv=accountlist_find_account(dest))==NULL) { /* is dest a valid account on this server ? */
  500.       message_send_text(c,message_type_error,c,"Receiver UNKNOWN!");
  501.       free(dest);
  502.       return;
  503.    }
  504.    free(dest); /* free dest here, the sooner the better */
  505.    if ((mailbox=mailbox_open(recv))==NULL) {
  506.       message_send_text(c,message_type_error,c,"There was an error completing your request!");
  507.       return;
  508.    }
  509.    if (get_mail_quota(recv)<=mailbox_count(mailbox)) { /* check quota */
  510.       message_send_text(c,message_type_error,c,"Receiver has reached his mail quota. Your message will NOT be sent.");
  511.       mailbox_close(mailbox);
  512.       return;
  513.    }
  514.    myname=conn_get_username(c); /* who am i ? */
  515.    if (mailbox_deliver(mailbox,myname,p+i+1)<0)
  516.      message_send_text(c,message_type_error,c,"There was an error completing your request!");
  517.    else 
  518.      message_send_text(c,message_type_info,c,"Your mail has been sent successfully.");
  519.    conn_unget_username(c,myname);
  520.    mailbox_close(mailbox);
  521. }
  522. static void mail_func_read(t_connection * c, const char * str) {
  523.    t_account * user;
  524.    t_mailbox * mailbox;
  525.    const char *p;
  526.    char tmp[256];
  527.    int i;
  528.    
  529.    if (c==NULL) {
  530.       eventlog(eventlog_level_error,"mail_func_read","got NULL connection");
  531.       return;
  532.    }
  533.    if (str==NULL) {
  534.       eventlog(eventlog_level_error,"mail_func_read","got NULL command string");
  535.       return;
  536.    }
  537.    for(i=0;str[i]==' ';i++);
  538.    p=str+i;
  539.    if ((user=conn_get_account(c))==NULL) {
  540.       eventlog(eventlog_level_error,"mail_func_read","got NULL account");
  541.       return;
  542.    }
  543.    if ((mailbox=mailbox_open(user))==NULL) {
  544.       eventlog(eventlog_level_error,"mail_func_read","got NULL mailbox");
  545.       return;
  546.    }
  547.    if (*p=='') { /* user wants to see the mail summary */
  548.       struct maillist_struct *maill, *mp;
  549.       unsigned int idx;
  550.       
  551.       if (mailbox_count(mailbox)==0) {
  552.  message_send_text(c,message_type_info,c,"You have no mail.");
  553.  mailbox_close(mailbox);
  554.  return;
  555.       }
  556.       if ((maill=mailbox_get_list(mailbox))==NULL) {
  557.  eventlog(eventlog_level_error,"mail_func_read","got NULL maillist");
  558.  mailbox_close(mailbox);
  559.  return;
  560.       }
  561.       sprintf(tmp,"You have %d messages. Your mail qouta is set to %d.",mailbox_count(mailbox),get_mail_quota(user));
  562.       message_send_text(c,message_type_info,c,tmp);
  563.       message_send_text(c,message_type_info,c,"ID    Sender          Date");
  564.       message_send_text(c,message_type_info,c,"-------------------------------------");
  565.       for(mp=maill,idx=1;mp!=NULL;mp=mp->next,idx++) {
  566.  sprintf(tmp,"%02u    %-14s %s",idx,mp->sender,ctime(&mp->timestamp));
  567.  clean_str(tmp); /* ctime() appends an newline that we get cleaned */
  568.  message_send_text(c,message_type_info,c,tmp);
  569.       }
  570.       message_send_text(c,message_type_info,c,"Use /mail read <ID> to read the content of any message");
  571.       mailbox_unget_list(maill);
  572.    }
  573.    else { /* user wants to read a message */
  574.       int idx;
  575.       t_mail * mail;
  576.       
  577.       for(i=0;p[i]>='0' && p[i]<='9' && p[i]!='';i++);
  578.       if (p[i]!='' && p[i]!=' ') {
  579.  message_send_text(c,message_type_error,c,"Invalid index. Please use /mail read <index> where <index> is a number.");
  580.  mailbox_close(mailbox);
  581.  return;
  582.       }
  583.       idx=atoi(p);
  584.       if (idx<1 || idx>mailbox_count(mailbox)) {
  585.  message_send_text(c,message_type_error,c,"That index is out of range.");
  586.  mailbox_close(mailbox);
  587.  return;
  588.       }
  589.       if ((mail=mailbox_read(mailbox,idx))==NULL) {
  590.  message_send_text(c,message_type_error,c,"There was an error completing your request.");
  591.  mailbox_close(mailbox);
  592.  return;
  593.       }
  594.       sprintf(tmp,"Message #%d from %s on %s:",idx,mail->sender,clean_str(ctime(&mail->timestamp)));
  595.       message_send_text(c,message_type_info,c,tmp);
  596.       message_send_text(c,message_type_info,c,mail->message);
  597.       mailbox_unread(mail);
  598.    }
  599.    mailbox_close(mailbox);
  600. }
  601. static void mail_func_delete(t_connection * c, const char * str) {
  602.    t_account * user;
  603.    t_mailbox * mailbox;
  604.    const char * p;
  605.    char tmp[256]; /* that should be enough */
  606.    int i;
  607.    
  608.    if (c==NULL) {
  609.       eventlog(eventlog_level_error,"mail_func_delete","got NULL connection");
  610.       return;
  611.    }
  612.    if (str==NULL) {
  613.       eventlog(eventlog_level_error,"mail_func_delete","got NULL command string");
  614.       return;
  615.    }
  616.    for(i=0;str[i]==' ';i++);
  617.    p=str+i;
  618.    if (*p=='') {
  619.       message_send_text(c,message_type_error,c,"Please specify which message to delete. Use the following syntax: /mail delete {<index>|all} .");
  620.       return;
  621.    }
  622.    if ((user=conn_get_account(c))==NULL) {
  623.       eventlog(eventlog_level_error,"mail_func_read","got NULL account");
  624.       return;
  625.    }
  626.    if ((mailbox=mailbox_open(user))==NULL) {
  627.       eventlog(eventlog_level_error,"mail_func_read","got NULL mailbox");
  628.       return;
  629.    }
  630.    if (strcmp(p,"all")==0) {
  631.       int rez;
  632.       
  633.       if ((rez=mailbox_delete_all(mailbox))<0) {
  634.  message_send_text(c,message_type_error,c,"There was an error completing your request.");
  635.  mailbox_close(mailbox);
  636.  return;
  637.       }
  638.       sprintf(tmp,"Successfuly deleted %d messages.",rez);
  639.       message_send_text(c,message_type_info,c,tmp);
  640.    }
  641.    else {
  642.       int idx;
  643.       
  644.       for(i=0;p[i]>='0' && p[i]<='9' && p[i]!='';i++);
  645.       if (p[i]!='' && p[i]!=' ') {
  646.  message_send_text(c,message_type_error,c,"Invalid index. Please use /mail delete {<index>|all} where <index> is a number.");
  647.  mailbox_close(mailbox);
  648.  return;
  649.       }
  650.       idx=atoi(p);
  651.       if (idx<1 || idx>mailbox_count(mailbox)) {
  652.  message_send_text(c,message_type_error,c,"That index is out of range.");
  653.  mailbox_close(mailbox);
  654.  return;
  655.       }
  656.       if (mailbox_delete(mailbox,idx)<0) {
  657.  message_send_text(c,message_type_error,c,"There was an error completing your request.");
  658.  mailbox_close(mailbox);
  659.  return;
  660.       }
  661.       sprintf(tmp,"Succesfully deleted message #%02d.",idx);
  662.       message_send_text(c,message_type_info,c,tmp);
  663.    }
  664.    mailbox_close(mailbox);
  665. }
  666. static void mail_usage(t_connection * c) {
  667.    message_send_text(c,message_type_info,c,"to print this information:");
  668.    message_send_text(c,message_type_info,c,"    /mail help");
  669.    message_send_text(c,message_type_info,c,"to print an index of you messages:");
  670.    message_send_text(c,message_type_info,c,"    /mail [read]");
  671.    message_send_text(c,message_type_info,c,"to send a message:");
  672.    message_send_text(c,message_type_info,c,"    /mail send <receiver> <message>");
  673.    message_send_text(c,message_type_info,c,"to read a message:");
  674.    message_send_text(c,message_type_info,c,"    /mail read <index num>");
  675.    message_send_text(c,message_type_info,c,"to delete a message:");
  676.    message_send_text(c,message_type_info,c,"    /mail delete {<index>|all}");
  677.    message_send_text(c,message_type_info,c,"Commands may be abbreviated as follows:");
  678.    message_send_text(c,message_type_info,c,"    help: h");
  679.    message_send_text(c,message_type_info,c,"    read: r");
  680.    message_send_text(c,message_type_info,c,"    send: s");
  681.    message_send_text(c,message_type_info,c,"    delete: del");
  682. }