File: cmd_rawdisplay.c

package info (click to toggle)
prayer 1.3.5-dfsg1-8
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,596 kB
  • sloc: ansic: 43,163; makefile: 817; sh: 445; perl: 166
file content (132 lines) | stat: -rw-r--r-- 3,868 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* $Cambridge: hermes/src/prayer/cmd/cmd_rawdisplay.c,v 1.3 2008/09/16 09:59:55 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);
}