folder.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:52k
- /*
- ** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for
- ** distribution information.
- */
- /*
- ** $Id: folder.c,v 1.59 2000/06/03 05:40:27 mrsam Exp $
- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include "config.h"
- #include "sqwebmail.h"
- #include "maildir/maildirmisc.h"
- #include "rfc822/rfc822.h"
- #include "rfc822/rfc2047.h"
- #include "rfc2045/rfc2045.h"
- #include "maildir.h"
- #include "folder.h"
- #include "cgi/cgi.h"
- #include "pref.h"
- #include "html.h"
- #include "token.h"
- #include "filter.h"
- #include "buf.h"
- #include "pref.h"
- #if TIME_WITH_SYS_TIME
- #include <sys/time.h>
- #include <time.h>
- #else
- #if HAVE_SYS_TIME_H
- #include <sys/time.h>
- #else
- #include <time.h>
- #endif
- #endif
- extern const char *nonloginscriptptr();
- extern int pref_flagpagesize;
- extern const char *sqwebmail_content_charset;
- extern time_t rfc822_parsedt(const char *);
- static time_t current_time;
- static const char black_color[]="<FONT COLOR="#000000">";
- static const char end_font[]="</FONT>";
- static char *folder_err_msg=0;
- extern const char *sqwebmail_folder;
- extern char form_args[];
- extern void output_scriptptrget();
- extern void output_scriptptr();
- extern void output_attrencoded(const char *);
- extern void output_urlencoded(const char *);
- extern char *scriptptrget();
- void print_safe_len(const char *p, size_t n, void (*func)(const char *, size_t))
- {
- char buf[10];
- const char *q=p;
- while (n)
- {
- --n;
- if (*p == '<') strcpy(buf, "<");
- else if (*p == '>') strcpy(buf, ">");
- else if (*p == '&') strcpy(buf, "&");
- else if (*p == ' ') strcpy(buf, " ");
- else if (*p == 'n') strcpy(buf, "<BR>");
- else if (ISCTRL(*p))
- sprintf(buf, "&#%d;", (int)(unsigned char)*p);
- else
- {
- p++;
- continue;
- }
- (*func)(q, p-q);
- (*func)(buf, strlen(buf));
- p++;
- q=p;
- }
- (*func)(q, p-q);
- }
- static void print_safe_to_stdout(const char *p, size_t cnt)
- {
- fwrite(p, cnt, 1, stdout);
- }
- void print_safe(const char *p)
- {
- print_safe_len(p, strlen(p), print_safe_to_stdout);
- }
- void call_print_safe_to_stdout(const char *p, size_t cnt)
- {
- print_safe_len(p, cnt, print_safe_to_stdout);
- }
-
- void folder_contents_title()
- {
- char *p;
- char *lab;
- const char *f;
- const char *inbox_lab, *drafts_lab, *trash_lab, *sent_lab;
- p=strdup(form_args);
- if (!p) return;
- (void)strtok(p, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- lab=strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- inbox_lab=strtok(0, "|");
- drafts_lab=strtok(0, "|");
- trash_lab=strtok(0, "|");
- sent_lab=strtok(0, "|");
- f=sqwebmail_folder;
- if (strcmp(f, INBOX) == 0) f=inbox_lab;
- else if (strcmp(f, DRAFTS) == 0) f=drafts_lab;
- else if (strcmp(f, SENT) == 0) f=sent_lab;
- else if (strcmp(f, TRASH) == 0) f=trash_lab;
- if (lab)
- {
- char *q=malloc(strlen(lab)+strlen(f)+1);
- if (*f == ':') ++f;
- if (!q) enomem();
- sprintf(q, lab, f);
- output_attrencoded(q);
- free(q);
- }
- free(p);
- }
- static int group_movedel(const char *folder,
- int (*func)(const char *, const char *, size_t))
- {
- struct cgi_arglist *arg;
- if (*cgi("SELECTALL")) /* Everything is selected */
- {
- for (arg=cgi_arglist; arg; arg=arg->next)
- {
- const char *f;
- if (strncmp(arg->argname, "MOVEFILE-", 9)) continue;
- f=cgi(arg->argname);
- CHECKFILENAME(f);
- if ((*func)(folder, f, atol(arg->argname+9)))
- return (-1);
- }
- return (0);
- }
- for (arg=cgi_arglist; arg; arg=arg->next)
- {
- unsigned long l;
- char movedel[MAXLONGSIZE+10];
- const char *f;
- if (strncmp(arg->argname, "MOVE-", 5)) continue;
- l=atol(arg->argname+5);
- sprintf(movedel, "MOVEFILE-%lu", l);
- f=cgi(movedel);
- CHECKFILENAME(f);
- if ((*func)(folder, f, l))
- return (-1);
- }
- return (0);
- }
- static int groupdel(const char *folder, const char *file, size_t pos)
- {
- maildir_msgdeletefile(folder, file, pos);
- return (0);
- }
- static int groupmove(const char *folder, const char *file, size_t pos)
- {
- return (maildir_msgmovefile(folder, file, cgi("moveto"), pos));
- }
- void folder_delmsgs(const char *dir, size_t pos)
- {
- int rc=0;
- if (*cgi("cmddel"))
- {
- rc=group_movedel( dir, &groupdel );
- maildir_savefoldermsgs(dir);
- }
- else if (*cgi("cmdmove"))
- {
- rc=group_movedel( dir, &groupmove );
- maildir_savefoldermsgs(dir);
- }
- http_redirect_argu(
- (rc ? "&error=quota&form=folder&pos=%s":"&form=folder&pos=%s"),
- (unsigned long)pos);
- }
- static void folder_msg_link(const char *, size_t, char);
- static void folder_msg_unlink(const char *, size_t, char);
- void folder_contents(const char *dir, size_t pos)
- {
- MSGINFO **contents;
- int i, found;
- int morebefore, moreafter;
- char *argdup;
- char *datelab, *fromlab, *subjlab, *sizelab, *beforelab, *afterlab;
- char *nomsg, *selectalllab;
- char *qerrmsg;
- maildir_reload(dir);
- contents=maildir_read(dir, pref_flagpagesize, &pos,
- &morebefore, &moreafter);
- argdup=strdup(form_args);
- if (!argdup) return;
-
- time(¤t_time);
- datelab=strtok(argdup, "|");
- fromlab=strtok(0, "|");
- subjlab=strtok(0, "|");
- sizelab=strtok(0, "|");
- (void)strtok(0, "|");
- nomsg=strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- beforelab=strtok(0, "|");
- afterlab=strtok(0, "|");
- selectalllab=strtok(0, "|");
- if (!beforelab) beforelab="";
- if (!afterlab) afterlab="";
- if (!selectalllab) selectalllab="";
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- qerrmsg=strtok(0, "|");
- if (!qerrmsg) qerrmsg="";
- if (strcmp(cgi("error"), "quota") == 0)
- printf("%s", qerrmsg);
- printf("<TABLE WIDTH="100%%" BORDER=0 CELLPADDING=1 CELLSPACING=0>");
- printf("<TR><TD ALIGN=LEFT>");
- printf("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=4><TR><TD BGCOLOR="#DDDDDD">");
- if (morebefore)
- {
- size_t beforepos;
- if (pos < pref_flagpagesize) beforepos=0;
- else beforepos=pos-pref_flagpagesize;
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=folder&pos=%ld" STYLE="text-decoration: none">",
- (long)beforepos);
- }
- printf("%s", beforelab);
- if (morebefore)
- printf("</A>");
- printf("</TD></TR></TABLE>n");
- printf("</TD><TD ALIGN=RIGHT>n");
- printf("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=4><TR><TD BGCOLOR="#DDDDDD">");
- if (moreafter)
- {
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=folder&pos=%ld" STYLE="text-decoration: none">",
- (long)(pos+pref_flagpagesize));
- }
- printf("%s", afterlab);
- if (moreafter)
- printf("</A>");
- printf("</TD></TR></TABLE>n");
- printf("</TD></TR></TABLE>");
- printf("<TABLE WIDTH="100%%" BORDER=0 CELLSPACING=0 CELLPADDING=4><TR BGCOLOR="#000080"><TH ALIGN=CENTER><FONT COLOR="#FFFF00">#</FONT></TH><TH> </TH><TH><FONT COLOR="#FFFF00">%s</FONT></TH><TH><FONT COLOR="#FFFF00">%s</FONT></TH><TH><FONT COLOR="#FFFF00">%s</FONT></TH><TH><FONT COLOR="#FFFF00">%s</FONT><BR></TH></TR>n",
- datelab ? datelab:"",
- fromlab ? fromlab:"",
- subjlab ? subjlab:"",
- sizelab ? sizelab:"");
- found=0;
- for (i=0; i<pref_flagpagesize; i++)
- {
- const char *date, *from, *subj, *size;
- char *froms, *subjs;
- const char *p, *q;
- size_t l;
- char type[8];
- char *start_bold, *end_bold;
- if (contents[i] == 0) continue;
- found=1;
- date=MSGINFO_DATE(contents[i]);
- from=MSGINFO_FROM(contents[i]);
- subj=MSGINFO_SUBJECT(contents[i]);
- size=MSGINFO_SIZE(contents[i]);
- type[0]=maildirfile_type(MSGINFO_FILENAME(contents[i]));
- type[1]=' ';
- if (type[0] == ' ') strcpy(type, " ");
- start_bold=""; end_bold="";
- if (type[0] == MSGTYPE_NEW)
- {
- start_bold="<B>";
- end_bold="</B>";
- }
- p=MSGINFO_FILENAME(contents[i]);
- if ((q=strrchr(p, '/')) != 0)
- p=q+1;
- printf("<TR BGCOLOR="%s"><TD ALIGN=RIGHT>%s%s%ld.%s%s</TD><TD><INPUT TYPE=CHECKBOX NAME="MOVE-%ld",
- (i & 1 ? "#EEEEEE":"#DDDDDD"),
- black_color, start_bold,
- (long)(i+pos+1),
- end_bold, end_font,
- (long) (pos+i));
- printf(""%s><INPUT TYPE=HIDDEN NAME="MOVEFILE-%ld" VALUE="",
- (type[0] == MSGTYPE_DELETED ? " DISABLED":""),
- (long)(pos+i));
- output_attrencoded(p);
- printf(""> %s%s%s%s%s</TD><TD>%s%s",
- black_color, start_bold,
- type,
- end_bold, end_font,
- black_color, start_bold
- );
- if (!*date) date=" ";
- folder_msg_link(dir, pos+i, type[0]);
- print_safe(date);
- folder_msg_unlink(dir, pos+i, type[0]);
- printf("%s%s</TD><TD>%s%s", end_bold, end_font,
- black_color, start_bold);
- if (!*from) from=" ";
- folder_msg_link(dir, pos+i, type[0]);
- froms=rfc2047_decode_simple(from);
- if (froms == 0) enomem();
- if (strlen(froms) >= 30)
- strcpy(froms+27, "...");
- print_safe(froms);
- free(froms);
- folder_msg_unlink(dir, pos+i, type[0]);
- printf("%s%s<BR></TD><TD>%s%s", end_bold, end_font,
- black_color, start_bold);
- folder_msg_link(dir, pos+i, type[0]);
- subjs=rfc2047_decode_simple(subj);
- if (subjs == 0) enomem();
- if (strlen(subjs) >= 40)
- strcpy(subjs+37, "...");
- print_safe(subjs);
- l=strlen(subjs);
- while (l++ < 8)
- printf(" ");
- free(subjs);
- folder_msg_unlink(dir, pos+i, type[0]);
- printf("%s%s</TD><TD ALIGN=RIGHT>%s%s%s%s%s<BR></TD></TR>n", end_bold, end_font, black_color, start_bold, size, end_bold, end_font);
- }
- if (found)
- {
- puts("<TR BGCOLOR="#DDDDDD"><TD COLSPAN=6><HR></TD></TR>");
- puts("<TR BGCOLOR="#EEEEEE"><TD> </TD>");
- printf("<TD COLSPAN=5><INPUT TYPE=CHECKBOX NAME="SELECTALL"> %s</TD></TR>",
- selectalllab);
- }
- if (!found && nomsg)
- {
- puts("<TR BGCOLOR="#FFBBBB"><TD COLSPAN=6 ALIGN=LEFT><P>");
- puts(black_color);
- puts(nomsg);
- puts(end_font);
- puts("<BR></TD></TR>");
- }
- printf("</TABLE>n");
- free(argdup);
- maildir_free(contents, pref_flagpagesize);
- }
- static void folder_msg_link(const char *dir, size_t pos, char t)
- {
- if (t == MSGTYPE_DELETED)
- {
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=folder&pos=%s">", cgi("pos"));
- return;
- }
- printf("<A HREF="");
- if (strcmp(dir, DRAFTS))
- {
- output_scriptptrget();
- printf("&form=readmsg&pos=%ld">", (long)pos);
- }
- else
- {
- size_t mpos=pos;
- char *filename=maildir_posfind(dir, &mpos);
- char *basename=filename ? maildir_basename(filename):NULL;
- output_scriptptrget();
- printf("&form=newmsg&draft=");
- output_urlencoded(basename);
- printf("">");
- if (basename) free(basename);
- if (filename) free(filename);
- }
- }
- static void folder_msg_unlink(const char *dir, size_t pos, char t)
- {
- printf("</A>");
- }
- static size_t msg_pos, msg_count;
- static char *msg_posfile;
- static int msg_hasprev, msg_hasnext;
- static char *msg_nextlab=0, *msg_prevlab=0, *msg_deletelab=0,
- *msg_purgelab=0, *msg_folderlab=0;
- static char msg_type;
- static char *msg_badcontenttype=0;
- static char *msg_dispattachment=0;
- static char *msg_downattachment=0;
- static char *msg_replylab=0;
- static char *msg_replyalllab=0;
- static char *msg_forwardlab=0;
- static char *msg_forwardattlab=0;
- static char *msg_fullheaderlab=0;
- static char *msg_movetolab=0;
- static char *msg_print=0;
- static char *folder_inbox=0;
- static char *folder_drafts=0;
- static char *folder_trash=0;
- static char *folder_sent=0;
- static char *msg_golab=0;
- static const char *msg_msglab;
- static int initnextprevcnt;
- void folder_initnextprev(const char *dir, size_t pos)
- {
- MSGINFO **info;
- const char *p;
- const char *msg_numlab, *msg_numnewlab;
- initnextprevcnt=0;
- msg_nextlab=strtok(form_args, "|");
- msg_prevlab=strtok(NULL, "|");
- msg_deletelab=strtok(NULL, "|");
- msg_purgelab=strtok(NULL, "|");
- msg_folderlab=strtok(NULL, "|");
- msg_badcontenttype=strtok(NULL, "|");
- msg_dispattachment=strtok(NULL, "|");
- msg_downattachment=strtok(NULL, "|");
- msg_replylab=strtok(NULL, "|");
- msg_replyalllab=strtok(NULL, "|");
- msg_forwardlab=strtok(NULL, "|");
- msg_forwardattlab=strtok(NULL, "|");
- msg_numlab=strtok(NULL, "|");
- msg_numnewlab=strtok(NULL, "|");
- msg_fullheaderlab=strtok(NULL, "|");
- msg_movetolab=strtok(NULL, "|");
- msg_print=strtok(NULL, "|");
- folder_inbox=strtok(NULL, "|");
- folder_drafts=strtok(NULL, "|");
- folder_trash=strtok(NULL, "|");
- folder_sent=strtok(NULL, "|");
- p=strtok(NULL, "|");
- if (!p) p="";
- if (strcmp(cgi("error"),"quota") == 0)
- printf("%s", p);
- msg_golab=strtok(NULL, "|");
- info=maildir_read(dir, 1, &pos, &msg_hasprev, &msg_hasnext);
- msg_pos=pos;
- printf("<INPUT TYPE=HIDDEN NAME="pos" VALUE="%ld">",
- (long)msg_pos);
- p=strrchr(MSGINFO_FILENAME(info[0]), '/');
- if (p) p++;
- else p=MSGINFO_FILENAME(info[0]);
- msg_posfile=strdup(p);
- if (!msg_posfile) enomem();
- if ((msg_type=maildirfile_type(MSGINFO_FILENAME(info[0])))
- == MSGTYPE_NEW) msg_numlab=msg_numnewlab;
- msg_msglab=msg_numlab;
- msg_count=maildir_countof(dir);
- printf("<INPUT TYPE=HIDDEN NAME="posfile" VALUE="");
- output_attrencoded(p);
- printf(""><INPUT TYPE=HIDDEN NAME="form" VALUE="delmsg">");
- maildir_free(info, 1);
- }
- void folder_nextprev()
- {
- printf("<TABLE WIDTH="100%%" BORDER=0 CELLSPACING=0 CELLPADDING=0><TR VALIGN=CENTER>");
- printf("<TD ALIGN=LEFT><TABLE BORDER=0 CELLSPACING=4><TR>");
- /* Pmovetolab */
- printf("<TD BGCOLOR="#DDDDDD"> ");
- if (msg_hasprev)
- {
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=readmsg&pos=%ld" STYLE="text-decoration: none">",
- (long)(msg_pos-1));
- }
- printf("%s", msg_prevlab ? msg_prevlab:"");
- if (msg_hasprev)
- {
- printf("</A>");
- }
- printf(" </TD>");
- /* NEXT */
- printf("<TD BGCOLOR="#DDDDDD"> ");
- if (msg_hasnext)
- {
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=readmsg&pos=%ld" STYLE="text-decoration: none">",
- (long)(msg_pos+1));
- }
- printf("%s", msg_nextlab ? msg_nextlab:"");
- if (msg_hasnext)
- {
- printf("</A>");
- }
- printf(" </TD>");
- /* DEL */
- printf("<TD BGCOLOR="#DDDDDD"> ");
- if (msg_type != MSGTYPE_DELETED)
- {
- printf("<A HREF="");
- output_scriptptrget();
- tokennewget();
- printf("&posfile=");
- output_urlencoded(msg_posfile);
- printf("&form=delmsg&pos=%ld" STYLE="text-decoration: none">",
- (long)msg_pos);
- }
- printf("%s", strcmp(sqwebmail_folder, TRASH) == 0
- ? msg_purgelab : msg_deletelab);
- if (msg_type != MSGTYPE_DELETED)
- printf("</A>");
- printf(" </TD>n");
- /* FOLDER */
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&form=folder"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)( (msg_pos/pref_flagpagesize)*pref_flagpagesize ),
- msg_folderlab);
- /* REPLY */
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&reply=1&form=newmsg"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)msg_pos,
- msg_replylab);
- /* REPLY ALL */
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&replyall=1&form=newmsg"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)msg_pos,
- msg_replyalllab);
- printf("</TR></TABLE><TABLE BORDER=0 CELLSPACING=4><TR>");
- /* FORWARD */
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&forward=1&form=newmsg"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)msg_pos,
- msg_forwardlab);
- /* FORWARD AS ATTACHMENT*/
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&forwardatt=1&form=newmsg"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)msg_pos,
- msg_forwardattlab);
- /* FULL HEADERS */
- if (!pref_flagfullheaders && !*cgi("fullheaders"))
- {
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- printf("&pos=%ld&form=readmsg&fullheaders=1"; STYLE="text-decoration: none">%s</A> </TD>n",
- (long)msg_pos, msg_fullheaderlab);
- }
- /* PRINT MESSAGE */
- printf("<TD BGCOLOR="#DDDDDD"> <A HREF="");
- output_scriptptrget();
- if (pref_flagfullheaders || *cgi("fullheaders"))
- {
- printf("&pos=%ld&form=print&setcookie=1&fullheaders=1"; STYLE="text-decoration: none" TARGET="_BLANK">%s</A> </TD>n", (long)msg_pos, msg_print);
- }
- else
- {
- printf("&pos=%ld&form=print&setcookie=1"; STYLE="text-decoration: none" TARGET="_BLANK">%s</A> </TD>n", (long)msg_pos, msg_print);
- }
- printf("</TD>");
-
- /* end PRINT MESSAGE */
-
- printf("</TR></TABLE></TD><TD ALIGN=RIGHT VALIGN=CENTER>");
- printf("<TABLE BORDER=0 CELLSPACING=4><TR><TD BGCOLOR="#666666"> <FONT COLOR="#FFFFFF">");
- printf(msg_msglab, (int)msg_pos+1, (int)msg_count);
- printf("</FONT> </TD></TR></TABLE>");
- printf("</TD></TR></TABLE>n");
- }
- static void show_transfer_dest(const char *cur_folder)
- {
- char **folders;
- size_t i;
- const char *p;
- int has_shared=0;
- maildir_readfolders(&folders);
- for (i=0; folders[i]; i++)
- {
- /* Transferring TO drafts is prohibited */
- if (strcmp(cur_folder, DRAFTS))
- {
- if (strcmp(folders[i], DRAFTS) == 0)
- continue;
- }
- else
- {
- if (folders[i][0] != ':' && strcmp(folders[i], TRASH))
- continue;
- }
- if (strcmp(cur_folder, folders[i]) == 0)
- continue;
- p=folders[i];
- if (strcmp(p, INBOX) == 0)
- p=folder_inbox;
- else if (strcmp(p, DRAFTS) == 0)
- p=folder_drafts;
- else if (strcmp(p, TRASH) == 0)
- p=folder_trash;
- else if (strcmp(p, SENT) == 0)
- p=folder_sent;
- if (!p) p=folders[i];
- if (folders[i][0] == ':')
- {
- char *d=maildir_shareddir(".", folders[i]+1);
- if (!d)
- {
- maildir_freefolders(&folders);
- enomem();
- }
- if (access(d, 0)) /* Not subscribed */
- {
- free(d);
- continue;
- }
- free(d);
- }
- if (folders[i][0] == ':' && !has_shared)
- {
- printf("<OPTION VALUE="">n");
- has_shared=1;
- }
- printf("<OPTION VALUE="");
- output_attrencoded(folders[i]);
- printf("">");
- print_safe(folders[i][0] == ':' ? p+1:p);
- printf("n");
- }
- maildir_freefolders(&folders);
- }
- void folder_msgmove()
- {
- ++initnextprevcnt;
- printf("<TABLE BORDER=0 BGCOLOR="#000000"><TR><TD>n");
- printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD BGCOLOR="#DDDDDD"> %s%s <SELECT NAME=list%d>n",
- black_color, msg_movetolab, initnextprevcnt);
- show_transfer_dest(sqwebmail_folder);
- printf("</SELECT><INPUT TYPE=SUBMIT %s NAME=move%d VALUE="%s">%s</TD></TR></TABLE>n",
- (msg_type == MSGTYPE_DELETED ? "DISABLED":""),
- initnextprevcnt,
- msg_golab ? msg_golab:"",
- end_font);
- printf("</TD></TR></TABLE>n");
- }
- void folder_delmsg(size_t pos)
- {
- MSGINFO **info;
- int dummy;
- const char *f=cgi("posfile");
- size_t newpos;
- int rc=0;
- CHECKFILENAME(f);
- if (*cgi("move1"))
- {
- rc=maildir_msgmovefile(sqwebmail_folder, f, cgi("list1"), pos);
- maildir_savefoldermsgs(sqwebmail_folder);
- }
- else if (*cgi("move2"))
- {
- rc=maildir_msgmovefile(sqwebmail_folder, f, cgi("list2"), pos);
- maildir_savefoldermsgs(sqwebmail_folder);
- }
- else
- {
- maildir_msgdeletefile(sqwebmail_folder, f, pos);
- maildir_savefoldermsgs(sqwebmail_folder);
- }
- if (rc)
- {
- http_redirect_argu("&form=readmsg&pos=%s&error=quota",
- (unsigned long)newpos);
- return;
- }
- newpos=pos+1;
- info=maildir_read(sqwebmail_folder, 1, &newpos, &dummy, &dummy);
- if (info[0] && newpos != pos)
- {
- maildir_free(info, 1);
- http_redirect_argu("&form=readmsg&pos=%s",
- (unsigned long)newpos);
- }
- else
- {
- maildir_free(info, 1);
- http_redirect_argu("&form=folder&pos=%s",
- (unsigned long)pos);
- }
- }
- static void showmsgrfc822(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showmsgrfc822_body(FILE *, struct rfc2045 *, struct rfc2045id *, int);
- void folder_showmsg(const char *dir, size_t pos)
- {
- char *filename;
- FILE *fp;
- struct rfc2045 *rfc;
- char buf[512];
- int n;
- int fd;
- filename=maildir_posfind(dir, &pos);
- if (!filename) return;
- fp=0;
- fd=maildir_semisafeopen(filename, O_RDONLY, 0);
- if (fd >= 0)
- {
- if ((fp=fdopen(fd, "r")) == 0)
- close(fd);
- }
- if (!fp)
- {
- free(filename);
- return;
- }
- msg_pos=pos;
- rfc=rfc2045_alloc();
- while ((n=fread(buf, 1, sizeof(buf), fp)) > 0)
- rfc2045_parse(rfc, buf, n);
- showmsgrfc822_body(fp, rfc, NULL, 0);
- rfc2045_free(rfc);
- fclose(fp);
- maildir_markread(dir, pos);
- free(filename);
- }
- static void showtextplain(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showdsn(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showtexthtml(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showmultipart(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showmsgrfc822(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void showunknown(FILE *, struct rfc2045 *, struct rfc2045id *);
- static void (*get_known_handler(struct rfc2045 *mime))(FILE *, struct rfc2045 *, struct rfc2045id *)
- {
- const char *content_type, *dummy;
- const char *disposition_s;
- const char *disposition_name_s;
- const char *disposition_filename_s;
- rfc2045_mimeinfo(mime, &content_type, &dummy, &dummy);
- if (strncmp(content_type, "multipart/", 10) == 0)
- return ( &showmultipart );
- rfc2045_dispositioninfo(mime, &disposition_s, &disposition_name_s,
- &disposition_filename_s);
- if (disposition_s && strcmp(disposition_s, "attachment") == 0)
- return (0);
- if (strcmp(content_type, "text/plain") == 0 ||
- strcmp(content_type, "text/rfc822-headers") == 0)
- return ( &showtextplain );
- if (strcmp(content_type, "message/delivery-status") == 0)
- return ( &showdsn);
- if (pref_showhtml && strcmp(content_type, "text/html") == 0)
- return ( &showtexthtml );
- if (strcmp(content_type, "message/rfc822") == 0)
- return ( &showmsgrfc822 );
- return (0);
- }
- static void (*get_handler(struct rfc2045 *mime))(FILE *, struct rfc2045 *, struct rfc2045id *)
- {
- void (*func)(FILE *, struct rfc2045 *, struct rfc2045id *);
- if ((func=get_known_handler(mime)) == 0)
- func= &showunknown;
- return (func);
- }
- static void showmsgrfc822(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- if (rfc->firstpart)
- showmsgrfc822_body(fp, rfc->firstpart, id, 1);
- }
- static void showmsgrfc822_header(const char *);
- static void showmsgrfc822_addressheader(const char *);
- static void showmsgrfc2369_header(const char *);
- static int isaddressheader(const char *header)
- {
- return (strcmp(header, "to") == 0 ||
- strcmp(header, "cc") == 0 ||
- strcmp(header, "from") == 0 ||
- strcmp(header, "sender") == 0 ||
- strcmp(header, "resent-to") == 0 ||
- strcmp(header, "resent-cc") == 0 ||
- strcmp(header, "reply-to") == 0);
- }
- static void showmimeid(struct rfc2045id *idptr)
- {
- char *p="&mimeid=";
- while (idptr)
- {
- printf("%s%d", p, idptr->idnum);
- idptr=idptr->next;
- p=".";
- }
- }
- static void digestaction(struct rfc2045id *idptr)
- {
- printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD><A HREF="");
- output_scriptptrget();
- showmimeid(idptr);
- printf("&pos=%ld&reply=1&form=newmsg"><FONT SIZE="-1">%s</FONT></A> </TD><TD> <A HREF="",
- (long)msg_pos, msg_replylab);
- output_scriptptrget();
- showmimeid(idptr);
- printf("&pos=%ld&replyall=1&form=newmsg"><FONT SIZE="-1">%s</FONT></A> </TD><TD> <A HREF="",
- (long)msg_pos, msg_replyalllab);
- output_scriptptrget();
- showmimeid(idptr);
- printf("&pos=%ld&forward=1&form=newmsg"><FONT SIZE="-1">%s</FONT></A> </TD><TD> <A HREF="",
- (long)msg_pos, msg_forwardlab);
- output_scriptptrget();
- showmimeid(idptr);
- printf("&pos=%ld&forwardatt=1&form=newmsg"><FONT SIZE="-1">%s</FONT></A></TD></TR></TABLE>n",
- (long)msg_pos, msg_forwardattlab);
- }
- /* Prettify header name by uppercasing the first character. */
- void header_uc(char *h)
- {
- while (*h)
- {
- *h=toupper( (int)(unsigned char) *h);
- while (*h)
- {
- if (*h++ == '-') break;
- }
- }
- }
- static void showmsgrfc822_body(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *idptr, int flag)
- {
- char *header, *value;
- char *save_subject=0;
- char *save_date=0;
- char *par;
- off_t start_pos, end_pos, start_body;
- struct rfc2045id *p, newpart;
- off_t dummy;
- off_t pos;
- rfc2045_mimepos(rfc, &start_pos, &end_pos, &start_body, &dummy, &dummy);
- if (fseek(fp, start_pos, SEEK_SET) < 0)
- {
- error("Seek error.");
- return;
- }
- printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>n");
- par="<P>";
- pos=start_pos;
- while ((header=maildir_readheader_mimepart(fp, &value, 1,
- &pos, &start_body)) != 0)
- {
- if (strcmp(header, "list-help") == 0 ||
- strcmp(header, "list-subscribe") == 0 ||
- strcmp(header, "list-unsubscribe") == 0 ||
- strcmp(header, "list-owner") == 0 ||
- strcmp(header, "list-archive") == 0 ||
- strcmp(header, "list-post") == 0)
- {
- header_uc(header);
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT>%s%s:<TT> </TT></TH>",
- par, header);
- par="";
- printf("<TD><TT>");
- showmsgrfc2369_header(value);
- printf("</TT></TD></TR>n");
- continue;
- }
- if (pref_flagfullheaders || *cgi("fullheaders"))
- {
- int isaddress=isaddressheader(header);
- header_uc(header);
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT>%s%s:<TT> </TT></TH>",
- par, header);
- printf("<TD><TT>");
- if (isaddress)
- showmsgrfc822_addressheader(value);
- else
- showmsgrfc822_header(value);
- printf("</TT></TD></TR>n");
- par="";
- continue;
- }
- if (strcmp(header, "subject") == 0)
- {
- if (save_subject) free(save_subject);
- save_subject=rfc2047_decode_enhanced(value,
- sqwebmail_content_charset);
- if (save_subject == 0)
- enomem();
- continue;
- }
- if (strcmp(header, "date") == 0)
- {
- if (save_date) free(save_date);
- if ((save_date=malloc(strlen(value)+1)) == 0)
- enomem();
- strcpy(save_date, value);
- continue;
- }
- if (isaddressheader(header))
- {
- header_uc(header);
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT>%s%s:<TT> </TT></TH>",
- par, header);
- printf("<TD><TT>");
- showmsgrfc822_addressheader(value);
- printf("</TT></TD></TR>n");
- par="";
- }
- }
- if (save_date)
- {
- time_t t=rfc822_parsedt(save_date);
- struct tm *tmp=t ? localtime(&t):0;
- char date_buf[100];
- if (tmp)
- {
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT>%sDate:<TT> </TT></TH>",
- par);
- strftime(date_buf, sizeof(date_buf)-1, "%d %b %Y, %I:%M:%S %p", tmp);
- date_buf[sizeof(date_buf)-1]=0;
- printf("<TD><TT>");
- showmsgrfc822_header(date_buf);
- printf("</TT></TD></TR>n");
- par="";
- }
- free(save_date);
- }
- if (save_subject)
- {
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT>%sSubject:<TT> </TT></TH>",
- par);
- printf("<TD><TT>");
- showmsgrfc822_header(save_subject);
- printf("</TT></TD></TR>n");
- par="";
- }
- if (flag)
- {
- printf("<TR VALIGN=TOP><TD> </TD><TD ALIGN=LEFT VALIGN=TOP>");
- digestaction(idptr);
- printf("</TD></TR>n");
- }
- printf("</TABLE>n<HR WIDTH="100%%">n");
- if (!idptr)
- {
- idptr= &newpart;
- p=0;
- }
- else
- {
- for (p=idptr; p->next; p=p->next)
- ;
- p->next=&newpart;
- }
- newpart.idnum=1;
- newpart.next=0;
- (*get_handler(rfc))(fp, rfc, idptr);
- if (p)
- p->next=0;
- }
- static void showmsgrfc822_headerp(const char *p, size_t l)
- {
- fwrite(p, 1, l, stdout);
- }
- static void showmsgrfc822_header(const char *p)
- {
- filter_start(FILTER_FOR_DISPLAY, showmsgrfc822_headerp);
- filter(p, strlen(p));
- filter_end();
- }
- static void showaddressheader_printc(char c, void *p)
- {
- p=p;
- print_safe_len(&c, 1, print_safe_to_stdout);
- }
- static void showaddressheader_printsep(const char *sep, void *p)
- {
- p=p;
- printf("%s", sep);
- }
- static void showmsgrfc822_addressheader(const char *p)
- {
- struct rfc822t *rfcp;
- struct rfc822a *rfca;
- rfcp=rfc822t_alloc(p, NULL);
- if (!rfcp) enomem();
- rfca=rfc822a_alloc(rfcp);
- if (!rfca) enomem();
- rfc2047_print(rfca, sqwebmail_content_charset,
- showaddressheader_printc, showaddressheader_printsep, NULL);
- rfc822a_free(rfca);
- rfc822t_free(rfcp);
- }
- static void showrfc2369_printheader(char c, void *p)
- {
- p=p;
- putchar(c);
- }
- static char *get_textlink(const char *);
- static void showmsgrfc2369_header(const char *p)
- {
- struct rfc822t *rfcp;
- struct rfc822a *rfca;
- int i;
- rfcp=rfc822t_alloc(p, NULL);
- if (!rfcp) enomem();
- rfca=rfc822a_alloc(rfcp);
- if (!rfca) enomem();
- for (i=0; i<rfca->naddrs; i++)
- {
- char *p=rfc822_getaddr(rfca, i);
- char *q=get_textlink(p);
- if (rfca->addrs[i].tokens)
- {
- rfca->addrs[i].tokens->token=0;
- if (*q)
- free(p);
- else
- {
- struct buf b;
- buf_init(&b);
- free(q);
- for (q=p; *q; q++)
- {
- char c[2];
- switch (*q) {
- case '<':
- buf_cat(&b, "<");
- break;
- case '>':
- buf_cat(&b, ">");
- break;
- case '&':
- buf_cat(&b, "&");
- break;
- case ' ':
- buf_cat(&b, " ");
- break;
- default:
- c[1]=0;
- c[0]=*q;
- buf_cat(&b, c);
- break;
- }
- }
- free(p);
- q=strdup(b.ptr ? b.ptr:"");
- buf_free(&b);
- if (!q) enomem();
- }
- rfca->addrs[i].tokens->ptr=q;
- rfca->addrs[i].tokens->len=strlen(q);
- rfca->addrs[i].tokens->next=0;
- }
- else
- {
- free(q);
- free(p);
- }
- }
- rfc822_print(rfca, showrfc2369_printheader,
- showaddressheader_printsep, NULL);
- for (i=0; i<rfca->naddrs; i++)
- if (rfca->addrs[i].tokens)
- free((char *)rfca->addrs[i].tokens->ptr);
- rfc822a_free(rfca);
- rfc822t_free(rfcp);
- }
- static void output_mimeurl(struct rfc2045id *id)
- {
- output_scriptptrget();
- printf("&form=fetch&pos=%ld", (long)msg_pos);
- showmimeid(id);
- }
- static void showattname(const char *fmt, const char *name,
- const char *content_type);
- static void showunknown(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- const char *content_type, *dummy;
- const char *disposition_s;
- const char *disposition_name_s;
- const char *disposition_filename_s;
- id=id;
- rfc2045_mimeinfo(rfc, &content_type, &dummy, &dummy);
- rfc2045_dispositioninfo(rfc, &disposition_s, &disposition_name_s,
- &disposition_filename_s);
- /* Punt for image/ MIMEs */
- if (strncmp(content_type, "image/", 6) == 0 &&
- (disposition_s == 0 || strcmp(disposition_s, "attachment")))
- {
- printf("<A HREF="");
- output_mimeurl(id);
- printf("" TARGET="_blank"><IMG SRC="");
- output_mimeurl(id);
- printf("" ALT="Inline picture: ");
- output_attrencoded(content_type);
- printf(""></A>n");
- return;
- }
- dummy=rfc2045_contentname(rfc);
- printf("<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=0 BGCOLOR="#000000"><TR><TD>");
- printf("<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0 BGCOLOR="#DDDDDD"><TR><TD>");
- if (msg_dispattachment)
- {
- printf("<CENTER><A HREF="");
- output_mimeurl(id);
- printf("" STYLE="text-decoration: none" TARGET="_blank">");
- showattname(msg_dispattachment, dummy, content_type);
- printf("</A></CENTER>");
- }
- printf("<HR WIDTH="100%%">n");
- if (msg_downattachment)
- {
- printf("<CENTER><A HREF="");
- output_mimeurl(id);
- printf("&download=1" STYLE="text-decoration: none">");
- showattname(msg_downattachment, dummy, content_type);
- printf("</A></CENTER>");
- }
- printf("</TR></TD></TABLE>n");
- printf("</TR></TD></TABLE>n");
- }
- static void showattname(const char *fmt, const char *name,
- const char *content_type)
- {
- char *s, *t;
- if (!name || !*name) name=content_type;
- if (!name) name="";
- s=rfc2047_decode_simple(name);
- if (!s) return;
- t=malloc(strlen(s)+strlen(fmt)+100);
- if (!t)
- {
- free(s);
- return;
- }
- sprintf(t, fmt, s ? s:name);
- if (s) free(s);
- output_attrencoded(t);
- }
- static void showmultipart(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- const char *content_type, *dummy;
- struct rfc2045 *q;
- struct rfc2045id nextpart;
- struct rfc2045id *p;
- for (p=id; p->next; p=p->next)
- ;
- p->next=&nextpart;
- nextpart.idnum=0;
- nextpart.next=0;
- rfc2045_mimeinfo(rfc, &content_type, &dummy, &dummy);
- if (strcmp(content_type, "multipart/alternative") == 0)
- {
- struct rfc2045 *q, *r=0;
- int idnum=0;
- for (q=rfc->firstpart; q; q=q->next, ++idnum)
- {
- if (q->isdummy) continue;
- if (!r || get_known_handler(q))
- {
- r=q; /* Pick up at least one part */
- nextpart.idnum=idnum;
- }
- }
- if (r)
- (*get_handler(r))(fp, r, id);
- }
- else if (strcmp(content_type, "multipart/related") == 0)
- {
- char *sid=rfc2045_related_start(rfc);
- /*
- ** We can't just walts in, search for the Content-ID:,
- ** and skeddaddle, that's because we need to keep track of
- ** our MIME section. So we pretend that we're multipart/mixed,
- ** see below, and abort at the first opportunity.
- */
- for (q=rfc->firstpart; q; q=q->next, ++nextpart.idnum)
- {
- const char *cid;
- if (q->isdummy) continue;
- cid=rfc2045_content_id(q);
- if (sid && *sid && strcmp(sid, cid))
- continue;
- (*get_handler(q))(fp, q, id);
- break;
- /* In all cases, we stop after dumping something */
- }
- if (sid) free(sid);
- }
- else
- {
- for (q=rfc->firstpart; q; q=q->next, ++nextpart.idnum)
- {
- if (q->isdummy) continue;
- (*get_handler(q))(fp, q, id);
- if (q->next)
- printf("<HR WIDTH="100%%">n");
- }
- }
- p->next=0;
- }
- static void text_to_stdout(const char *p, size_t n)
- {
- while (n)
- {
- --n;
- putchar(*p++);
- }
- }
- static struct buf showtextplain_buf;
- static const char *skip_text_url(const char *r, const char *end)
- {
- const char *q=r;
- for (; r < end && (isalnum(*r) || *r == ':' || *r == '/'
- || *r == '.' || *r == '~' || *r == '%'
- || *r == '+' || *r == '?' || *r == '&' || *r == '#'
- || *r == '=' || *r == '@' || *r == ';'
- || *r == '-' || *r == '_' || *r == ','); r++)
- {
- if (*r == '&' && (end-r < 5 || strncmp(r, "&", 5)))
- break;
- }
- if (r > q && (r[-1] == ',' || r[-1] == '.')) --r;
- return (r);
- }
- static char *decode_cgiurlencode(const char *s)
- {
- char *q=malloc(strlen(s)+1), *r;
- const char *t;
- if (!q) enomem();
- for (r=q, t=s; *t; )
- {
- if (strncmp(t, "&", 5) == 0)
- {
- *r++ = '&';
- t += 5;
- continue;
- }
- if (strncmp(t, "<", 4) == 0)
- {
- *r++ = '<';
- t += 4;
- continue;
- }
- if (strncmp(t, ">", 4) == 0)
- {
- *r++ = '>';
- t += 4;
- continue;
- }
- if (strncmp(t, """, 6) == 0)
- {
- *r++ = '"';
- t += 6;
- continue;
- }
- *r++ = *t++;
- }
- *r=0;
- r=cgiurlencode(q);
- free(q);
- return (r);
- }
- static char *get_textlink(const char *s)
- {
- char *t;
- struct buf b;
- buf_init(&b);
- if (strncmp(s, "mailto:", 7) == 0)
- {
- int i;
- buf_cat(&b, "<A HREF="");
- buf_cat(&b, scriptptrget());
- buf_cat(&b, "&form=newmsg&to=");
- for (i=7; s[i]; i++)
- {
- char c[2];
- c[1]=0;
- if ((c[0]=s[i]) == '?')
- c[0]='&';
- buf_cat(&b, c);
- }
- buf_cat(&b, "">");
- buf_cat(&b, s);
- buf_cat(&b, "</A>");
- }
- else if (strncmp(s, "http:", 5) == 0)
- {
- t=decode_cgiurlencode(s);
- buf_cat(&b, "<A HREF="");
- buf_cat(&b, getenv("SCRIPT_NAME"));
- buf_cat(&b, "?redirect=");
- buf_cat(&b, t);
- buf_cat(&b, "" TARGET="_blank">");
- buf_cat(&b, s);
- buf_cat(&b, "</A>");
- free(t);
- }
- t=strdup(b.ptr ? b.ptr:"");
- if (!t) enomem();
- buf_free(&b);
- return (t);
- }
- static void showtextplain_oneline(const char *p, size_t n)
- {
- const char *q, *r;
- char *s, *t;
- for (q=r=p; q < p+n; q++)
- {
- if ( p+n-q > 7 &&
- (strncmp(q, "http://", 7) == 0
- ||
- strncmp(q, "mailto:", 7) == 0)
- )
- {
- fwrite(r, 1, q-r, stdout);
- r=skip_text_url(q, p+n);
- if ((s=malloc(r+1-q)) == NULL) enomem();
- memcpy(s, q, r-q);
- s[r-q]=0;
- printf("%s", (t=get_textlink(s)));
- free(t);
- free(s);
- q=r;
- }
- }
- fwrite(r, 1, q-r, stdout);
- }
- static void showtextplainfunc(const char *txt, size_t l)
- {
- const char *p;
- size_t n;
- if (txt)
- {
- buf_catn(&showtextplain_buf, txt, l);
- while ((p=strchr(showtextplain_buf.ptr, 'n')) != 0)
- {
- n= p+1 - showtextplain_buf.ptr;
- showtextplain_oneline(showtextplain_buf.ptr, n);
- buf_trimleft(&showtextplain_buf, n);
- }
- }
- else if (showtextplain_buf.cnt)
- showtextplain_oneline(showtextplain_buf.ptr,
- showtextplain_buf.cnt);
- }
- static int filter_stub(const char *ptr, size_t cnt, void *voidptr)
- {
- filter(ptr, cnt);
- return (0);
- }
- static void showtextplain(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- off_t start_pos, end_pos, start_body;
- char buf[512];
- int cnt;
- off_t dummy;
- id=id;
- rfc2045_mimepos(rfc, &start_pos, &end_pos, &start_body, &dummy, &dummy);
- if (fseek(fp, start_body, SEEK_SET) < 0)
- {
- error("Seek error.");
- return;
- }
- printf("<TT><PRE>");
- buf_init(&showtextplain_buf);
- filter_start(FILTER_FOR_DISPLAY, &showtextplainfunc);
- rfc2045_cdecode_start(rfc, &filter_stub, 0);
- while (start_body < end_pos)
- {
- cnt=sizeof(buf);
- if (cnt > end_pos-start_body)
- cnt=end_pos-start_body;
- cnt=fread(buf, 1, cnt, fp);
- if (cnt <= 0) break;
- rfc2045_cdecode(rfc, buf, cnt);
- start_body += cnt;
- }
- rfc2045_cdecode_end(rfc);
- filter_end();
- showtextplainfunc(0, 0);
- buf_free(&showtextplain_buf);
- printf("</PRE></TT><BR>n");
- }
- static void showdsn(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- off_t start_pos, end_pos, start_body;
- off_t dummy;
- char *par;
- id=id;
- rfc2045_mimepos(rfc, &start_pos, &end_pos, &start_body, &dummy, &dummy);
- if (fseek(fp, start_body, SEEK_SET) < 0)
- {
- error("Seek error.");
- return;
- }
- par="<P>";
- printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>n");
- while (start_body < end_pos)
- {
- int c=getc(fp);
- char *header, *value;
- if (c == EOF) break;
- if (c == 'n')
- {
- printf("<TR><TD COLSPAN=2><HR></TD></TR>n");
- ++start_body;
- par="<P>";
- continue;
- }
- ungetc(c, fp);
- if ((header=maildir_readheader_mimepart(fp, &value, 1,
- &start_body, &end_pos)) == 0)
- break;
- header_uc(header);
- printf("<TR VALIGN=BASELINE><TH ALIGN=RIGHT><FONT SIZE="-1">%s%s:</FONT><TT> </TT></TH>",
- par, header);
- par="";
- printf("<TD><TT>");
- /* showmsgrfc822_addressheader(value); */
- printf("%s", value);
- printf("</TT></TD></TR>n");
- }
- printf("</TABLE>n");
- }
- static int htmlfilter_stub(const char *ptr, size_t cnt, void *voidptr)
- {
- htmlfilter(ptr, cnt);
- return (0);
- }
- /* Recursive search for a Content-ID: header that we want */
- static struct rfc2045 *find_cid(struct rfc2045 *p, const char *cidurl)
- {
- const char *cid=rfc2045_content_id(p);
- if (cid && strcmp(cid, cidurl) == 0)
- return (p);
- for (p=p->firstpart; p; p=p->next)
- {
- struct rfc2045 *q;
- if (p->isdummy) continue;
- q=find_cid(p, cidurl);
- if (q) return (q);
- }
- return (0);
- }
- /*
- ** Given an rfc2045 ptr, return the mime reference that will resolve to
- ** this MIME part.
- */
- static char *rfc2mimeid(struct rfc2045 *p)
- {
- char buf[MAXLONGSIZE+1];
- char *q=0;
- unsigned n=p->pindex+1; /* mime counts start at one */
- char *r;
- if (p->parent)
- {
- q=rfc2mimeid(p->parent);
- if (p->parent->firstpart->isdummy)
- --n; /* ... except let's ignore the dummy part */
- }
- else n=1;
- sprintf(buf, "%u", n);
- r=malloc( (q ? strlen(q)+1:0)+strlen(buf)+1);
- if (!r) enomem();
- *r=0;
- if (q)
- {
- strcat(strcat(r, q), ".");
- free(q);
- }
- strcat(r, buf);
- return (r);
- }
- /*
- ** Convert cid: url to a http:// reference that will access the indicated
- ** MIME section.
- */
- static char *convertcid(const char *cidurl, void *voidp)
- {
- struct rfc2045 *rfc= (struct rfc2045 *)voidp;
- char *p;
- char *mimeid;
- char *q;
- const char *pos;
- if (rfc->parent) rfc=rfc->parent;
- rfc=find_cid(rfc, cidurl);
- if (!rfc) /* Not found, punt */
- {
- char *p=malloc(1);
- if (!p) enomem();
- *p=0;
- return (p);
- }
- p=scriptptrget();
- mimeid=rfc2mimeid(rfc);
- pos=cgi("pos");
- q=malloc(strlen(p)+strlen(mimeid)+strlen(pos) +
- sizeof("&pos=&form=fetch&mimeid="));
- if (!q) enomem();
- strcpy(q, p);
- strcat(q, "&form=fetch&pos=");
- strcat(q, pos);
- strcat(q, "&mimeid=");
- strcat(q, mimeid);
- free(p);
- free(mimeid);
- return (q);
- }
- static void showtexthtml(FILE *fp, struct rfc2045 *rfc, struct rfc2045id *id)
- {
- off_t start_pos, end_pos, start_body;
- char buf[512];
- int cnt;
- static const char redirect[]="?redirect=";
- const char *script_name=nonloginscriptptr();
- char *washpfix;
- char *washpfixmailto;
- char *scriptnameget=scriptptrget();
- static const char formbuf[]="&form=newmsg&to=";
- off_t dummy;
- char *content_base;
- id=id;
- if (!script_name) enomem();
- rfc2045_mimepos(rfc, &start_pos, &end_pos, &start_body, &dummy, &dummy);
- if (fseek(fp, start_body, SEEK_SET) < 0)
- {
- error("Seek error.");
- return;
- }
- washpfix=malloc(strlen(script_name) + sizeof(redirect));
- if (!washpfix) enomem();
- strcat(strcpy(washpfix, script_name), redirect);
- htmlfilter_washlink(washpfix);
- htmlfilter_convertcid(&convertcid, rfc);
- content_base=rfc2045_content_base(rfc);
- htmlfilter_contentbase(content_base);
- washpfixmailto=malloc(strlen(scriptnameget)+sizeof(formbuf));
- if (!washpfixmailto) enomem();
- strcat(strcpy(washpfixmailto, scriptnameget), formbuf);
- htmlfilter_washlinkmailto(washpfixmailto);
- htmlfilter_init(&text_to_stdout);
- printf("<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH="100%%"><TR><TD>n");
- rfc2045_cdecode_start(rfc, &htmlfilter_stub, 0);
- while (start_body < end_pos)
- {
- cnt=sizeof(buf);
- if (end_pos - start_body < cnt)
- cnt=end_pos - start_body;
- cnt=fread(buf, 1, cnt, fp);
- if (cnt <= 0) break;
- rfc2045_cdecode(rfc, buf, cnt);
- start_body += cnt;
- }
- rfc2045_cdecode_end(rfc);
- printf("</TD></TR></TABLE>n");
- free(washpfix);
- free(washpfixmailto);
- free(content_base);
- }
- static char *get_parent_folder(const char *p)
- {
- const char *q=strrchr(p, '.');
- char *s;
- if (!q)
- {
- s=strdup("");
- if (!s) enomem();
- return (s);
- }
- s=malloc(q-p+1);
- if (!s) enomem();
- memcpy(s, p, q-p);
- s[q-p]=0;
- return (s);
- }
- void folder_list()
- {
- char **folders;
- size_t i;
- unsigned nnew, nother;
- char *args=strdup(form_args);
- char *unread_label;
- char *err_invalid;
- char *err_exists;
- char *err_cantdelete;
- char *msg_hasbeensent;
- char *name_inbox;
- char *name_drafts;
- char *name_sent;
- char *name_trash;
- char *folder_img;
- char *folders_img;
- const char *folderdir;
- if (!args) return;
- unread_label=strtok(args, "|");
- err_invalid=strtok(NULL, "|");
- err_exists=strtok(NULL, "|");
- err_cantdelete=strtok(NULL, "|");
- msg_hasbeensent=strtok(NULL, "|");
- name_inbox=strtok(NULL, "|");
- name_drafts=strtok(NULL, "|");
- name_sent=strtok(NULL, "|");
- name_trash=strtok(NULL, "|");
- folder_img=strtok(NULL, "|");
- folders_img=strtok(NULL, "|");
- if (!unread_label) unread_label="";
- if (!err_invalid) err_invalid="";
- if (!err_exists) err_exists="";
- if (!err_cantdelete) err_cantdelete="";
- if (!name_inbox) name_inbox="";
- if (!name_drafts) name_drafts="";
- if (!name_sent) name_sent="";
- if (!name_trash) name_trash="";
- if (!folder_img) folder_img="";
- if (!folders_img) folders_img="";
- if (folder_err_msg)
- free(folder_err_msg);
- folder_err_msg=0;
- if (strcmp(cgi("foldermsg"), "sent") == 0)
- folder_err_msg=msg_hasbeensent;
- if (strcmp(cgi("cmd"), "newfolder") == 0)
- {
- const char *newfoldername=cgi("foldername");
- const char *newdirname=cgi("dirname");
- const char *folderdir=cgi("folderdir");
- /*
- ** New folder names cannot contain :s, and must be considered
- ** as valid by maildir_folderpath.
- */
- if (!*newfoldername ||
- strchr(newfoldername, '.') ||
- strchr(newdirname, '.'))
- folder_err_msg=err_invalid;
- {
- char *p=malloc(strlen(folderdir)+strlen(newfoldername)
- +strlen(newdirname)+2);
- if (!p) enomem();
- strcpy(p, folderdir);
- if (*newdirname)
- {
- if (*p) strcat(p, ".");
- strcat(p, newdirname);
- }
- if (*p) strcat(p, ".");
- strcat(p, newfoldername);
- if (strchr(p, ':'))
- {
- free(p);
- folder_err_msg=err_invalid;
- }
- else
- {
- char *q=maildir_folderdir(0, p);
- if (!q)
- folder_err_msg=err_invalid;
- else
- {
- free(q);
- if (maildir_create(p))
- folder_err_msg=err_exists;
- }
- free(p);
- }
- }
- }
- if (*cgi("do.delete"))
- {
- const char *p=cgi("DELETE");
- char *pp=strdup(p);
- if (pp && strchr(pp, ':') == 0)
- {
- if (maildir_delete(pp))
- folder_err_msg=err_cantdelete;
- free(pp);
- }
- }
- if (*cgi("do.subunsub"))
- {
- const char *p=cgi("DELETE");
- char *pp=strdup(p);
- char *d;
- if (pp && *pp == ':' &&
- (d=maildir_shareddir(".", pp+1)) != 0)
- {
- if (access(d, 0) == 0)
- maildir_shared_unsubscribe(".", pp+1);
- else
- maildir_shared_subscribe(".", pp+1);
- free(d);
- }
- if (pp)
- free(pp);
- }
- if (*cgi("do.rename"))
- {
- const char *p=cgi("DELETE");
- char *pp=strdup(p);
- if (pp && strchr(pp, ':') == 0)
- {
- const char *q=cgi("renametofolder");
- const char *r=cgi("renametoname");
- char *s=malloc(strlen(q)+strlen(r)+1);
- char *t;
- if (!s) enomem();
- *s=0;
- if (strchr(q, '.'))
- strcpy(s, q);
- strcat(s, r);
- if (strchr(s, ':') || (t=maildir_folderdir(0, s)) == 0)
- folder_err_msg=err_invalid;
- else
- {
- if (access(t, 0) == 0)
- folder_err_msg=err_exists;
- else
- {
- if (maildir_rename(pp, s))
- folder_err_msg=err_cantdelete;
- }
- free(t);
- }
- free(pp);
- free(s);
- }
- }
- if (folder_err_msg)
- {
- char *p=malloc(strlen(folder_err_msg)+1);
- if (!p) enomem();
- strcpy(p, folder_err_msg);
- folder_err_msg=p;
- }
- sqwebmail_folder=0;
- folderdir=cgi("folderdir");
- printf("<TABLE WIDTH="100%%" BORDER=0 CELLPADDING=2 CELLSPACING=0 BGCOLOR="#FFFFC0">n");
- maildir_readfolders(&folders);
- if (*folderdir)
- {
- char *parentfolder=get_parent_folder(folderdir);
- size_t i;
- printf("<TR><TD ALIGN=LEFT COLSPAN=2 BGCOLOR="#EEEE80">%s<<< <A HREF="", folders_img);
- output_scriptptrget();
- printf("&form=folders&folder=INBOX">");
- print_safe(name_inbox);
- printf("</A>");
- i=0;
- while (parentfolder[i])
- {
- char *p=strchr(parentfolder+i, '.');
- int c;
- if (!p) p=parentfolder+strlen(parentfolder);
- c= *p;
- *p=0;
- printf(".<A HREF="");
- output_scriptptrget();
- printf("&form=folders&folder=INBOX&folderdir=");
- output_urlencoded(parentfolder);
- printf("">");
- print_safe(parentfolder+i);
- printf("</A>");
- if ( (*p=c) != 0) ++p;
- i=p-parentfolder;
- }
- printf("</TD></TR>n");
- free(parentfolder);
- }
- for (i=0; folders[i]; i++)
- {
- const char *p;
- const char *shortname=folders[i];
- size_t j;
- const char *pfix=0;
- int isshared=0;
- int isunsubscribed=0;
- char *img=folder_img;
- if (*shortname == ':') /* Shared folders */
- {
- char *dir;
- isshared=1;
- pfix="+++";
- dir=maildir_shareddir(".", shortname+1);
- if (!dir) continue;
- if (access(dir, 0))
- isunsubscribed=1;
- free(dir);
- }
- if (*folderdir)
- {
- unsigned l=strlen(folderdir);
- if (memcmp(shortname, folderdir, l) ||
- shortname[l] != '.') continue;
- shortname += l;
- ++shortname;
- pfix=0;
- }
- if (!pfix)
- {
- pfix=">>>";
- }
- if ((p=strchr(shortname, '.')) != 0)
- {
- char *s=malloc(p+1-folders[i]), *t;
- unsigned tot_nnew, tot_nother;
- if (!s) enomem();
- memcpy(s, folders[i], p-folders[i]);
- s[p-folders[i]]=0;
- img=folders_img;
- printf("<TR BGCOLOR="#EEEE80"><TD ALIGN=LEFT>%s%s <A HREF="", img, pfix);
- output_scriptptrget();
- printf("&form=folders&folder=INBOX&folderdir=");
- output_urlencoded(s);
- printf("">");
- free(s);
- t=malloc(p-shortname+1);
- if (!t) enomem();
- memcpy(t, shortname, p-shortname);
- t[p-shortname]=0;
- print_safe(isshared ? t+1:t);
- free(t);
- printf("</A>");
- tot_nnew=0;
- tot_nother=0;
- j=i;
- while (folders[j] && memcmp(folders[j], folders[i],
- p-folders[i]+1) == 0)
- {
- maildir_count(folders[j], &nnew, ¬her);
- ++j;
- tot_nnew += nnew;
- tot_nother += nother;
- }
- i=j-1;
- if (tot_nnew)
- {
- printf(" <FONT COLOR="#800000" SIZE="-1">");
- printf(unread_label, tot_nnew);
- printf(end_font);
- }
- printf("</TD><TD ALIGN=RIGHT VALIGN=TOP>%s%d%s </TD></TR>nn",
- black_color, tot_nnew + tot_nother, end_font);
- continue;
- }
- nnew=0;
- nother=0;
- if (!isunsubscribed)
- maildir_count(folders[i], &nnew, ¬her);
- printf("<TR %s><TD ALIGN=LEFT VALIGN=TOP>",
- isunsubscribed ? "BGCOLOR="#DDDD80"":"");
- printf("%s<INPUT BORDER=0 TYPE="radio" NAME="DELETE" VALUE="", img);
- output_attrencoded(folders[i]);
- printf(""> ");
- if (!isunsubscribed)
- {
- printf("<A HREF="");
- output_scriptptrget();
- printf("&form=folder&folder=");
- output_urlencoded(folders[i]);
- printf("">");
- }
- if (strcmp(folders[i], INBOX) == 0)
- shortname=name_inbox;
- else if (strcmp(folders[i], DRAFTS) == 0)
- shortname=name_drafts;
- else if (strcmp(folders[i], TRASH) == 0)
- shortname=name_trash;
- else if (strcmp(folders[i], SENT) == 0)
- shortname=name_sent;
- print_safe(shortname);
- if (!isunsubscribed)
- printf("</A>");
- if (nnew)
- {
- printf(" <FONT COLOR="#800000" SIZE="-1">");
- printf(unread_label, nnew);
- printf(end_font);
- }
- printf("</TD><TD ALIGN=RIGHT VALIGN=TOP>");
- if (!isunsubscribed)
- {
- printf("%s%d%s ",
- black_color, nnew + nother, end_font);
- }
- else
- printf(" n");
- printf("</TD></TR>nn");
- }
- maildir_freefolders(&folders);
- printf("</TABLE>n");
- free(args);
- }
- void folder_list2()
- {
- if (folder_err_msg)
- {
- printf("<P><FONT COLOR="FF0000" SIZE="+1">%s%s<BR><BR>n",
- folder_err_msg, end_font);
- }
- }
- void folder_rename_list()
- {
- char **folders;
- int i;
- printf("<select name="renametofolder">n");
- printf("<option value="%s">", INBOX);
- printf("( ... )");
- printf("</option>n");
- maildir_readfolders(&folders);
- for (i=0; folders[i]; i++)
- {
- const char *p=folders[i];
- char *q;
- size_t ql;
- if (*p == ':') continue; /* Omit shared hierarchy */
- p=strrchr(folders[i], '.');
- if (!p) continue;
- q=malloc(p-folders[i]+1);
- if (!q) enomem();
- memcpy(q, folders[i], p-folders[i]);
- q[p-folders[i]]=0;
- printf("<OPTION VALUE="");
- output_attrencoded(q);
- printf("." %s>",
- strcmp(q, cgi("folderdir")) == 0 ? "SELECTED":"");
- output_attrencoded(q);
- printf(".</OPTION>n");
- ql=strlen(q);
- while (folders[++i])
- {
- if (memcmp(folders[i], q, ql) ||
- folders[i][ql] != '.' ||
- strchr(folders[i]+ql+1, '.')) break;
- }
- --i;
- free(q);
- }
- maildir_freefolders(&folders);
- printf("</select>n");
- }
- static int download_func(const char *, size_t, void *);
- void disposition_attachment(FILE *fp, const char *p)
- {
- fprintf(fp, "Content-Disposition: attachment; filename="");
- while (*p)
- {
- if (*p == '"' || *p == '\')
- putc('\', fp);
- if (!ISCTRL(*p))
- putc(*p, fp);
- p++;
- }
- fprintf(fp, ""n");
- }
- void folder_download(const char *folder, size_t pos, const char *mimeid)
- {
- char *filename;
- struct rfc2045 *rfc, *part;
- char buf[BUFSIZ];
- int n,cnt;
- const char *content_type, *dummy, *charset;
- off_t start_pos, end_pos, start_body;
- FILE *fp;
- const char *content_name;
- off_t ldummy;
- const char *disposition_s;
- const char *disposition_name_s;
- const char *disposition_filename_s;
- int fd;
- filename=maildir_posfind(folder, &pos);
- if (!filename) error("Message not found.");
- fp=0;
- fd=maildir_semisafeopen(filename, O_RDONLY, 0);
- if (fd >= 0)
- {
- if ((fp=fdopen(fd, "r")) == 0)
- close(fd);
- }
- if (!fp)
- {
- free(filename);
- error("Message not found.");
- return;
- }
- free(filename);
- rfc=rfc2045_alloc();
- while ((n=fread(buf, 1, sizeof(buf), fp)) > 0)
- rfc2045_parse(rfc, buf, n);
- part=rfc2045_find(rfc, mimeid);
- if (!part) error("Message not found.");
- rfc2045_mimeinfo(part, &content_type, &dummy, &charset);
- rfc2045_dispositioninfo(part, &disposition_s, &disposition_name_s,
- &disposition_filename_s);
- cginocache();
- content_name=rfc2045_contentname(part);
- if (*cgi("download") == '1')
- {
- const char *p=disposition_filename_s;
- if (!p || !*p) p=content_name;
- if (!p || !*p) p="message.dat";
- disposition_attachment(stdout, p);
- content_type="application/octet-stream";
- }
-
- printf(
- *content_name ?
- "Content-Type: %s; charset="%s"; name="%s"nn":
- "Content-Type: %s; charset="%s"nn",
- content_type, charset, content_name);
- rfc2045_mimepos(part, &start_pos, &end_pos, &start_body,
- &ldummy, &ldummy);
- if (fseek(fp, start_body, SEEK_SET) < 0)
- {
- error("Seek error.");
- return;
- }
- rfc2045_cdecode_start(part, &download_func, 0);
- while (start_body < end_pos)
- {
- cnt=sizeof(buf);
- if (cnt > end_pos-start_body)
- cnt=end_pos-start_body;
- cnt=fread(buf, 1, cnt, fp);
- if (cnt <= 0) break;
- start_body += cnt;
- rfc2045_cdecode(part, buf, cnt);
- }
- rfc2045_cdecode_end(part);
- fclose(fp);
- }
- static int download_func(const char *p, size_t cnt, void *voidptr)
- {
- while (cnt--)
- if (putchar(*p++) == EOF)
- {
- cleanup();
- fake_exit(0);
- }
- return (0);
- }
- void folder_showtransfer()
- {
- char *p;
- char *deletelab, *purgelab, *movelab, *golab;
- p=strdup(form_args);
- if (!p) return;
- (void)strtok(p, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- deletelab=strtok(0, "|");
- purgelab=strtok(0, "|");
- movelab=strtok(0, "|");
- golab=strtok(0, "|");
- if (!deletelab) deletelab="";
- if (!purgelab) purgelab="";
- if (!movelab) movelab="";
- if (!golab) golab="";
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- (void)strtok(0, "|");
- folder_inbox=strtok(NULL, "|");
- folder_drafts=strtok(NULL, "|");
- folder_trash=strtok(NULL, "|");
- folder_sent=strtok(NULL, "|");
- printf("<INPUT TYPE=HIDDEN NAME=pos VALUE=%s>", cgi("pos"));
- printf("<INPUT TYPE=SUBMIT NAME=cmddel VALUE="%s">%s%s%s<SELECT NAME=moveto>",
- strcmp(sqwebmail_folder, TRASH) == 0
- ? purgelab:deletelab,
- black_color, movelab, end_font);
- show_transfer_dest(sqwebmail_folder);
- printf("</SELECT><INPUT TYPE=SUBMIT NAME=cmdmove VALUE="%s">n",
- golab);
- }
- void
- folder_cleanup()
- {
- msg_purgelab=0;
- msg_folderlab=0;
- folder_drafts=0;
- folder_inbox=0;
- folder_sent=0;
- folder_trash=0;
- msg_badcontenttype=0;
- msg_dispattachment=0;
- msg_downattachment=0;
- msg_forwardattlab=0;
- msg_forwardlab=0;
- msg_fullheaderlab=0;
- msg_golab=0;
- msg_movetolab=0;
- msg_nextlab=0;
- msg_prevlab=0;
- msg_deletelab=0;
- msg_posfile=0;
- msg_replyalllab=0;
- msg_replylab=0;
- folder_err_msg=0;
- msg_msglab=0;
- msg_type=0;
- initnextprevcnt=0;
- msg_hasprev=0;
- msg_hasnext=0;
- msg_pos=0;
- msg_count=0;
- }