Back to index

courier  0.68.2
Classes | Defines | Functions | Variables
autoresponse.c File Reference
#include "config.h"
#include "autoresponse.h"
#include "maildir/autoresponse.h"
#include "mailfilter.h"
#include "unicode/unicode.h"
#include "sqwebmail.h"
#include "htmllibdir.h"
#include "maildir.h"
#include "maildir/maildirmisc.h"
#include "maildir/maildirfilter.h"
#include "rfc2045/rfc2045.h"
#include "newmsg.h"
#include "cgi/cgi.h"
#include "numlib/numlib.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>

Go to the source code of this file.

Classes

struct  upload_attach_info

Defines

#define WEXITSTATUS(stat_val)   ((unsigned)(stat_val) >> 8)
#define WIFEXITED(stat_val)   (((stat_val) & 255) == 0)

Functions

void output_attrencoded (const char *)
const char * calc_mime_type (const char *filename)
void charset_warning (const char *)
static void save_autoresponse (const char *p, size_t l, void *vp)
static int read_headers (FILE *)
static int show_autoresponse_trampoline (const char *ptr, size_t cnt, void *arg)
void autoresponse ()
static FILE * upload_attachment (const char *)
void autoresponsedelete ()
static int start_upload (const char *, const char *, void *)
static int upload (const char *, size_t, void *)
static void end_upload (void *)
static int upload_messagerfc822 (FILE *, FILE *)
static int comp_autorespname (const void *a, const void *b)
void autoresponselist ()
void autoresponsepick ()

Variables

const char * sqwebmail_content_charset

Class Documentation

struct upload_attach_info

Definition at line 296 of file autoresponse.c.

Class Members
const char * autorespname
const char * filename
FILE * fp
const char * name

Define Documentation

#define WEXITSTATUS (   stat_val)    ((unsigned)(stat_val) >> 8)

Definition at line 33 of file autoresponse.c.

#define WIFEXITED (   stat_val)    (((stat_val) & 255) == 0)

Definition at line 36 of file autoresponse.c.


Function Documentation

void autoresponse ( )

Definition at line 62 of file autoresponse.c.

{
const char    *autoresp_title1=getarg("TITLE1");
const char    *autoresp_title2=getarg("TITLE2");
const char    *autoresp_text1=getarg("TEXT1");
const char    *autoresp_text2=getarg("TEXT2");

       if ( *cgi("do.newautoresp"))
       {
              const char *name=cgi("newname");
              char *p;
              FILE *fp;

              p=folder_toutf7(name);

              if (!p || maildir_autoresponse_validate(NULL, p))
              {
                     free(p);
                     printf("%s", getarg("BADNAME"));
                     return;
              }

              if ((fp=maildir_autoresponse_open(NULL, p)) != NULL)
              {
                     free(p);
                     fclose(fp);
                     printf("%s", getarg("EEXIST"));
                     return;
              }

              printf("%s%s%s\n", autoresp_title1, name, autoresp_title2);
              printf("<input type=\"hidden\" name=\"autoresponse\" value=\"");
              output_attrencoded(p);
              printf("\" />\n");
              free(p);

              printf("%s%s\n", autoresp_text1, autoresp_text2);
              printf("%s<input type=\"file\" size=\"20\" name=\"uploadfile\" /><br />",
                     getarg("UPLOAD"));
              printf("<input type=\"submit\" name=\"do.autorespcreate\""
                     " value=\"%s\" />", getarg("SAVE"));
              return;
       }

       if ( *cgi("do.autorespedit"))
       {
              const char *autorespname=cgi("autoresponse_choose");
              FILE *fp;
              char *s=folder_fromutf7(autorespname);
              const char *pp;

              if (!s)
              {
                     printf(getarg("ERROR"), strerror(errno));
                     return;
              }

              pp=cgi("replytext");

              if ((fp=maildir_autoresponse_open(NULL, autorespname)) == NULL
                  && !*pp)
              {
                     free(s);
                     return;
              }

              printf("%s%s%s\n", autoresp_title1, s, autoresp_title2);

              if (fp && read_headers(fp))
              {
                     fclose(fp);
                     free(s);
                     return;
              }

              printf("<input type=\"hidden\" name=\"autoresponse\" value=\"");
              output_attrencoded(autorespname);
              printf("\" />\n");
              free(s);

              printf("%s", autoresp_text1);

              if (pp && *pp)
                     output_attrencoded(pp);
              else
              {
                     struct show_textarea_info info;
                     libmail_u_convert_handle_t h;

                     show_textarea_init(&info, 0);

                     h=libmail_u_convert_init("utf-8",
                                           sqwebmail_content_charset,
                                           show_autoresponse_trampoline,
                                           &info);

                     if (h)
                     {
                            size_t i;
                            char buf[BUFSIZ];

                            while ((i=fread(buf, 1, sizeof(buf), fp)) > 0)
                            {
                                   libmail_u_convert(h, buf, i);
                            }
                            libmail_u_convert_deinit(h, NULL);
                     }
              }

              if (fp)
                     fclose(fp);
              printf("%s\n", autoresp_text2);
              printf("%s<input type=\"file\" size=\"20\" name=\"uploadfile\" /><br />",
                     getarg("UPLOAD"));
              printf("<input type=\"submit\" name=\"do.autorespcreate\""
                     " value=\"%s\" />", getarg("SAVE"));
              return;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 223 of file autoresponse.c.

{
       if ( *cgi("do.autorespcreate"))
       {
              const char *autorespname=cgi("autoresponse");
              const char *autoresptxt=cgi("text");
              FILE *fp;
              size_t l;

              if ((fp=upload_attachment(autorespname)) == NULL)
              {
                     struct wrap_info uw;

                     if ((fp=maildir_autoresponse_create(NULL,
                                                     autorespname))
                         == NULL)
                     {
                            printf(getarg("SAVEFAILED"), strerror(errno));
                            return;
                     }

                     l=strlen(autoresptxt);
                     while (l && (autoresptxt[l-1] == '\r' ||
                                 autoresptxt[l-1] == '\n'))
                            --l;

                     fprintf(fp, "Content-Type: text/plain");
                     fprintf(fp, "; format=flowed; delsp=yes"
                            "; charset=\"utf-8\"\n");
                     fprintf(fp, "Content-Transfer-Encoding: 8bit\n\n");

                     wrap_text_init(&uw, "utf-8", save_autoresponse, &fp);
                     wrap_text(&uw, autoresptxt, l);
              }

              if (fflush(fp) || ferror(fp))
              {
                     fclose(fp);
                     printf(getarg("SAVEFAILED"), strerror(errno));
                     return;
              }
              if (maildir_autoresponse_create_finish(NULL, autorespname, fp))
              {
                     if (errno == ENOSPC)
                     {
                            cgi_put("do.autorespedit", "1");
                            cgi_put("autoresponse_choose", autorespname);
                            cgi_put("replytext", cgi("text"));
                            printf(getarg("QUOTA"), strerror(errno));
                     }
                     else
                            printf(getarg("SAVEFAILED"), strerror(errno));
              }
              return;
       }

       if ( *cgi("do.autorespdelete"))
       {
              const char *autorespname=cgi("autoresponse_choose");

              if (mailfilter_autoreplyused(autorespname))
              {
                     char *s=folder_fromutf7(autorespname);
                     printf(getarg("INUSE"), s ? s:"");
                     if (s)
                            free(s);
              }
              else
                     maildir_autoresponse_delete(NULL, autorespname);
              return;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void autoresponselist ( )

Definition at line 552 of file autoresponse.c.

{
       char **list=maildir_autoresponse_list(NULL); /* I'm sorry... */
       size_t i;

       if (!list)
       {
              printf(getarg("ERROR"), strerror(errno));
              return;
       }

       for (i=0; list[i]; i++)
              ;

       qsort(list, i, sizeof(list[0]), &comp_autorespname);

       for (i=0; list[i]; i++)
       {
              char *s;

              printf("<option value=\"");
              output_attrencoded(list[i]);
              printf("\">");

              s=folder_fromutf7(list[i]);
              output_attrencoded(s);
              printf("</option>");
              free(s);
       }

       maildir_autoresponse_list_free(list);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void autoresponsepick ( )

Definition at line 585 of file autoresponse.c.

{
       char **list=maildir_autoresponse_list(NULL);
       size_t i;
       const char *choice=cgi("autoresponse_choose");

       if (!list)
       {
              printf(getarg("ERROR"), strerror(errno));
              return;
       }

       for (i=0; list[i]; i++)
              ;

       qsort(list, i, sizeof(list[0]), &comp_autorespname);

       for (i=0; list[i]; i++)
       {
              char *s;

              printf("<option%s value=\"",
                     strcmp(choice, list[i]) ? "":" selected='selected'");
              output_attrencoded(list[i]);
              printf("\">");

              s=folder_fromutf7(list[i]);
              output_attrencoded(s);
              printf("</option>");
              free(s);
       }

       maildir_autoresponse_list_free(list);
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* calc_mime_type ( const char *  filename)

Definition at line 569 of file attachments.c.

{
static const char mimetypes[]=MIMETYPES;
const char    *p;
char *q;
const char *r;
char *s;

       p=mimetypes;
       if (!p)       enomem();
       while (*p)
       {
              if (*p == ':')
              {
                     ++p;
                     continue;
              }
              q=strdup(p);
              if (!q)       enomem();
              if ((s=strchr(q, ':')) != NULL)    *s='\0';
              if ((r=search_mime_type(q, filename)) != 0)
              {
                     free(q);
                     return (r);
              }
              free(q);
              while (*p && *p != ':')
                     p++;
       }
       return ("auto");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void charset_warning ( const char *  )

Here is the caller graph for this function:

static int comp_autorespname ( const void *  a,
const void *  b 
) [static]

Definition at line 537 of file autoresponse.c.

{
       const char *ca=*(const char **)a;
       const char *cb=*(const char **)b;

       char *sa=folder_fromutf7(ca);
       char *sb=folder_fromutf7(cb);

       int i=sa && sb ? strcoll(sa, sb):0;

       free(sa);
       free(sb);
       return (i);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void end_upload ( void *  vp) [static]

Definition at line 370 of file autoresponse.c.

{
       struct upload_attach_info *uai=(struct upload_attach_info *)vp;
       const char *mimetype;
       char *argvec[10];
       int n;
       pid_t pid1, pid2;
       int waitstat;
       FILE *afp;

       if (fflush(uai->fp) || ferror(uai->fp)
           || fseek(uai->fp, 0L, SEEK_SET) < 0)
       {
              fclose(uai->fp);
              enomem();
       }

       mimetype=calc_mime_type(uai->filename);

       if (strcasecmp(mimetype, "message/rfc822") == 0)
       {
              /* Magic */

              afp=maildir_autoresponse_create(NULL, uai->autorespname);
              if (!afp)
              {
                     fclose(uai->fp);
                     enomem();
              }

              if (upload_messagerfc822(uai->fp, afp) ||
                  fflush(afp) || ferror(afp))
              {
                     fclose(uai->fp);
                     fclose(afp);
                     enomem();
              }
              fclose(uai->fp);
              uai->fp=afp;
              return;
       }
       argvec[0]="makemime";
       argvec[1]="-c";
       argvec[2]=(char *)mimetype;

       n=3;
       if (strncasecmp(argvec[2], "text/", 5) == 0 ||
           strcasecmp(argvec[2], "auto") == 0)
       {
              argvec[3]="-C";
              argvec[4]=(char *)sqwebmail_content_charset;
              n=5;
       }

       argvec[n++]="-";
       argvec[n]=0;

       afp=maildir_autoresponse_create(NULL, uai->autorespname);
       if (!afp)
       {
              fclose(uai->fp);
              enomem();
       }

       signal(SIGCHLD, SIG_DFL);
       pid1=fork();

       if (pid1 < 0)
       {
              fclose(afp);
              fclose(uai->fp);
              enomem();
       }

       if (pid1 == 0)
       {
              dup2(fileno(uai->fp), 0);
              dup2(fileno(afp), 1);
              fclose(uai->fp);
              fclose(afp);
              execv(MAKEMIME, argvec);
              fprintf(stderr,
                     "CRIT: exec %s: %s\n", MAKEMIME, strerror(errno));
              exit(1);
       }

       for (;;)
       {
              pid2=wait(&waitstat);

              if (pid2 == pid1)
              {
                     waitstat= WIFEXITED(waitstat) ? WEXITSTATUS(waitstat)
                            : 1;
                     break;
              }

              if (pid2 == -1)
              {
                     waitstat=1;
                     break;
              }
       }

       if (waitstat)
       {
              fclose(afp);
              fclose(uai->fp);
              enomem();
       }

       fclose(uai->fp);
       uai->fp=afp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void output_attrencoded ( const char *  )

Definition at line 259 of file sqwebmail.c.

{
       output_attrencoded_fp(p, stdout);
}
static int read_headers ( FILE *  fp) [static]

Definition at line 187 of file autoresponse.c.

{
       struct rfc2045 *rfc2045p=rfc2045_alloc();
       static const char mv[]="Mime-Version: 1.0\n";
       char buf[BUFSIZ];
       char *s;
       const char *content_type, *content_transfer_encoding, *charset;

       rfc2045_parse(rfc2045p, mv, sizeof(mv)-1);

       while ((s=fgets(buf, sizeof(buf), fp)) != NULL)
       {
              rfc2045_parse(rfc2045p, s, strlen(s));
              if (strcmp(s, "\n") == 0 || strcmp(s, "\r\n") == 0)
                     break;
       }
       rfc2045_parse_partial(rfc2045p);

       rfc2045_mimeinfo(rfc2045p, &content_type,
                      &content_transfer_encoding,
                      &charset);

       if (strcmp(content_type, "text/plain") ||
           !rfc2045_isflowed(rfc2045p))
       {
              printf(getarg("ATT"), content_type);
              rfc2045_free(rfc2045p);
              return (-1);
       }

       rfc2045_free(rfc2045p);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void save_autoresponse ( const char *  p,
size_t  l,
void *  vp 
) [static]

Definition at line 45 of file autoresponse.c.

{
       FILE *fp=*(FILE **)vp;

       if (fp)
              if (fwrite(p, l, 1, fp) != 1)
                     ; /* ignore */
}

Here is the caller graph for this function:

static int show_autoresponse_trampoline ( const char *  ptr,
size_t  cnt,
void *  arg 
) [static]

Definition at line 56 of file autoresponse.c.

{
       show_textarea((struct show_textarea_info *)arg, ptr, cnt);
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int start_upload ( const char *  name,
const char *  filename,
void *  vp 
) [static]

Definition at line 325 of file autoresponse.c.

{
       struct upload_attach_info *uai=(struct upload_attach_info *)vp;
       const char *p;

       p=strrchr(filename, '/');
       if (p) filename=p+1;

       p=strrchr(filename, '\\');
       if (p) filename=p+1;

       if (*filename)
       {
              uai->filename=filename;
       }
       else
       {
              p=strrchr(name, '/');
              if (p) name=p+1;

              p=strrchr(name, '\\');
              if (p) name=p+1;
              uai->filename=p;
       }

       uai->fp=tmpfile();
       if (!uai->fp)
              enomem();
       return (0);
}

Here is the caller graph for this function:

static int upload ( const char *  c,
size_t  n,
void *  vp 
) [static]

Definition at line 356 of file autoresponse.c.

{
       struct upload_attach_info *uai=(struct upload_attach_info *)vp;

       if (fwrite(c, n, 1, uai->fp) != 1)
       {
              fclose(uai->fp);
              enomem();
       }
       return (0);
}

Here is the caller graph for this function:

static FILE * upload_attachment ( const char *  autorespname) [static]

Definition at line 307 of file autoresponse.c.

{
       struct upload_attach_info uai;

       uai.fp=NULL;
       uai.autorespname=autorespname;

       if (cgi_getfiles( &start_upload, &upload, &end_upload, 1, &uai ))
       {
              if (uai.fp)
                     fclose(uai.fp);

              return (NULL);
       }

       return (uai.fp);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int upload_messagerfc822 ( FILE *  i,
FILE *  o 
) [static]

Definition at line 492 of file autoresponse.c.

{
       char buf[BUFSIZ];
       int skip_hdr;
       int c;
       const char *pp;

       skip_hdr=0;

       for (;;)
       {
              if (fgets(buf, sizeof(buf), i) == NULL)
              {
                     fprintf(o, "\n");
                     return (0);
              }

              if (strcmp(buf, "\n") == 0 || strcmp(buf, "\r\n") == 0)
              {
                     fprintf(o, "\n");
                     break;
              }

              if (!isspace((int)(unsigned char)*buf))
                     skip_hdr=strncasecmp(buf, "content-", 8) != 0;

              if (skip_hdr)
                     continue;

              for (pp=buf; *pp; pp++)
                     if (*pp != '\r')
                            if (putc((int)(unsigned char)*pp, o)
                                == EOF)
                                   return (-1);
       }

       while ((c=getc(i)) != EOF)
              if (c != '\r')
                     if (putc(c, o) == EOF)
                            return (-1);
       return (0);
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 39 of file gpg.c.