Back to index

courier  0.68.2
Defines | Functions | Variables
attachments.c File Reference
#include "config.h"
#include "sqwebmail.h"
#include "cgi/cgi.h"
#include "sqconfig.h"
#include "maildir.h"
#include "folder.h"
#include "pref.h"
#include "rfc822/rfc822.h"
#include "rfc822/rfc2047.h"
#include "rfc2045/rfc2045.h"
#include "token.h"
#include "newmsg.h"
#include "gpg.h"
#include "gpglib/gpglib.h"
#include "courierauth.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "maildir/maildirmisc.h"
#include "htmllibdir.h"
#include "unicode/unicode.h"

Go to the source code of this file.

Defines

#define WEXITSTATUS(stat_val)   ((unsigned)(stat_val) >> 8)
#define WIFEXITED(stat_val)   (((stat_val) & 255) == 0)
#define HASTEXTPLAIN(q)   (rfc2045_searchcontenttype((q), "text/plain") != NULL)

Functions

char * newmsg_alladdrs (FILE *)
void newmsg_copy_content_headers (FILE *fp)
char * alloc_filename (const char *, const char *, const char *)
const char * showsize (unsigned long)
void output_attrencoded (const char *)
void newmsg_hiddenheader (const char *, const char *)
void output_scriptptrget ()
void output_urlencoded (const char *)
void sendmsg_done ()
char * multipart_boundary_create ()
int multipart_boundary_checkf (const char *, FILE *)
int ishttps ()
void newmsg_create_multipart (int, const char *, const char *)
void newmsg_copy_nonmime_headers (FILE *)
static void attachment_showname (const char *)
static off_t max_attach ()
void attachments_head (const char *folder, const char *pos, const char *draft)
void attachments_opts (const char *draft)
static void attachment_open (const char *draft, FILE **fp, int *fd2, struct rfc2045 **rfcp)
static int messagecopy (FILE *fp, off_t start, off_t end)
static int deleting_all_attachments (struct rfc2045 *p)
static int del_final_attachment (FILE *fp, struct rfc2045 *rfcp)
static int del_some_attachments (FILE *fp, struct rfc2045 *rfcp)
void attach_delete (const char *draft)
static int upload_start (const char *name, const char *filename, void *dummy)
static int upload_file (const char *ptr, size_t cnt, void *voidptr)
static void upload_end (void *dummy)
static const char * search_mime_type (const char *mimetype, const char *filename)
const char * calc_mime_type (const char *filename)
static int getkey (const char *keyname, int issecret)
static int cnt_filename (const char *param, const char *value, void *void_arg)
static int save_filename (const char *param, const char *value, void *void_arg)
int attach_upload (const char *draft, const char *attpubkey, const char *attprivkey)
void doattach (const char *folder, const char *draft)

Variables

int newdraftfd
const char * sqwebmail_content_charset
const char * sqwebmail_content_language
static int isbinary
static int attachfd
static const char * cgi_attachname
static const char * cgi_attachfilename

Define Documentation

#define HASTEXTPLAIN (   q)    (rfc2045_searchcontenttype((q), "text/plain") != NULL)

Definition at line 74 of file attachments.c.

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

Definition at line 39 of file attachments.c.

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

Definition at line 42 of file attachments.c.


Function Documentation

char* alloc_filename ( const char *  ,
const char *  ,
const char *   
)

Definition at line 245 of file maildir.c.

{
char   *p;

       if (!dir1)    dir1="";
       if (!dir2)    dir2="";

       p=malloc(strlen(dir1)+strlen(dir2)+strlen(filename)+3);

       if (!p)       enomem();

       strcpy(p, dir1);
       if (*dir2)
       {
              if (*p)       strcat(p, "/");
              strcat(p, dir2);
       }
       if (*filename)
       {
              if (*p)       strcat(p, "/");
              strcat(p, filename);
       }

       return (p);
}
void attach_delete ( const char *  draft)

Definition at line 446 of file attachments.c.

{
FILE   *fp;
int    fd2;
struct rfc2045 *rfcp;
char   *draftfilename;
int    isok=1;
struct stat   stat_buf;

       attachment_open(draft, &fp, &fd2, &rfcp);
       if (!rfcp->firstpart)
       {
              rfc2045_free(rfcp);
              fclose(fp);
              return;       /* No attachments to delete */
       }

       if (fstat(fileno(fp), &stat_buf))
       {
              fclose(fp);
              enomem();
       }

       newdraftfd=maildir_recreatemsg(INBOX "." DRAFTS, draft, &draftfilename);
       if (newdraftfd < 0)
       {
              fclose(fp);
              enomem();
       }

       if (deleting_all_attachments(rfcp))
       {
              /* Deleting all attachments */

              if (del_final_attachment(fp, rfcp))       isok=0;
       }
       else
       {
              if (del_some_attachments(fp, rfcp))       isok=0;
       }
       fclose(fp);
       rfc2045_free(rfcp);

       if ( maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, isok,
              stat_buf.st_size))
       {
              free(draftfilename);
              enomem();
       }
       free(draftfilename);
       maildir_remcache(INBOX "." DRAFTS);       /* Cache file invalid now */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int attach_upload ( const char *  draft,
const char *  attpubkey,
const char *  attprivkey 
)

Definition at line 655 of file attachments.c.

{
       char   *attachfilename;
       char   *draftfilename;
       FILE   *draftfp;
       char   *boundary;
       FILE   *tempfp;
       struct rfc2045 *rfcp, *q;
       const char *content_type;
       const char *content_transfer_encoding;
       const char *charset;
       off_t  start_pos, end_pos, start_body;
       int    n;
       char   buf[BUFSIZ];
       int    pipefd[2];
       struct stat   stat_buf, attach_stat_buf;
       off_t  dummy;
       int    fd2;
       char   *filenamemime;
       char *argvec[20];
       char   *filenamebuf;
       pid_t pid1, pid2;
       int waitstat;

       /* Open the file containing the draft message */

       draftfilename=maildir_find(INBOX "." DRAFTS, draft);
       if (!draftfilename)  return (0);

       fd2=maildir_safeopen(draftfilename, O_RDONLY, 0);

       draftfp=0;
       if (fd2 >= 0)
       {
              draftfp=fdopen(fd2, "r");
              if (draftfp == NULL)
                     close(fd2);
       }

       if (draftfp == 0)
              enomem();

       free(draftfilename);
       if (fstat(fileno(draftfp), &stat_buf))
       {
              fclose(draftfp);
              enomem();
       }

       /* Create a temporary file in tmp where we'll temporarily store the
       ** attachment
       */

       attachfd=maildir_createmsg(INBOX "." DRAFTS, "temp", &attachfilename);
       if (attachfd < 0)
       {
              fclose(draftfp);
              enomem();
       }

       if ((
            attpubkey ? getkey(attpubkey, 0):
            attprivkey ? getkey(attprivkey, 1):
            cgi_getfiles( &upload_start, &upload_file, &upload_end, 1, NULL))
              || maildir_writemsg_flush(attachfd))
       {
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              free(attachfilename);
              fclose(draftfp);
              close(attachfd);
              return (0);
       }

       if (fstat(attachfd, &attach_stat_buf) ||
           attach_stat_buf.st_size + stat_buf.st_size > max_attach())
       {
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              maildir_deletenewmsg(attachfd, INBOX "." DRAFTS, attachfilename);
              free(attachfilename);
              fclose(draftfp);
              close(attachfd);
              return (-2);
       }
              

       /* Calculate new MIME content boundary */

       boundary=0;
       tempfp=0;

       n=dup(attachfd);

       if (n < 0)
       {
              fclose(draftfp);
              enomem();
       }
       tempfp=fdopen(n, "r");
       if (tempfp == 0)
       {
              fclose(draftfp);
              enomem();
       }

       do
       {
              if (boundary) free(boundary);
              boundary=multipart_boundary_create();
       } while ( multipart_boundary_checkf(boundary, draftfp) ||
                multipart_boundary_checkf(boundary, tempfp));

       if (tempfp)   fclose(tempfp);

       /* Parse existing draft for its MIME structure */

       rfcp=rfc2045_fromfp(draftfp);

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

       /* Create a new version of the draft message */

       newdraftfd=maildir_recreatemsg(INBOX "." DRAFTS, draft, &draftfilename);
       if (newdraftfd < 0)
       {
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              fclose(draftfp);
              close(attachfd);
              enomem();
       }

       if (fseek(draftfp, 0L, SEEK_SET) < 0)
       {
              maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, 0, 0);
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              fclose(draftfp);
              close(attachfd);
              enomem();
       }

       newmsg_copy_nonmime_headers(draftfp);

       /* Create a multipart message, 1st attachment is the existing
       ** contents.
       */

       newmsg_create_multipart(newdraftfd, charset, boundary);
       maildir_writemsgstr(newdraftfd, "--");
       maildir_writemsgstr(newdraftfd, boundary);
       maildir_writemsgstr(newdraftfd, "\n");

       if (rfcp == NULL || strcmp(content_type, "multipart/mixed"))
       {
              int rc;

              /*
              ** The current draft does not have attachments.  Take its
              ** sole contents, and write it as a text/plain attachment.
              */

              if (fseek(draftfp, 0L, SEEK_SET) < 0)
                     rc = -1;
              else
              {
                     newmsg_copy_content_headers(draftfp);
                     maildir_writemsgstr(newdraftfd, "\n");
                     rfc2045_mimepos(rfcp, &start_pos, &end_pos,
                                   &start_body,
                                   &dummy, &dummy);
                     rc=messagecopy(draftfp, start_body, end_pos);
              }

              if (rc)
              {
                     maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename,
                            0, 0);
                     maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename,
                            0, 0);
                     fclose(draftfp);
                     close(newdraftfd);
                     close(attachfd);
                     enomem();
              }

              maildir_writemsgstr(newdraftfd, "\n--");
              maildir_writemsgstr(newdraftfd, boundary);
              maildir_writemsgstr(newdraftfd, "\n");
       }
       else
       {
              /* If the current draft already has MIME attachments,
              ** just copy them over to the new draft message.
              */

              for (q=rfcp->firstpart; q; q=q->next)
              {
                     if (q->isdummy)      continue;
                     rfc2045_mimepos(q, &start_pos, &end_pos, &start_body,
                                   &dummy, &dummy);
                     if (messagecopy(draftfp, start_pos, end_pos))
                     {
                            maildir_closemsg(newdraftfd, INBOX "." DRAFTS,
                                   draftfilename, 0, 0);
                            maildir_closemsg(attachfd, INBOX "." DRAFTS,
                                   attachfilename, 0, 0);
                            fclose(draftfp);
                            close(newdraftfd);
                            close(attachfd);
                            enomem();
                     }
                     maildir_writemsgstr(newdraftfd, "\n--");
                     maildir_writemsgstr(newdraftfd, boundary);
                     maildir_writemsgstr(newdraftfd, "\n");
              }
       }

       {
              const char *cp=strrchr(cgi_attachfilename, '/');
              int len;
              static const char fnStr[]="filename";

              if (cp)
                     ++cp;
              else
                     cp=cgi_attachfilename;

              len=1;
              rfc2231_attrCreate(fnStr, cp,
                               sqwebmail_content_charset,
                               sqwebmail_content_language,
                               &cnt_filename, &len);

              filenamemime=malloc(len);

              if (filenamemime)
              {
                     *filenamemime=0;
                     rfc2231_attrCreate(fnStr, cp,
                                      sqwebmail_content_charset,
                                      sqwebmail_content_language,
                                      save_filename, filenamemime);
              }
       }

       argvec[0]="makemime";
       argvec[1]="-c";

       if (attpubkey || attprivkey)
       {
              argvec[2]="application/pgp-keys";
              argvec[3]="-N";
              argvec[4]="pgpkeys.txt";
              argvec[5]="-a";
              argvec[6]="Content-Disposition: attachment; filename=\"pgpkeys.txt\"";
              n=7;
              filenamebuf=0;
       }
       else
       {
              const char *pp;

              argvec[2]=(char *)calc_mime_type(cgi_attachfilename);
              argvec[3]="-N";
              argvec[4]=cgi_attachfilename ?
                     (char *)cgi_attachfilename:"filename.dat";
              n=5;

              pp=*cgi("attach_inline") ?
                     "Content-Disposition: inline":
                     "Content-Disposition: attachment";

              filenamebuf=malloc(strlen(pp)+strlen(filenamemime ?
                                               filenamemime:"") + 15);

              if (filenamebuf)
              {
                     strcpy(filenamebuf, pp);
                     strcat(filenamebuf, filenamemime ? filenamemime:"");

                     argvec[n++]="-a";
                     argvec[n++]=filenamebuf;
              }
       }

       argvec[n++]="-C";
       argvec[n++]=(char *)sqwebmail_content_charset;

       signal(SIGCHLD, SIG_DFL);

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

       if (pipe(pipefd) < 0)
       {
              if (filenamemime)
                     free(filenamemime);
              if (filenamebuf)
                     free(filenamebuf);
              maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, 0, 0);
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              fclose(draftfp);
              close(newdraftfd);
              close(attachfd);
              enomem();
       }

       if (lseek(attachfd, 0L, SEEK_SET) < 0 || (pid1=fork()) < 0)
       {
              close(pipefd[0]);
              close(pipefd[1]);
              if (filenamemime)
                     free(filenamemime);
              if (filenamebuf)
                     free(filenamebuf);
              maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, 0, 0);
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              fclose(draftfp);
              close(newdraftfd);
              close(attachfd);
              enomem();
              return (0);
       }

       if (pid1 == 0)
       {
              dup2(attachfd, 0);
              dup2(pipefd[1], 1);
              close(attachfd);
              close(newdraftfd);
              close(pipefd[0]);
              close(pipefd[1]);
              execv(MAKEMIME, argvec);
              fprintf(stderr,
                     "CRIT: exec %s: %s\n", MAKEMIME, strerror(errno));
              exit(1);
       }

       if (filenamemime)
              free(filenamemime);
       if (filenamebuf)
              free(filenamebuf);

       close (pipefd[1]);


       while ((n=read(pipefd[0], buf, sizeof(buf))) > 0)
       {
              maildir_writemsg(newdraftfd, buf, n);
       }
       close(pipefd[0]);

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

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

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

       if (waitstat > 0 || n < 0)
       {
              maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, 0, 0);
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              fclose(draftfp);
              close(newdraftfd);
              maildir_deletenewmsg(attachfd, INBOX "." DRAFTS, attachfilename);
              close(attachfd);
              return (-3);
       }

       maildir_writemsgstr(newdraftfd, "\n--");
       maildir_writemsgstr(newdraftfd, boundary);
       maildir_writemsgstr(newdraftfd, "--\n");

       /* Finish new draft message, let it replace the current one */

       if (maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, 1,
              stat_buf.st_size))
       {
              maildir_closemsg(attachfd, INBOX "." DRAFTS, attachfilename, 0, 0);
              free(draftfilename);
              maildir_deletenewmsg(attachfd, INBOX "." DRAFTS, attachfilename);
              free(attachfilename);
              rfc2045_free(rfcp);
              fclose(draftfp);
              close(attachfd);
              return (-1);
       }
       free(draftfilename);

       fclose(draftfp);

       /* Remove and delete temp attachment file */

       maildir_deletenewmsg(attachfd, INBOX "." DRAFTS, attachfilename);
       free(attachfilename);
       rfc2045_free(rfcp);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void attachment_open ( const char *  draft,
FILE **  fp,
int *  fd2,
struct rfc2045 **  rfcp 
) [static]

Definition at line 294 of file attachments.c.

{
char   *oldname=maildir_find(INBOX "." DRAFTS, draft);

       if (!oldname) enomem();

       *fd2=maildir_safeopen(oldname, O_RDONLY, 0);

       *fp=0;
       if (*fd2 >= 0)
       {
              *fp=fdopen(*fd2, "r");
              if (*fp == NULL)
                     close(*fd2);
       }

       if (*fp == NULL)     enomem();
       *rfcp=rfc2045_fromfp( *fp );
       if (!*rfcp)   enomem();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void attachment_showname ( const char *  name) [static]

Definition at line 288 of file attachments.c.

{
       if (!name || !*name) name="[attachment]"; /* Eh??? */
       output_attrencoded(name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void attachments_head ( const char *  folder,
const char *  pos,
const char *  draft 
)

Definition at line 92 of file attachments.c.

{
char *filename;
FILE   *fp;
struct rfc2045 *rfcp;
int    cnt=0;
struct rfc2045 *q;
int    foundtextplain=0;
const char    *noattach_lab=getarg("NOATTACH");
const char    *quotaerr=getarg("QUOTAERR");
const char    *limiterr=getarg("LIMITERR");
off_t  dummy;
int    fd2;

       CHECKFILENAME(draft);
       filename=maildir_find(INBOX "." DRAFTS, draft);
       if (!filename)       return;

       fd2=maildir_safeopen(filename, O_RDONLY, 0);

       fp=0;
       if (fd2 >= 0)
       {
              fp=fdopen(fd2, "r");
              if (fp == NULL)
                     close(fd2);
       }

       if (fp == NULL)
       {
              free(filename);
              return;
       }

       rfcp=rfc2045_fromfp(fp);
       fclose(fp);
       free(filename);

       if (strcmp(cgi("error"), "quota") == 0)
       {
              printf("%s", quotaerr);
       }

       if (strcmp(cgi("error"), "limits") == 0)
       {
              printf(limiterr, (unsigned long)(max_attach() / (1024 * 1024)));
       }

       if (strcmp(cgi("error"), "makemime") == 0)
       {
              printf(getarg("MAKEMIMEERR"), MAKEMIME);
       }
       newmsg_hiddenheader("pos", pos);
       newmsg_hiddenheader("draft", draft);
       tokennew();
       printf("<table width=\"100%%\" border=\"0\">");

       if (rfcp)
       {
              const char *content_type;
              const char *content_transfer_encoding;
              const char *charset;

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

              if (content_type &&
                  strcmp(content_type, "multipart/alternative") == 0)
                     rfcp=NULL;

              /* No attachments here */
       }

       for (q=rfcp ? rfcp->firstpart:0; q; q=q->next)
       {
       const char *content_type;
       const char *content_transfer_encoding;
       const char *charset;
       const char *name;
       const char *cn;
       char *content_name;

       off_t start_pos, end_pos, start_body;

              if (q->isdummy)      continue;

              rfc2045_mimeinfo(q, &content_type,
                     &content_transfer_encoding, &charset);
              if (!foundtextplain && HASTEXTPLAIN(q))
              {
                     foundtextplain=1;
                     continue;
              }
              rfc2045_mimepos(q, &start_pos, &end_pos, &start_body,
                     &dummy, &dummy);

              ++cnt;
              printf("<tr><td align=\"left\"><input type=\"checkbox\" name=\"del%d\" id=\"del%d\" />&nbsp;",
                     cnt, cnt);

              if (rfc2231_udecodeType(q, "name", sqwebmail_content_charset,
                                   &content_name) < 0 ||
                  rfc2231_udecodeDisposition(q, "filename",
                                          sqwebmail_content_charset,
                                          &content_name) < 0)
                     content_name=NULL;

              if (!content_name &&
                  ((cn=rfc2045_getattr(q->content_type_attr, "name")) ||
                   (cn=rfc2045_getattr(q->content_disposition_attr,
                                    "filename"))))
              {
                     content_name =
                            rfc822_display_hdrvalue_tobuf("subject",
                                                       cn,
                                                       sqwebmail_content_charset,
                                                       NULL,
                                                       NULL);
              }

              if ((!content_name || !*content_name) &&
                  strcmp(content_type, "application/pgp-keys") == 0)
                     name=getarg("KEYDESCR");
              else
              {
                     name=content_name;
              }

              attachment_showname(name);
              if (content_name)
                     free(content_name);
              printf("</td><td align=\"left\">&nbsp;&nbsp;<label for=\"del%d\">", cnt);
              output_attrencoded( content_type );
              printf("</label></td><td align=\"right\">%s<br /></td></tr>",
                     showsize(end_pos - start_body));
       }

       if (cnt == 0)
              printf("<tr><td align=\"center\">%s<br /></td></tr>\n",
                     noattach_lab);
       printf("</table>\n");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void attachments_opts ( const char *  draft)

Definition at line 235 of file attachments.c.

{
       char *filename;
       FILE *fp;

       CHECKFILENAME(draft);

       filename=maildir_find(INBOX "." DRAFTS, draft);
       if (!filename)
              return;
       fp=fopen(filename, "r");
       free(filename);
       if (!fp)
              return;

       printf("<label><input type=\"checkbox\" name=\"fcc\"%s />%s</label><br />",
              pref_noarchive ? "":" checked=\"checked\"",
              getarg("PRESERVELAB"));
       if (auth_getoptionenvint("wbnodsn") == 0)
              printf("<label><input type=\"checkbox\" name=\"dsn\" />%s</label><br />",
                     getarg("DSN"));

       if (libmail_gpg_has_gpg(GPGDIR) == 0)
       {
              char *all_addr;

              printf("<label><input type=\"checkbox\" "
                     "name=\"sign\" />%s</label><select name=\"signkey\">",
                     getarg("SIGNLAB"));
              gpgselectkey();
              printf("</select><br />\n");

              all_addr=newmsg_alladdrs(fp);

              printf("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"
                     "<tr valign=\"middle\"><td><input type=\"checkbox\""
                     " name=\"encrypt\" id=\"encrypt\" /></td><td><label for=\"encrypt\">%s</label></td>"
                     "<td><select size=\"4\" multiple=\"multiple\" name=\"encryptkey\">",
                     getarg("ENCRYPTLAB"));
              gpgencryptkeys(all_addr);
              printf("</select></td></tr>\n");

              if (ishttps())
                     printf("<tr valign=\"middle\"><td>&nbsp;</td><td>%s</td><td><input type=\"password\" name=\"passphrase\" /></td></tr>\n",
                            getarg("PASSPHRASE"));

              printf("</table><br />\n");
              if (all_addr)
                     free(all_addr);
       }
       fclose(fp);
}

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:

static int cnt_filename ( const char *  param,
const char *  value,
void *  void_arg 
) [static]

Definition at line 638 of file attachments.c.

{
       *(int *)void_arg += strlen(param)+strlen(value)+5;
       return 0;
}

Here is the caller graph for this function:

static int del_final_attachment ( FILE *  fp,
struct rfc2045 rfcp 
) [static]

Definition at line 368 of file attachments.c.

{
struct rfc2045 *q;
const char *content_type;
const char *content_transfer_encoding;
const char *charset;
off_t start_pos, end_pos, start_body;
off_t dummy;

       for (q=rfcp->firstpart; q; q=q->next)
       {
              if (q->isdummy)      continue;
              rfc2045_mimeinfo(q, &content_type,
                     &content_transfer_encoding, &charset);
              if (HASTEXTPLAIN(q))
                     break;
       }
       if (!q)       return (-1);

       if (fseek(fp, 0L, SEEK_SET) == -1) return (-1);
       newmsg_copy_nonmime_headers(fp);
       maildir_writemsgstr(newdraftfd, "mime-version: 1.0\n");

       rfc2045_mimepos(q, &start_pos, &end_pos, &start_body, &dummy, &dummy);
       return (messagecopy(fp, start_pos, end_pos));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int del_some_attachments ( FILE *  fp,
struct rfc2045 rfcp 
) [static]

Definition at line 395 of file attachments.c.

{
struct rfc2045 *q;
const char *content_type;
const char *content_transfer_encoding;
const char *charset;
int    foundtextplain;
int    cnt;
const char *boundary=rfc2045_boundary(rfcp);
off_t  start_pos, end_pos, start_body;
off_t  dummy;

       rfc2045_mimepos(rfcp, &start_pos, &end_pos, &start_body, &dummy,
              &dummy);
       if (messagecopy(fp, 0, start_body))       return (-1);

       foundtextplain=0;
       cnt=0;
       for (q=rfcp->firstpart; q; q=q->next)
       {
              rfc2045_mimeinfo(q, &content_type,
                     &content_transfer_encoding, &charset);
              if (q->isdummy)
                     ;
              else if (!foundtextplain && HASTEXTPLAIN(q))
                     foundtextplain=1;
              else
              {
              char   buf[MAXLONGSIZE+4];

                     sprintf(buf, "del%d", ++cnt);
                     if (*cgi(buf))       continue;     /* This one's gone */
              }

              if (!q->isdummy)
              {
                     maildir_writemsgstr(newdraftfd, "\n--");
                     maildir_writemsgstr(newdraftfd, boundary);
                     maildir_writemsgstr(newdraftfd, "\n");
              }
              rfc2045_mimepos(q, &start_pos, &end_pos, &start_body, &dummy,
                     &dummy);
              if (messagecopy(fp, start_pos, end_pos))
                     return (-1);
       }
       maildir_writemsgstr(newdraftfd, "\n--");
       maildir_writemsgstr(newdraftfd, boundary);
       maildir_writemsgstr(newdraftfd, "--\n");
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int deleting_all_attachments ( struct rfc2045 p) [static]

Definition at line 339 of file attachments.c.

{
struct rfc2045 *q;
const char *content_type;
const char *content_transfer_encoding;
const char *charset;
int    foundtextplain, cnt;
char   buf[MAXLONGSIZE+4];

       foundtextplain=0;
       cnt=0;
       for (q=p->firstpart; q; q=q->next)
       {
              rfc2045_mimeinfo(q, &content_type,
                     &content_transfer_encoding, &charset);
              if (q->isdummy)      continue;

              if (!foundtextplain && HASTEXTPLAIN(q))
              {
                     foundtextplain=1;
                     continue;
              }

              sprintf(buf, "del%d", ++cnt);
              if (*cgi(buf) == '\0')      return (0);
       }
       return (1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void doattach ( const char *  folder,
const char *  draft 
)

Definition at line 1067 of file attachments.c.

{
int    quotaflag=0;

       CHECKFILENAME(draft);
       if (*cgi("dodelete"))
       {
              if (!tokencheck())
              {
                     attach_delete(draft);
                     tokensave();
              }
       }
       else if (*cgi("upload"))
       {
              if (!tokencheck())
              {
                     quotaflag=attach_upload(draft, NULL, NULL);
                     tokensave();
              }
       }
       else if (*cgi("uppubkey") && libmail_gpg_has_gpg(GPGDIR) == 0)
       {
              if (!tokencheck())
              {
                     quotaflag=attach_upload(draft, cgi("pubkey"), NULL);
                     tokensave();
              }
       }
       else if (*cgi("upprivkey") && *cgi("really") &&
               libmail_gpg_has_gpg(GPGDIR) == 0)
       {
              if (!tokencheck())
              {
                     quotaflag=attach_upload(draft, NULL, cgi("privkey"));
                     tokensave();
              }
       }
       else if (*cgi("previewmsg"))
       {
              cgi_put("draft", draft);
              newmsg_do(folder);
              return;
       }
       else if (*cgi("sendmsg"))
       {
              cgi_put("draftmessage", draft);
              newmsg_do(folder);
              return;
       }
       else if (*cgi("savedraft"))
       {
              sendmsg_done();
              return;
       }

       if (quotaflag == -2)
        {
                http_redirect_argss(
                  "&form=attachments&pos=%s&draft=%s&error=limits",
                  cgi("pos"), draft);
        }
       else if (quotaflag == -3)
       {
                http_redirect_argss(
                  "&form=attachments&pos=%s&draft=%s&error=makemime",
                  cgi("pos"), draft);
       }
        else
        {
                http_redirect_argss(
                  (quotaflag ? "&form=attachments&pos=%s&draft=%s&error=quota":
                  "&form=attachments&pos=%s&draft=%s"), cgi("pos"),
                  draft);
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int getkey ( const char *  keyname,
int  issecret 
) [static]

Definition at line 601 of file attachments.c.

{
       int rc;

       if (!*keyname)
              return (1);
       upload_start("", "", NULL);

       rc=gpgexportkey(keyname, issecret, &upload_file, NULL);
       upload_end(NULL);
       return (rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ishttps ( )

Definition at line 494 of file sqwebmail.c.

{
       const char *p=getenv("HTTPS");

       return (p && strcasecmp(p, "on") == 0);
}

Here is the caller graph for this function:

static off_t max_attach ( ) [static]

Definition at line 78 of file attachments.c.

{
       off_t n=0;
       const char *p=getenv("SQWEBMAIL_MAXMSGSIZE");

       if (p)
              n=atol(p);

       if (n < MAXMSGSIZE)
              n=MAXMSGSIZE;
       return n;
}

Here is the caller graph for this function:

static int messagecopy ( FILE *  fp,
off_t  start,
off_t  end 
) [static]

Definition at line 318 of file attachments.c.

{
char   buf[512];
int    n;

       if (fseek(fp, start, SEEK_SET) == -1)     return (-1);
       while (start < end)
       {
              n=sizeof(buf);
              if (n > end - start)
                     n=end - start;
              n=fread(buf, 1, n, fp);
              if (n <= 0)   enomem();
              maildir_writemsg(newdraftfd, buf, n);
              start += n;
       }
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int multipart_boundary_checkf ( const char *  ,
FILE *   
)

Definition at line 1375 of file newmsg_create.c.

{
size_t boundarylen=strlen(boundary);
const char *line;

       if (fseek(f, 0L, SEEK_SET) == -1)
       {
              fclose(f);
              close(newdraftfd);
              enomem();
       }

       while ((line=maildir_readline(f)) != 0)
              if (line[0] == '-' && line[1] == '-' &&
                     strncasecmp(line+2, boundary, boundarylen) == 0)
                            return (-1);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1334 of file newmsg_create.c.

{
char   pidbuf[MAXLONGSIZE];
char   timebuf[MAXLONGSIZE];
time_t t;
char   cntbuf[MAXLONGSIZE];
static unsigned long cnt=0;
char   *p;

       sprintf(pidbuf, "%lu", (unsigned long)getpid());
       time(&t);
       sprintf(timebuf, "%lu", (unsigned long)t);
       sprintf(cntbuf, "%lu", cnt++);
       p=malloc(strlen(pidbuf)+strlen(timebuf) +strlen(cntbuf)+20);
       sprintf(p, "=_%s_%s_%s_000", cntbuf, pidbuf, timebuf);
       return (p);
}

Here is the caller graph for this function:

char* newmsg_alladdrs ( FILE *  )

Definition at line 361 of file newmsg.c.

{
       char   *headers=NULL;
       struct rfc822t *t;
       struct rfc822a *a;
       char *p, *q;
       int l, i;

       if (fp)
       {
              char *header, *value;

              rewind(fp);

              /* First, combine all the headers into one header. */

              while ((header=maildir_readheader(fp, &value, 1)) != 0)
              {
                     char *newh;

                     if (strcmp(header, "from") &&
                         strcmp(header, "to") &&
                         strcmp(header, "cc") &&
                         strcmp(header, "bcc"))
                            continue;

                     if (headers)
                     {
                            newh=realloc(headers, strlen(headers)
                                        +strlen(value)+2);
                            if (!newh)
                                   continue;
                            strcat(newh, ",");
                            headers=newh;
                     }
                     else
                     {
                            newh=malloc(strlen(value)+1);
                            if (!newh)
                                   continue;
                            *newh=0;
                            headers=newh;
                     }
                     strcat(headers, value);
              }

       }

       /* Now, parse the header, and extract the addresses */

       t=rfc822t_alloc_new(headers ? headers:"", NULL, NULL);
       a= t ? rfc822a_alloc(t):NULL;

       l=1;
       for (i=0; i < (a ? a->naddrs:0); i++)
       {
              p=rfc822_getaddr(a, i);
              if (p)
              {
                     ++l;
                     l +=strlen(p);
                     free(p);
              }
       }
       p=malloc(l);
       if (p)
              *p=0;

       for (i=0; i < (a ? a->naddrs:0); i++)
       {
              q=rfc822_getaddr(a, i);
              if (q)
              {
                     if (p)
                     {
                            strcat(strcat(p, q), "\n");
                     }
                     free(q);
              }
       }

       rfc822a_free(a);
       rfc822t_free(t);
       free(headers);
       return (p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void newmsg_copy_content_headers ( FILE *  fp)

Definition at line 266 of file newmsg_create.c.

{
char   *header, *value;
char   *q;

       while ((header=maildir_readheader(fp, &value, 1)) != NULL)
       {
              if (strncmp(header, "content-", 8)) continue;

              for (q=header; *q; q++)
              {
                     for (*q=toupper(*q); *q; q++)
                            if (*q == '-')       break;
                     if (!*q)
                            break;
              }

              maildir_writemsgstr(newdraftfd, header);
              maildir_writemsgstr(newdraftfd, ": ");
              maildir_writemsgstr(newdraftfd, value);
              maildir_writemsgstr(newdraftfd, "\n");
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void newmsg_copy_nonmime_headers ( FILE *  )

Definition at line 239 of file newmsg_create.c.

{
char   *header, *value;
char   *q;

       while ((header=maildir_readheader(fp, &value, 1)) != NULL)
       {
              if (strcmp(header, "mime-version") == 0 ||
                     strncmp(header, "content-", 8) == 0)      continue;

              /* Fluff - capitalize header names */

              for (q=header; *q; q++)
              {
                     for (*q=toupper(*q); *q; q++)
                            if (*q == '-')       break;
                     if (!*q)
                            break;
              }

              maildir_writemsgstr(newdraftfd, header);
              maildir_writemsgstr(newdraftfd, ": ");
              maildir_writemsgstr(newdraftfd, value);
              maildir_writemsgstr(newdraftfd, "\n");
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void newmsg_create_multipart ( int  ,
const char *  ,
const char *   
)

Definition at line 220 of file newmsg_create.c.

{
       maildir_writemsgstr(newdraftfd,
              "Mime-version: 1.0\n"
              "Content-Type: multipart/mixed; boundary=\"");
       maildir_writemsgstr(newdraftfd, multipart_boundary);
       maildir_writemsgstr(newdraftfd, "\"; charset=\"");
       maildir_writemsgstr(newdraftfd, charset);
       maildir_writemsgstr(newdraftfd, 
                                   "\"\n\n");

       maildir_writemsgstr(newdraftfd, mimemsg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void newmsg_hiddenheader ( const char *  ,
const char *   
)

Definition at line 176 of file newmsg.c.

{
       printf("<input type=\"hidden\" name=\"%s\" value=\"", label);
       output_attrencoded(value);
       printf("\" />");
}

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);
}

Definition at line 384 of file sqwebmail.c.

{
char   *p=scriptptrget();

       printf("%s", p);
       free(p);
       return;
}
void output_urlencoded ( const char *  )

Definition at line 279 of file sqwebmail.c.

{
char   *q=cgiurlencode(p);

       printf("%s", q);
       free(q);
}
static int save_filename ( const char *  param,
const char *  value,
void *  void_arg 
) [static]

Definition at line 646 of file attachments.c.

{
       strcat(strcat(strcat(strcat((char *)void_arg, ";\n  "), param),
                    "="), value);
       return 0;
}

Here is the caller graph for this function:

static const char* search_mime_type ( const char *  mimetype,
const char *  filename 
) [static]

Definition at line 545 of file attachments.c.

{
FILE   *fp;
char   *p, *q;

       if (!filename || !(filename=strrchr(filename, '.')))    return (0);
       ++filename;

       if ((fp=fopen(mimetype, "r")) == NULL)    return(0);
       while ((p=maildir_readline(fp)) != NULL)
       {
              if ((q=strchr(p, '#')) != NULL)    *q='\0';
              if ((p=strtok(p, " \t")) == NULL)  continue;
              while ((q=strtok(NULL, " \t")) != NULL)
                     if (strcasecmp(q, filename) == 0)
                     {
                            fclose(fp);
                            return (p);
                     }
       }
       fclose(fp);
       return (NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sendmsg_done ( )

Definition at line 902 of file newmsg.c.

{
       if ( *cgi("pos"))
              http_redirect_argss("&form=readmsg&pos=%s", cgi("pos"), "");
       else if (*cgi("sendmsg"))
              http_redirect_argss("&form=folders&foldermsg=sent", "", "");
       else
              http_redirect_argss("&form=folders", "", "");
}

Here is the call graph for this function:

Here is the caller graph for this function:

const char* showsize ( unsigned  long)

Definition at line 207 of file maildir.c.

{
static char   sizebuf[MAXLONGSIZE+10];

       /* If size is less than 1K bytes, display it as 0.xK */

       if (n < 1024)
       {
              strcpy(sizebuf, "0.");
              cat_n(sizebuf, (int)(10 * n / 1024 ));
              strcat(sizebuf, "K");
       }
       /* If size is less than 1 meg, display is as xK */

       else if (n < 1024 * 1024)
       {
              *sizebuf=0;
              cat_n(sizebuf, (unsigned long)(n+512)/1024);
              strcat(sizebuf, "K");
       }

       /* Otherwise, display in megabytes */

       else
       {
       unsigned long nm=(double)n / (1024.0 * 1024.0) * 10;

              *sizebuf=0;
              cat_n( sizebuf, nm / 10);
              strcat(sizebuf, ".");
              cat_n( sizebuf, nm % 10);
              strcat(sizebuf, "M");
       }
       return (sizebuf);
}

Here is the caller graph for this function:

static void upload_end ( void *  dummy) [static]

Definition at line 534 of file attachments.c.

{
}

Here is the caller graph for this function:

static int upload_file ( const char *  ptr,
size_t  cnt,
void *  voidptr 
) [static]

Definition at line 522 of file attachments.c.

{
size_t i;

       for (i=0; i<cnt; i++)
              if ( (ptr[i] < ' ' || ptr[i] >= 127) && ptr[i] != '\n' &&
                     ptr[i] != '\r')
                     isbinary=1;
       maildir_writemsg(attachfd, ptr, cnt);
       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int upload_start ( const char *  name,
const char *  filename,
void *  dummy 
) [static]

Definition at line 506 of file attachments.c.

{
const  char *p;

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

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

       cgi_attachname=name;
       cgi_attachfilename=filename;
       isbinary=0;
       return (0);
}

Here is the caller graph for this function:


Variable Documentation

int attachfd [static]

Definition at line 503 of file attachments.c.

const char * cgi_attachfilename [static]

Definition at line 504 of file attachments.c.

const char* cgi_attachname [static]

Definition at line 504 of file attachments.c.

int isbinary [static]

Definition at line 502 of file attachments.c.

Definition at line 49 of file newmsg_create.c.

Definition at line 39 of file gpg.c.

Definition at line 123 of file sqwebmail.c.