/* $Cambridge: hermes/src/prayer/cmd/cmd_rawdisplay.c,v 1.2 2008/05/19 15:55:54 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2008 */
/* See the file NOTICE for conditions of use and distribution. */

#include "prayer_session.h"

void cmd_rawdisplay(struct session *session)
{
    struct options *options = session->options;
    struct prefs *prefs = options->prefs;
    struct request *request = session->request;
    struct buffer *b = request->write_buffer;
    MAILSTREAM *stream = session->stream;
    unsigned long msgno, msguid;
    char *section, *name, *type;
    char *init_msg;
    unsigned char *decode_msg;
    unsigned long len;
    BODY *body;
    unsigned long i;

    if (request->argc < 6) {
        /* User playing silly buggers, or hit browser back button after
           asynchronous rawdisplay event */
        session_redirect(session, request, "display");
        return;
    }

    msgno = atoi(request->argv[1]);
    msguid = atoi(request->argv[2]);

    if (!(msgno = stream_check_uid(session, stream, msgno, msguid))) {
        session_redirect(session, request, "list");
        return;
    }

    section = request->argv[3];
    type = request->argv[4];
    name = request->argv[5];

    string_url_decode(type);
    string_url_decode(name);

    if (!prefs->preserve_mimetype)
        type = "application/octet-stream";

    if (!ml_fetch_structure(session, stream, msgno, &body, NIL)) {
        session_redirect(session, request, "restart");
        return;
    }

    /* Tranlate section "0" -> main body */
    if (section && !strcmp(section, "0"))
        section = "1";

    if (!(body = ml_body(session, stream, msgno, section))) {
        session_redirect(session, request, "restart");
        return;
    }

    if ((body->type == TYPEMESSAGE) || (body->type == TYPEMULTIPART)) {
        char *hdrs, *msg;
        unsigned long hlen, len;

        hdrs = ml_fetch_header(session, stream, msgno, section, NIL, &hlen, 0);
        msg  = ml_fetch_body(session, stream, msgno, section, &len, 0);
        type = "application/octet-stream";

        if (!(hdrs && msg)) {
            session_redirect(session, request, "restart");
            return;
        }

        for (i = 0; i < hlen; i++)
            bputc(b, hdrs[i]);

        for (i = 0; i < len; i++)
            bputc(b, msg[i]);

        response_raw(request, name, type, 200);
        return;
    }

    if (!(init_msg = ml_fetchbody(session, stream, msgno, section, &len))) {
        session_redirect(session, request, "restart");
        return;
    }

    /* Strip off encoding */
    switch (body->encoding) {
    case ENCBASE64:
        if (!(decode_msg = rfc822_base64((unsigned char *) init_msg,
                                         body->size.bytes, &len))) {
            /* Decode failed */
            decode_msg = (unsigned char *) init_msg;
            len = body->size.bytes;
        }
        break;
    case ENCQUOTEDPRINTABLE:
        if (!(decode_msg = rfc822_qprint((unsigned char *) init_msg,
                                         body->size.bytes, &len))) {
            /* Decode failed */
            decode_msg = (unsigned char *) init_msg;
            len = body->size.bytes;
        }
        break;
    case ENC7BIT:
    case ENC8BIT:
    case ENCBINARY:
    case ENCOTHER:
    default:
        decode_msg = (unsigned char *) init_msg;
        len = body->size.bytes;
    }

    if (!decode_msg) {
        session_redirect(session, request, "restart");
        return;
    }

    for (i = 0; i < len; i++)
        bputc(b, decode_msg[i]);

    if (init_msg != (char *) decode_msg)
        fs_give((void **) &decode_msg);

    response_raw(request, name, type, 200);
}
