mail.c

Go to the documentation of this file.
00001 /* Mail utility routines.
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  *
00012  */
00013 
00014 #include "services.h"
00015 #include "language.h"
00016 
00017 /*************************************************************************/
00018 
00029 MailInfo *MailRegBegin(User * u, NickRequest * nr, char *subject,
00030                        char *service)
00031 {
00032         int timeToWait = 0;
00033     if (!u || !nr || !subject || !service) {
00034         return NULL;
00035     }
00036 
00037     if (!UseMail) {
00038         notice_lang(service, u, MAIL_DISABLED);
00039     } else if ((time(NULL) - u->lastmail < MailDelay)) {
00040         timeToWait = MailDelay - (time(NULL) - u->lastmail);
00041         notice_lang(service, u, MAIL_DELAYED, timeToWait);
00042     } else if (!nr->email) {
00043         notice_lang(service, u, MAIL_INVALID, nr->nick);
00044     } else {
00045         MailInfo *mail;
00046         int pipefds[2];
00047 
00048         mail = scalloc(sizeof(MailInfo), 1);
00049         mail->sender = u;
00050         mail->recipient = NULL;
00051         mail->recip = nr;
00052         mail->pipe = mail->writepipe = mail->readpipe = NULL;
00053 
00054 #if HAVE_FORK
00055         if (ForkForMail && !pipe(pipefds))
00056         {
00057                 mail->writepipe = fdopen(pipefds[1], "w");
00058                 mail->readpipe = fdopen(pipefds[0], "r");
00059                 mail->pipe = mail->writepipe;
00060         }
00061 #endif
00062         if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
00063             free(mail);
00064             notice_lang(service, u, MAIL_LATER);
00065             return NULL;
00066         }
00067 
00068         fprintf(mail->pipe, "From: %s\n", SendFrom);
00069         if (DontQuoteAddresses) {
00070             fprintf(mail->pipe, "To: %s <%s>\n", nr->nick, nr->email);
00071         } else {
00072             fprintf(mail->pipe, "To: \"%s\" <%s>\n", nr->nick, nr->email);
00073         }
00074         fprintf(mail->pipe, "Subject: %s\n", subject);
00075         return mail;
00076     }
00077 
00078     return NULL;
00079 }
00080 
00081 /*************************************************************************/
00082 
00093 MailInfo *MailBegin(User * u, NickCore * nc, char *subject, char *service)
00094 {
00095     if (!u || !nc || !subject || !service) {
00096         return NULL;
00097     }
00098 
00099     if (!UseMail) {
00100         notice_lang(service, u, MAIL_DISABLED);
00101     } else if (((time(NULL) - u->lastmail < MailDelay)
00102                 || (time(NULL) - nc->lastmail < MailDelay))
00103                && !is_services_root(u)) {
00104         notice_lang(service, u, MAIL_DELAYED, MailDelay);
00105     } else if (!nc->email) {
00106         notice_lang(service, u, MAIL_INVALID, nc->display);
00107     } else {
00108         MailInfo *mail;
00109         int pipefds[2];
00110 
00111         mail = scalloc(sizeof(MailInfo), 1);
00112         mail->sender = u;
00113         mail->recipient = nc;
00114         mail->recip = NULL;
00115         mail->pipe = mail->writepipe = mail->readpipe = NULL;
00116 
00117 #if HAVE_FORK
00118         if (ForkForMail && !pipe(pipefds))
00119         {
00120                 mail->writepipe = fdopen(pipefds[1], "w");
00121                 mail->readpipe = fdopen(pipefds[0], "r");
00122                 mail->pipe = mail->writepipe;
00123         }
00124 #endif
00125         if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
00126             free(mail);
00127             notice_lang(service, u, MAIL_LATER);
00128             return NULL;
00129         }
00130 
00131         fprintf(mail->pipe, "From: %s\n", SendFrom);
00132         if (DontQuoteAddresses) {
00133             fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
00134         } else {
00135             fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
00136                     nc->email);
00137         }
00138         fprintf(mail->pipe, "Subject: %s\n", subject);
00139 
00140         return mail;
00141     }
00142 
00143     return NULL;
00144 }
00145 
00146 /*************************************************************************/
00147 
00153 MailInfo *MailMemoBegin(NickCore * nc)
00154 {
00155 
00156     if (!nc)
00157         return NULL;
00158 
00159     if (!UseMail || !nc->email) {
00160         return NULL;
00161 
00162     } else {
00163         MailInfo *mail;
00164         int pipefds[2];
00165 
00166         mail = scalloc(sizeof(MailInfo), 1);
00167         mail->sender = NULL;
00168         mail->recipient = nc;
00169         mail->recip = NULL;
00170         mail->pipe = mail->writepipe = mail->readpipe = NULL;
00171 
00172 #if HAVE_FORK
00173         if (ForkForMail && !pipe(pipefds))
00174         {
00175                 mail->writepipe = fdopen(pipefds[1], "w");
00176                 mail->readpipe = fdopen(pipefds[0], "r");
00177                 mail->pipe = mail->writepipe;
00178         }
00179 #endif
00180         if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
00181             free(mail);
00182             return NULL;
00183         }
00184 
00185         fprintf(mail->pipe, "From: %s\n", SendFrom);
00186         if (DontQuoteAddresses) {
00187             fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
00188         } else {
00189             fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
00190                     nc->email);
00191         }
00192         fprintf(mail->pipe, "Subject: %s\n",
00193                 getstring2(NULL, MEMO_MAIL_SUBJECT));
00194         return mail;
00195     }
00196     return NULL;
00197 }
00198 
00199 /*************************************************************************/
00200 
00206 void MailEnd(MailInfo * mail)
00207 {
00208    int pid = -1;
00209     /*  - param checking modified because we don't
00210        have an user sending this mail.
00211        Certus, 02.04.2004 */
00212 
00213     if (!mail || !mail->pipe) { /* removed sender check */
00214         return;
00215     }
00216 
00217     if (!mail->recipient && !mail->recip) {
00218         return;
00219     }
00220 
00221 #if HAVE_FORK
00222     if (ForkForMail && mail->writepipe && mail->readpipe && !(pid = fork()))
00223     {
00224         FILE *fd;
00225         int ret;
00226 
00227         fputc(255, mail->writepipe);
00228         fclose(mail->writepipe);
00229 
00230         fd = popen(SendMailPath, "w");
00231 
00232         if (fd)
00233         {
00234                 while ((ret = fgetc(mail->readpipe)) != 255)
00235                         fputc(ret, fd);
00236                 pclose(fd);
00237         }
00238 
00239         fclose(mail->readpipe);
00240         _exit(EXIT_SUCCESS);
00241     }
00242     else if (pid < 0)
00243 #endif
00244     {
00245         if (mail->pipe != mail->writepipe)
00246                 pclose(mail->pipe);
00247         else
00248         {
00249                 if (mail->writepipe)
00250                         fclose(mail->writepipe);
00251                 if (mail->readpipe)
00252                         fclose(mail->readpipe);
00253         }
00254     }
00255 
00256     if (mail->sender)           /* added sender check */
00257         mail->sender->lastmail = time(NULL);
00258 
00259     if (mail->recipient)
00260         mail->recipient->lastmail = time(NULL);
00261     else
00262         mail->recip->lastmail = time(NULL);
00263 
00264 
00265     free(mail);
00266 }
00267 
00268 /*************************************************************************/
00269 
00276 void MailReset(User * u, NickCore * nc)
00277 {
00278     if (u)
00279         u->lastmail = 0;
00280     if (nc)
00281         nc->lastmail = 0;
00282 }
00283 
00284 /*************************************************************************/
00285 
00296 int MailValidate(const char *email)
00297 {
00298     int i, j, has_period = 0, len;
00299     char copy[BUFSIZE], *domain;
00300 
00301     static char specials[] =
00302         { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']',
00303         ' '
00304     };
00305 
00306     if (!email)
00307         return 0;
00308     strscpy(copy, email, sizeof(copy));
00309 
00310     domain = strchr(copy, '@');
00311     if (!domain)
00312         return 0;
00313     *domain = '\0';
00314     domain++;
00315 
00316     /* Don't accept NULL copy or domain. */
00317     if (*copy == 0 || *domain == 0)
00318         return 0;
00319 
00320     /* Check for forbidden characters in the name */
00321     for (i = 0; i < strlen(copy); i++) {
00322 
00323         if (copy[i] <= 31 || copy[i] >= 127)
00324             return 0;
00325         for (j = 0; j < 13; j++)
00326             if (copy[i] == specials[j])
00327                 return 0;
00328     }
00329 
00330     /* Check for forbidden characters in the domain, and if it seems to be valid. */
00331     for (i = 0; i < (len = strlen(domain)); i++) {
00332         if (domain[i] <= 31 || domain[i] >= 127)
00333             return 0;
00334         for (j = 0; j < 13; j++)
00335             if (domain[i] == specials[j])
00336                 return 0;
00337         if (domain[i] == '.') {
00338             if (i == 0 || i == len - 1)
00339                 return 0;
00340             has_period = 1;
00341         }
00342     }
00343 
00344     if (!has_period)
00345         return 0;
00346 
00347     return 1;
00348 }