more font size tweaks.
[citadel.git] / webcit / static.c
1 // The functions in this file handle static pages and objects -- a basic web server.
2 //
3 // Copyright (c) 1996-2021 by the citadel.org team
4 //
5 // This program is open source software.  You can redistribute it and/or
6 // modify it under the terms of the GNU General Public License, version 3.
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <dirent.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <stddef.h>
16 #include "webcit.h"
17 #include "webserver.h"
18
19 unsigned char OnePixelGif[37] = {
20                 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x01, 0x00,
21                 0x01, 0x00, 0x80, 0x00, 0x00, 0xff, 0xff, 0xff,
22                 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00,
23                 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44,
24                 0x01, 0x00, 0x3b 
25 };
26
27
28 void output_error_pic(const char *ErrMsg1, const char *ErrMsg2) {
29         hprintf("HTTP/1.1 200 %s\r\n", ErrMsg1);
30         hprintf("Content-Type: image/gif\r\n");
31         hprintf("x-webcit-errormessage: %s\r\n", ErrMsg2);
32         begin_burst();
33         StrBufPlain(WC->WBuf, (const char *)OnePixelGif, sizeof(OnePixelGif));
34         end_burst();
35 }
36
37 /*
38  * dump out static pages from disk
39  */
40 void output_static(char *prefix) {
41         int fd;
42         struct stat statbuf;
43         off_t bytes;
44         const char *content_type;
45         int len;
46         const char *Err;
47         char what[SIZ];
48         snprintf(what, sizeof what, "./%s/%s", prefix, (char *)ChrPtr(WC->Hdr->HR.ReqLine));
49
50         syslog(LOG_DEBUG, "output_static(%s)", what);
51         len = strlen (what);
52         content_type = GuessMimeByFilename(what, len);
53         fd = open(what, O_RDONLY);
54         if (fd <= 0) {
55                 syslog(LOG_INFO, "output_static('%s') [%s] : %s", what, ChrPtr(WC->Hdr->this_page), strerror(errno));
56                 if (strstr(content_type, "image/") != NULL) {
57                         output_error_pic("the file you requsted is gone.", strerror(errno));
58                 }
59                 else {
60                         hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
61                         hprintf("Content-Type: text/plain\r\n");
62                         begin_burst();
63                         wc_printf("Cannot open %s: %s\r\n", what, strerror(errno));
64                         end_burst();
65                 }
66         }
67         else {
68                 if (fstat(fd, &statbuf) == -1) {
69                         syslog(LOG_INFO, "output_static('%s') : %s", what, strerror(errno));
70                         if (strstr(content_type, "image/") != NULL) {
71                                 output_error_pic("Stat failed!", strerror(errno));
72                         }
73                         else {
74                                 hprintf("HTTP/1.1 404 %s\r\n", strerror(errno));
75                                 hprintf("Content-Type: text/plain\r\n");
76                                 begin_burst();
77                                 wc_printf("Cannot fstat %s: %s\n", what, strerror(errno));
78                                 end_burst();
79                         }
80                         if (fd > 0) close(fd);
81                         return;
82                 }
83
84                 bytes = statbuf.st_size;
85
86                 if (StrBufReadBLOB(WC->WBuf, &fd, 1, bytes, &Err) < 0) {
87                         if (fd > 0) close(fd);
88                         syslog(LOG_INFO, "output_static('%s')  -- FREAD FAILED (%s) --\n", what, strerror(errno));
89                                 hprintf("HTTP/1.1 500 internal server error \r\n");
90                                 hprintf("Content-Type: text/plain\r\n");
91                                 end_burst();
92                                 return;
93                 }
94
95                 close(fd);
96                 http_transmit_thing(content_type, 2);
97         }
98         if (yesbstr("force_close_session")) {
99                 end_webcit_session();
100         }
101 }
102
103
104 /*
105  * robots.txt
106  */
107 void robots_txt(void) {
108         output_headers(0, 0, 0, 0, 0, 0);
109
110         hprintf("Content-type: text/plain\r\n"
111                 "Server: %s\r\n"
112                 "Connection: close\r\n",
113                 PACKAGE_STRING);
114         begin_burst();
115
116         wc_printf("User-agent: *\r\n"
117                 "Disallow: /printmsg\r\n"
118                 "Disallow: /msgheaders\r\n"
119                 "Disallow: /groupdav\r\n"
120                 "Disallow: /do_template\r\n"
121                 "Disallow: /static\r\n"
122                 "Disallow: /display_page\r\n"
123                 "Disallow: /readnew\r\n"
124                 "Disallow: /display_enter\r\n"
125                 "Disallow: /skip\r\n"
126                 "Disallow: /ungoto\r\n"
127                 "Sitemap: %s/sitemap.xml\r\n"
128                 "\r\n"
129                 ,
130                 ChrPtr(site_prefix)
131         );
132
133         wDumpContent(0);
134 }
135
136
137 // These are the various prefixes we can use to fetch static pages.
138 void output_static_root(void)           {       output_static(".");             }
139 void output_static_static(void)         {       output_static("static");        }
140 void output_static_tinymce(void)        {       output_static("tiny_mce");      }
141 void output_static_acme(void)           {       output_static(".well-known");   }
142
143
144 void 
145 ServerStartModule_STATIC
146 (void)
147 {
148 }
149
150
151 void 
152 ServerShutdownModule_STATIC
153 (void)
154 {
155 }
156
157 void 
158 InitModule_STATIC
159 (void)
160 {
161         WebcitAddUrlHandler(HKEY("robots.txt"), "", 0, robots_txt, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
162         WebcitAddUrlHandler(HKEY("favicon.ico"), "", 0, output_static_root, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
163         WebcitAddUrlHandler(HKEY("static"), "", 0, output_static_static, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
164         WebcitAddUrlHandler(HKEY("tinymce"), "", 0, output_static_tinymce, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
165         WebcitAddUrlHandler(HKEY("tiny_mce"), "", 0, output_static_tinymce, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
166         WebcitAddUrlHandler(HKEY(".well-known"), "", 0, output_static_acme, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC|LOGCHATTY);
167 }