#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>

#include "globals.h"
#include "decode.h"
#include "ckm.h"

int mailfrom(char *buf, int bsize)
{
    FILE *p;
    char tmpp[201], *ki;
// szukaj zdefiniowanej
    snprintf(tmpp, sizeof(tmpp), "%s/wap-mailname", home);
    if ((p = fopen(tmpp, "r"))) {
	fgets(buf, bsize - 1, p);
	fclose(p);

	ki = (char *) index(buf, 10);
	if (ki != NULL)
	    ki[0] = 0;
	ki = (char *) index(buf, 13);
	if (ki != NULL)
	    ki[0] = 0;

	if (strlen(buf) > 0)
	    return 1;
    }

// jesli jej nie ma to szukaj w /etc/mailname
    if ((p = fopen("/etc/mailname", "r"))) {
	fgets(tmpp, bsize - 1, p);
	fclose(p);

	ki = (char *) index(tmpp, 10);
	if (ki != NULL)
	    ki[0] = 0;
	ki = (char *) index(tmpp, 13);
	if (ki != NULL)
	    ki[0] = 0;

	if ((strlen(logname) + strlen(tmpp) + 2) < bsize) {
	    snprintf(buf, bsize, "%s@%s", logname, tmpp);
	    if (strlen(buf) > 1)
		return 1;
	}
    }
// no mailname no mail
    memset(&buf, 0, sizeof(buf));
    return 0;
}

/*
Sprawdzanie mailboxa i maildira
mailboxpath/maildirpath - sciezka do skrytki
mailboxname/maildirname - nazwa skrytki
outbuf - bufor wyjsciowy
cmd - komenda
  0 - wyswietl krotki raport skrytki
  1 - lista wszystkich maili
  2 - lista nowych maili
  3 - wyswietl dany mail (tresc)
ofs - od ktorego maila dla listy, lub ktory mail
ile - ile maili
emails - ilosc nowych emaili narastajaco
*/

int wap_ckmdir(char *maildirpath, char *maildirname, char *outbuf, int sizeofoutbuf, int cmd, int ofs, int ile, int *emails, int nopl, int xe_count)
{
    char name[20], tmppath[300];
    struct dirent **namelist;
    int ileold, ilenew, n;

    if (cmd == 0) {
	snprintf(name, sizeof(name), "%.19s", maildirname);
	snprintf(tmppath, sizeof(tmppath), "%snew", maildirpath);
//    printf("%s\n",tmppath);
	ilenew = scandir(tmppath, &namelist, 0, alphasort);
	n = ilenew;
	if (ilenew < 0)
	    return 0;
	else
	    while (--n) {
		free(namelist[n - 1]);
	    }
	free(namelist);
	ilenew -= 2;
	snprintf(tmppath, sizeof(tmppath), "%scur", maildirpath);
//    printf("%s\n",tmppath);
	ileold = scandir(tmppath, &namelist, 0, alphasort);
	n = ileold;
	if (ilenew < 0)
	    return 0;
	else
	    while (--n) {
		free(namelist[n - 1]);
	    }
	free(namelist);
	ileold -= 2;
	snprintf(outbuf, sizeofoutbuf,
		 "<p>%s: <a href=\"?c=mail;n=%s;t=10\">%d</a> new <a href=\"?c=mail;n=%s;t=20\">%d</a></p>", name, name, ileold, name, ilenew);
	emails[0] += ilenew;
	return 1;
    }
    if (cmd == 1 || cmd == 2 || cmd == 3 || cmd == 4) {
	int k, head, maili = 0, nowy, quotedp, boundaryhead, textct, read;
	FILE *p;
	char buf[501], odkogo[500], subiect[500], *ki, tmpp[500], returnpath[500], returnpath2[201];
	snprintf(name, sizeof(name), "%.19s", maildirname);
	if (cmd == 1 || cmd == 4) {
	    snprintf(tmppath, sizeof(tmppath), "%scur", maildirpath);
	    nowy = 0;
	}
	else {
	    snprintf(tmppath, sizeof(tmppath), "%snew", maildirpath);
	    nowy = 1;
	}
	outbuf[0] = 0;
	n = scandir(tmppath, &namelist, 0, alphasort);
	k = n;
	if (n < 0)
	    return 0;
	else
	    while (n--) {
		if (namelist[k - n - 1]->d_name[0] != '.') {
		    head = 1;
		    quotedp = 0;
		    boundaryhead = 0;
		    textct = 1;
		    read = 0;
		    snprintf(tmpp, sizeof(tmpp), "%s/%s", tmppath, namelist[k - n - 1]->d_name);
		    if ((p = fopen(tmpp, "r"))) {
			maili++;
			if ((cmd == 3 || cmd == 4) && maili == ofs) {
			    // odczyt tego wlasnie maila
			    memset(&subiect, 0, sizeof(subiect));
			    memset(&odkogo, 0, sizeof(odkogo));
			    while (fgets(buf, 501, p)) {
				ki = (char *) index(buf, 10);
				if (ki != NULL)
				    ki[0] = 0;
				ki = (char *) index(buf, 13);
				if (ki != NULL)
				    ki[0] = 0;

				if (strncmp(buf, "From: ", 6) == 0 && head == 1) {
				    snprintf(odkogo, sizeof(odkogo), "%.499s", buf + 6);
				}
				else if (strncmp(buf, "Return-Path: <", 14)
					 == 0 && head == 1) {
				    snprintf(returnpath, sizeof(returnpath), "%s", buf + 14);
				    if (strlen(returnpath) > 1)
					returnpath[strlen(returnpath) - 1] = 0;
				}
				else if (head == 1 && strncmp(buf, "Subject: ", 9) == 0) {
				    if (strlen(buf + 9) > 0)
					snprintf(subiect, sizeof(subiect), "%.499s", buf + 9);
				    else
					snprintf(subiect, sizeof(subiect), "none");
				}
				else if ((strncmp(buf, "Content-Transfer-Encoding: ", 27) == 0) && (head == 1 || boundaryhead == 1)) {
				    if (strstr(buf, "quoted-printable") != 0 || strstr(buf, "QUOTED-PRINTABLE") != 0)
					quotedp = 1;
				    else
					quotedp = 0;
				}
				else if (head == 1 && strlen(buf) == 0) {
				    head = 0;
				    snprintf(returnpath2, sizeof(returnpath2), "%.200s", returnpath);
				    decodesubiect(odkogo, 499);
				    dozwolonys(odkogo, sizeof(odkogo), 1, 0, 0, nopl, xe_count);
				    decodesubiect(subiect, 499);
				    dozwolonys(subiect, sizeof(subiect), 1, 0, 0, nopl, xe_count);
				    snprintf(outbuf + strlen(outbuf),
					     sizeofoutbuf - strlen(outbuf),
					     "<p>%s<b>%d %s</b></p><p><u>%s</u></p><p>", (nowy == 1) ? "N " : "", maili, odkogo, subiect);
				    read = 1;
				}
				else if (head == 0 && boundaryhead == 0 && textct == 1) {
				    if (quotedp == 1)
					decodeqp(buf, 4999);
				    dozwolonys(buf, sizeof(buf), 1, 0, 0, nopl, xe_count);
				    if ((strlen(outbuf) + strlen(buf)) < 2500)
					snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf), "<br/>%s", buf);
				}

			    }
			    if (read == 1)
				snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf), "</p>");
			}

			if ((cmd == 1 || cmd == 2) && maili >= ofs && maili < (ofs + ile)) {
			    // odczyt glowek
			    memset(&subiect, 0, sizeof(subiect));
			    memset(&odkogo, 0, sizeof(odkogo));
			    while (fgets(buf, 501, p)) {
				ki = (char *) index(buf, 10);
				if (ki != NULL)
				    ki[0] = 0;
				ki = (char *) index(buf, 13);
				if (ki != NULL)
				    ki[0] = 0;

				if (strncmp(buf, "From: ", 6) == 0 && head == 1) {
				    snprintf(odkogo, sizeof(odkogo), "%.499s", buf + 6);
				}
				else if (head == 1 && strncmp(buf, "Subject: ", 9) == 0) {
				    if (strlen(buf + 9) > 0)
					snprintf(subiect, sizeof(subiect), "%.499s", buf + 9);
				    else
					snprintf(subiect, sizeof(subiect), "none");
				}
				else if (head == 1 && strlen(buf) == 0) {
				    head = 0;
				    decodesubiect(odkogo, 499);
				    dozwolonys(odkogo, sizeof(odkogo), 1, 0, 0, nopl, xe_count);
				    decodesubiect(subiect, 499);
				    dozwolonys(subiect, sizeof(subiect), 1, 0, 0, nopl, xe_count);

				    snprintf(outbuf + strlen(outbuf),
					     sizeofoutbuf - strlen(outbuf),
					     "<p>%s<b><a href=\"?c=mail;n=%s;t=%d%d\">%d</a> %s</b></p><p>%s</p>",
					     (nowy == 1) ? "N " : "", name, (nowy == 1) ? 3 : 4, maili, maili, odkogo, subiect);
				}
			    }
			    //show
			}
			fclose(p);
		    }
		}
		free(namelist[k - n - 1]);
	    }
	free(namelist);

	if (cmd == 1 || cmd == 2)
	    snprintf(outbuf + strlen(outbuf),
		     sizeofoutbuf - strlen(outbuf),
		     "<do type=\"next\" label=\"next\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		     "<do type=\"back\" label=\"back\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		     "<do type=\"last\" label=\"last\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		     "<do type=\"prev\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>"
		     "<do type=\"Mailbox list\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>",
		     name, cmd, ofs + 10, name, cmd, ((ofs - 10) > 0) ? ofs - 10 : 0, name, cmd, ((maili - 9) > 0) ? maili - 9 : 0);
	if (cmd == 3 || cmd == 4)
	    snprintf(outbuf + strlen(outbuf),
		     sizeofoutbuf - strlen(outbuf),
		     "<do type=\"reply\" label=\"reply\"><go href=\"?c=newmail;n=%s;t=0\"/></do>"
		     "<do type=\"next\" label=\"next\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		     "<do type=\"previous\" label=\"previous\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		     "<do type=\"Mailbox\" label=\"Mailbox\"><go href=\"?c=mail;n=%s;t=1%d\"/></do>"
		     "<do type=\"prev\" label=\"Mailbox\"><go href=\"?c=mail;n=%s;t=1%d\"/></do>"
		     "<do type=\"Mailbox list\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>",
		     returnpath2, name, cmd,
		     (ofs != maili) ? ofs + 1 : ofs, name, cmd, (ofs > 1) ? ofs - 1 : 1, name, (ofs > 4) ? ofs - 4 : 1, name, (ofs > 4) ? ofs - 4 : 1);
	return 1;
    }
    return 0;
}

int wap_ckm(char *mailboxpath, char *mailboxname, char *outbuf, int sizeofoutbuf, int cmd, int ofs, int ile, int *emails, int nopl, int xe_count)
{
    FILE *f;
    char buf[5000], *k, odkogo[500], name[20], subiect[500], returnpath[201], boundary[500], parttype[500];
    char returnpath2[201];
    int head = 0, read = 0, quotedp = 0, boundaryhead = 0;
    int maili = 0, body = 0, readed = 0, unread = 0, nowy = 0, textct = 0, wskhtml = 1;

    snprintf(name, sizeof(name), "%.19s", mailboxname);

    if (!(f = fopen(mailboxpath, "r")))
	return 0;

    outbuf[0] = 0;

    while (fgets(buf, 501, f)) {
	k = (char *) index(buf, 10);
	if (k != NULL)
	    k[0] = 0;
	k = (char *) index(buf, 13);
	if (k != NULL)
	    k[0] = 0;

	if (strncmp(buf, "From ", 5) == 0 && head == 0) {
	    head = 1;
	    maili++;
	    nowy = 1;
	    read = 0;
	    quotedp = 0;
	    textct = 1;
	    wskhtml = 1;
	    snprintf(boundary, sizeof(boundary), "serekserekserekserekserek");
	    memset(&subiect, 0, sizeof(subiect));
	    memset(&returnpath, 0, sizeof(returnpath));
	}
	else if (strncmp(buf, "Return-Path: <", 14) == 0 && head == 1 && cmd == 3) {
	    snprintf(returnpath, sizeof(returnpath), "%s", buf + 14);
	    if (strlen(returnpath) > 1)
		returnpath[strlen(returnpath) - 1] = 0;
	}
	else if (strncmp(buf, "From: ", 6) == 0 && head == 1) {
	    snprintf(odkogo, sizeof(odkogo), "%.499s", buf + 6);
	}
	else if (strlen(buf) == 0 && head == 1) {
	    if (nowy == 1)
		unread++;
	    // tu sie zaczyna tresc
	    if (cmd == 1 && ofs <= maili && (ofs + ile) > maili) {
		decodesubiect(odkogo, 499);
		dozwolonys(odkogo, sizeof(odkogo), 1, 0, 0, nopl, xe_count);
		decodesubiect(subiect, 499);
		dozwolonys(subiect, sizeof(subiect), 1, 0, 0, nopl, xe_count);
		snprintf(outbuf + strlen(outbuf),
			 sizeofoutbuf - strlen(outbuf),
			 "<p>%s<b><a href=\"?c=mail;n=%s;t=3%d\">%d</a> %s</b></p><p>%s</p>", (nowy == 1) ? "N " : "", name, maili, maili, odkogo, subiect);
	    }
	    else if (cmd == 2 && nowy == 1 && ofs <= unread && (ofs + ile) > unread) {
		decodesubiect(odkogo, 499);
		dozwolonys(odkogo, sizeof(odkogo), 1, 0, 0, nopl, xe_count);
		decodesubiect(subiect, 499);
		dozwolonys(subiect, sizeof(subiect), 1, 0, 0, nopl, xe_count);
		snprintf(outbuf + strlen(outbuf),
			 sizeofoutbuf - strlen(outbuf),
			 "<p>N <b><a href=\"?c=mail;n=%s;t=3%d\">%d</a> %s</b></p><p>%s</p>", name, maili, maili, odkogo, subiect);
	    }
	    if (cmd == 3 && ofs == maili) {
		decodesubiect(odkogo, 499);
		dozwolonys(odkogo, sizeof(odkogo), 1, 0, 0, nopl, xe_count);
		decodesubiect(subiect, 499);
		dozwolonys(subiect, sizeof(subiect), 1, 0, 0, nopl, xe_count);
		snprintf(returnpath2, sizeof(returnpath2), "%.200s", returnpath);
		snprintf(outbuf + strlen(outbuf),
			 sizeofoutbuf - strlen(outbuf), "<p>%s<b>%d %s</b></p><p><u>%s</u></p><p>", (nowy == 1) ? "N " : "", maili, odkogo, subiect);
		read = 1;
	    }
	    head = 0;
	    body++;
	    nowy = 0;
	}
	else if ((head == 1 || boundaryhead == 1)
		 && strncasecmp(buf, "Content-Type: ", 14) == 0) {
	    if (strncasecmp(buf, "Content-Type: text/html", 23) == 0)
		textct = 2;
	    else if (strncasecmp(buf, "Content-Type: text/", 19) == 0)
		textct = 1;
	    else
		textct = 0;

	    snprintf(parttype, sizeof(parttype), "%.499s", buf + 14);
	    wskhtml = 1;

//czasami boundary jest w tej samej linii co content-type
	    if (cmd == 3 && head == 1 && (strstr(buf, "boundary=") != 0 || strstr(buf, "BOUNDARY=") != 0)) {
		char *k;
		//wiadomosc wieloczesciowa
		if (strstr(buf, "boundary=") != 0)
		    snprintf(boundary, sizeof(boundary), "--%.490s", strstr(buf, "boundary=") + 10);
		else
		    snprintf(boundary, sizeof(boundary), "--%.490s", strstr(buf, "BOUNDARY=") + 10);
		k = (char *) index(boundary, '"');
		if (k != NULL)
		    k[0] = 0;
	    }
	}
	else if (strlen(buf) == 0 && head == 0 && boundaryhead == 1) {
	    if (textct == 0)
		snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf), "<br/>Cannot display this part: %s", parttype);
	    boundaryhead = 0;
	}
	else if ((strncmp(buf, "Content-Transfer-Encoding: ", 27) == 0)
		 && (head == 1 || boundaryhead == 1)) {
	    if (strstr(buf, "quoted-printable") != 0 || strstr(buf, "QUOTED-PRINTABLE") != 0)
		quotedp = 1;
	    else
		quotedp = 0;
	}
	else if (cmd == 3 && head == 1 && (strstr(buf, "boundary=") != 0 || strstr(buf, "BOUNDARY=") != 0)) {
	    char *k;
	    //wiadomosc wieloczesciowa
	    if (strstr(buf, "boundary=") != 0)
		snprintf(boundary, sizeof(boundary), "--%.490s", strstr(buf, "boundary=") + 10);
	    else
		snprintf(boundary, sizeof(boundary), "--%.490s", strstr(buf, "BOUNDARY=") + 10);
	    k = (char *) index(boundary, '"');
	    if (k != NULL)
		k[0] = 0;
	}
	else if (read == 1 && head == 0 && strcmp(buf, boundary) == 0) {
//      printf("\nnext part\n");
	    boundaryhead = 1;
	    textct = 1;
	    wskhtml = 1;
	}
	else if (head == 0 && read == 1 && boundaryhead == 0 && textct != 0) {
	    if (quotedp == 1)
		decodeqp(buf, 4999);

	    if (textct == 1)
		dozwolonys(buf, sizeof(buf), 1, 0, 0, nopl, xe_count);
	    else
		wskhtml = dozwolonys(buf, sizeof(buf), 3 - wskhtml, 0, 0, nopl, xe_count);

	    if ((strlen(outbuf) + strlen(buf)) < (sizeofoutbuf - 300))
		snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf), "<br/>%s", buf);
	}
	else if (head == 1 && strncmp(buf, "Status:", 7) == 0) {
	    if (index(buf, 'R') != 0) {
		readed++;
		nowy = 0;
	    }
	    else
		nowy = 1;
	}
	else if (head == 1 && strncmp(buf, "Subject: ", 9) == 0) {
	    if (strlen(buf + 9) > 0)
		snprintf(subiect, sizeof(subiect), "%.499s", buf + 9);
	    else
		snprintf(subiect, sizeof(subiect), "none");
	}
    }
    fclose(f);

    if (cmd == 3)
	snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf),
		 "</p>"
		 "<do type=\"reply\" label=\"reply\"><go href=\"?c=newmail;n=%s;t=0\"/></do>"
		 "<do type=\"next\" label=\"next\"><go href=\"?c=mail;n=%s;t=3%d\"/></do>"
		 "<do type=\"previous\" label=\"previous\"><go href=\"?c=mail;n=%s;t=3%d\"/></do>"
		 "<do type=\"Mailbox\" label=\"Mailbox\"><go href=\"?c=mail;n=%s;t=1%d\"/></do>"
		 "<do type=\"prev\" label=\"Mailbox\"><go href=\"?c=mail;n=%s;t=1%d\"/></do>"
		 "<do type=\"Mailbox list\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>",
		 returnpath2, name, (ofs != maili) ? ofs + 1 : ofs, name,
		 (ofs > 1) ? ofs - 1 : 1, name, (ofs > 4) ? ofs - 4 : 1, name, (ofs > 4) ? ofs - 4 : 1);
    if (cmd == 0)
	snprintf(outbuf, sizeofoutbuf,
		 "<p>%s: <a href=\"?c=mail;n=%s;t=10\">%d</a> new <a href=\"?c=mail;n=%s;t=20\">%d</a></p>", name, name, maili, name, unread);
    if (cmd == 1 || cmd == 2) {
	snprintf(outbuf + strlen(outbuf), sizeofoutbuf - strlen(outbuf),
		 "<do type=\"next\" label=\"next\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		 "<do type=\"back\" label=\"back\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		 "<do type=\"last\" label=\"last\"><go href=\"?c=mail;n=%s;t=%d%d\"/></do>"
		 "<do type=\"prev\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>"
		 "<do type=\"Mailbox list\" label=\"Mailbox list\"><go href=\"?c=mail;n=0;t=0\"/></do>",
		 name,
		 cmd,
		 ofs + 10,
		 name, cmd, ((ofs - 10) > 0) ? ofs - 10 : 0, name, cmd, (cmd == 1) ? (((maili - 9) > 0) ? maili - 9 : 0) : (((unread - 9) > 0) ? unread - 9 : 0)
	    );
    }
    emails[0] += unread;
    return 1;
}
