f97b1b4fdbab42be3a0ae7234f642ad46a18e427
[citadel.git] / webcit / downloads.c
1 /*
2  * $Id$
3  */
4 #include "webcit.h"
5
6 void display_room_directory(void)
7 {
8         char buf[1024];
9         char filename[256];
10         char filesize[256];
11         char mimetype[64];
12         char comment[512];
13         int bg = 0;
14         char title[256];
15
16         output_headers(1, 1, 2, 0, 0, 0);
17         wprintf("<div id=\"banner\">\n");
18         wprintf("<h1>");
19         snprintf(title, sizeof title, _("Files available for download in %s"), WC->wc_roomname);
20         escputs(title);
21         wprintf("</h1>");
22         wprintf("</div>\n");
23
24         wprintf("<div id=\"content\" class=\"service\">\n");
25
26         wprintf("<div class=\"fix_scrollbar_bug\">"
27                 "<table class=\"downloads_background\"><tr><td>\n");
28         wprintf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
29                 _("Filename"),
30                 _("Size"),
31                 _("Content"),
32                 _("Description")
33         );
34
35         serv_puts("RDIR");
36         serv_getln(buf, sizeof buf);
37         if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000"))
38         {
39                 extract_token(filename, buf, 0, '|', sizeof filename);
40                 extract_token(filesize, buf, 1, '|', sizeof filesize);
41                 extract_token(mimetype, buf, 2, '|', sizeof mimetype);
42                 extract_token(comment,  buf, 3, '|', sizeof comment);
43                 bg = 1 - bg;
44                 wprintf("<tr bgcolor=\"#%s\">", (bg ? "DDDDDD" : "FFFFFF"));
45                 wprintf("<td>"
46                         "<a href=\"download_file/");
47                 urlescputs(filename);
48                 wprintf("\"><img src=\"display_mime_icon?type=%s\" border=0 align=middle>\n", mimetype);
49                                         escputs(filename);      wprintf("</a></td>");
50                 wprintf("<td>");        escputs(filesize);      wprintf("</td>");
51                 wprintf("<td>");        escputs(mimetype);      wprintf("</td>");
52                 wprintf("<td>");        escputs(comment);       wprintf("</td>");
53                 wprintf("</tr>\n");
54         }
55         wprintf("</table>\n");
56
57         /** Now offer the ability to upload files... */
58         if (WC->room_flags & QR_UPLOAD)
59         {
60                 wprintf("<hr>");
61                 wprintf("<form "
62                         "enctype=\"multipart/form-data\" "
63                         "method=\"POST\" "
64                         "accept-charset=\"UTF-8\" "
65                         "action=\"upload_file\" "
66                         "name=\"upload_file_form\""
67                         ">\n"
68                 );
69                 wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%ld\">\n", WC->nonce);
70
71                 wprintf(_("Upload a file:"));
72                 wprintf("&nbsp;<input NAME=\"filename\" SIZE=16 TYPE=\"file\">&nbsp;\n");
73                 wprintf(_("Description:"));
74                 wprintf("&nbsp;<input type=\"text\" name=\"description\" maxlength=\"64\" size=\"64\">&nbsp;");
75                 wprintf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Upload"));
76
77                 wprintf("</form>\n");
78         }
79
80         wprintf("</div>\n");
81         wDumpContent(1);
82 }
83
84 extern char* static_dirs[];
85 void display_mime_icon(void)
86 {
87         char diskette[SIZ];
88
89         snprintf (diskette, SIZ, "%s%s", static_dirs[0], "/diskette_24x.gif");
90         output_static(diskette);
91
92 }
93
94 void download_file(char *filename)
95 {
96         char buf[256];
97         off_t bytes;
98         char content_type[256];
99         char *content = NULL;
100
101         /* Setting to nonzero forces a MIME type of application/octet-stream */
102         int force_download = 1;
103         
104         safestrncpy(buf, filename, sizeof buf);
105         unescape_input(buf);
106         serv_printf("OPEN %s", buf);
107         serv_getln(buf, sizeof buf);
108         if (buf[0] == '2') {
109                 bytes = extract_long(&buf[4], 0);
110                 content = malloc(bytes + 2);
111                 if (force_download) {
112                         strcpy(content_type, "application/octet-stream");
113                 }
114                 else {
115                         extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
116                 }
117                 output_headers(0, 0, 0, 0, 0, 0);
118                 read_server_binary(content, bytes);
119                 serv_puts("CLOS");
120                 serv_getln(buf, sizeof buf);
121                 http_transmit_thing(content, bytes, content_type, 0);
122                 free(content);
123         } else {
124                 wprintf("HTTP/1.1 404 %s\n", &buf[4]);
125                 output_headers(0, 0, 0, 0, 0, 0);
126                 wprintf("Content-Type: text/plain\r\n");
127                 wprintf("\r\n");
128                 wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
129         }
130
131 }
132
133
134
135 void upload_file(void)
136 {
137         const char *MimeType;
138         char buf[1024];
139         size_t bytes_transmitted = 0;
140         size_t blocksize;
141         struct wcsession *WCC = WC;     /* stack this for faster access (WC is a function) */
142
143         MimeType = GuessMimeType(WCC->upload, WCC->upload_length); 
144         serv_printf("UOPN %s|%s|%s", WCC->upload_filename, MimeType, bstr("description"));
145         serv_getln(buf, sizeof buf);
146         if (buf[0] != '2')
147         {
148                 strcpy(WCC->ImportantMessage, &buf[4]);
149                 display_room_directory();
150                 return;
151         }
152
153         while (bytes_transmitted < WCC->upload_length)
154         {
155                 blocksize = 4096;
156                 if (blocksize > (WCC->upload_length - bytes_transmitted))
157                 {
158                         blocksize = (WCC->upload_length - bytes_transmitted);
159                 }
160                 serv_printf("WRIT %d", blocksize);
161                 serv_getln(buf, sizeof buf);
162                 if (buf[0] == '7')
163                 {
164                         blocksize = atoi(&buf[4]);
165                         serv_write(&WCC->upload[bytes_transmitted], blocksize);
166                         bytes_transmitted += blocksize;
167                 }
168         }
169
170         serv_puts("UCLS 1");
171         serv_getln(buf, sizeof buf);
172         strcpy(WCC->ImportantMessage, &buf[4]);
173         display_room_directory();
174 }