add stylesheet and rxpd option / config
[webgit] / src / webgit.c
1 /*
2     cehtehs git web frontend
3
4   Copyright (C)
5     2007,               Christian Thaeter <ct@pipapo.org>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23 #include "webgit.h"
24
25 #define WEBGIT_CONFIG "./webgit.conf"
26
27 #ifndef WEBGIT_CONFIG
28 #define WEBGIT_CONFIG "/etc/webgit.conf"
29 #endif
30
31 #include "actions.h"
32 #include "query.h"
33 #include "options.h"
34
35 #include "git/git-compat-util.h"
36
37 #include <cwa.h>
38
39 #include <stdio.h>
40 #include <stdarg.h>
41 #include <string.h>
42 #include <time.h>
43 #include <setjmp.h>
44
45 Html error_log;
46 jmp_buf err_jmp;
47
48 void
49 webgit_err_vargs (const char *err, va_list params)
50 {
51   html_list_append (error_log, html (html_fmt_vargs (err, params), html_tag ("br")));
52   longjmp (err_jmp, 0);
53 }
54
55 void
56 webgit_warn_vargs (const char *err, va_list params)
57 {
58   html_list_append (error_log, html (html_fmt_vargs (err, params), html_tag("br")));
59 }
60
61
62 static void
63 webgit_setup (void)
64 {
65   set_die_routine (webgit_err_vargs);
66   set_error_routine (webgit_err_vargs);
67   set_warn_routine (webgit_warn_vargs);
68 }
69
70
71 Html
72 webgit_email_link (Html name, Html email)
73 {
74   return html (
75                html_tag("a",
76                         html_attr ("href",
77                                    html ("mailto:", email))
78                         ),
79                name
80                );
81 }
82
83
84 char*
85 webgit_mimetype (const char* name)
86 {
87   char buf[256];
88
89   if (!name)
90     return NULL;
91
92   char* ext = strrchr (name, '.');
93   if (!ext)
94     return NULL;
95   ++ext;
96   if (!*ext)
97     return NULL;
98
99   FILE* mime_types = fopen ("/etc/mime.types", "r");
100   if (!mime_types)
101     return NULL;
102
103   while (fgets (buf, 256, mime_types))
104     {
105       if (buf[0] == '#' || !strtok (buf, " \t\n"))
106         continue;
107
108       char* suffix;
109       while ((suffix = strtok (NULL, " \t\n")))
110         if (!strcmp (suffix, ext))
111           {
112             fclose (mime_types);
113             return cwa_strndup (buf, SIZE_MAX);
114           }
115     }
116   return NULL;
117 }
118
119
120 int
121 main (int argc, char**argv)
122 {
123   Html page;
124   struct webgit_query query;
125
126   webgit_setup();
127
128   error_log = html_list();
129
130   clock_t timestat = clock();
131
132   webgit_query_init (&query);
133
134   /* set some defaults if not already set */
135   setenv ("REQUEST_METHOD", "GET", 0);
136   setenv ("SCRIPT_NAME", argv[0], 0);
137   setenv ("WEBGIT_CONFIG", WEBGIT_CONFIG, 0);
138
139   /* we can only longjmp out of libgit's error handling */
140   if (setjmp (err_jmp))
141     goto error;
142
143   if (webgit_commandline_dispatch (argc, argv, &query))
144     goto error;
145
146   // read config
147   if (webgit_configfile_dispatch (getenv("WEBGIT_CONFIG"), &query))
148     goto error;
149
150
151   // parse request/query What to show?
152
153   query.request = cgi_new ();
154
155   cgi_run_query (query.request, webgit_param_dispatch, &query);
156
157   if (query.count < 0)
158     query.count = query.count_def;
159
160   /* TODO: if no object given but repo+path+ref are given then compute object */
161
162   /* default action is to show the main page with the list of repos */
163   if (!query.action)
164     query.action = cwa_strndup ("main", SIZE_MAX);
165
166
167   // query to cache-line
168
169   // check if in cache
170
171   // generate page
172
173   Html content = webgit_action_dispatch (&query);
174
175   if (query.content_type && !strcmp (query.content_type, "text/html"))
176     {
177       /* generate html page */
178       page = html(
179                   html_httpheader(
180                                   html_httpfield(
181                                                  "Content-type",
182                                                  query.content_type,
183                                                  html_attr("charset", "UTF-8")
184                                                  )//,
185                                   //html_httpfield("Last-Modified", cgit_page.modified),
186                                   //html_httpfield("Expires", cgit_page.expires)
187                                   ),
188                   html_document(
189                                 "-//W3C//DTD XHTML 1.0 Transitional//EN",
190                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
191                                 html_content(
192                                              /*head*/
193                                              html(
194                                                   html(html_tag("title"), "webgit"),
195                                                   html_nl(),
196                                                   html_meta("generator", "webgit")//,
197                                                   //html_link_rel("stylesheet", "text/css", cgit_page.stylesheet)
198                                                   ),
199                                              /*body*/
200                                              html (
201                                                    html (
202                                                          html_tag("div"),
203                                                          content
204                                                          ),
205                                                    html(
206                                                         html_tag("div"),
207                                                         error_log
208                                                         )
209                                                    ),
210                                              html_attr("xmlns", "http://www.w3.org/1999/xhtml"),
211                                              html_attr("xml:lang", "en"),
212                                              html_attr("lang", "en")
213                                              )
214                                 )
215                   );
216
217       timestat = clock() - timestat;
218       html_list_append (error_log, html (
219                                          html_fmt ("processing took %g secs\n", timestat/(float)CLOCKS_PER_SEC),
220                                          html_tag("br")
221                                          )
222                         );
223
224
225     }
226   else
227     {
228       /* diffrent content type, raw content */
229       html_free (error_log);
230
231       page = html(
232                   html_httpheader (
233                                    html_httpfield ("Content-type",
234                                                    query.content_type ?
235                                                    query.content_type
236                                                    : "application/octet-stream")
237                                   ),
238                   content
239                   );
240     }
241
242   html_fprint (stdout, page);
243
244   html_free (page);
245
246   webgit_query_destroy (&query);
247
248   return 0;
249
250  error:
251   page = html(
252               html_httpheader(
253                               html_httpfield(
254                                              "Content-type",
255                                              "text/html",
256                                              html_attr("charset", "UTF-8")
257                                              )                              ),
258               html_document(
259                             "-//W3C//DTD XHTML 1.0 Transitional//EN",
260                             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
261                             html_content(
262                                          /*head*/
263                                          html(
264                                               html(html_tag("title"), "ERROR: webgit"),
265                                               html_nl(),
266                                               html_meta("generator", "webgit")
267                                               ),
268                                          /*body*/
269                                          html(
270                                               html_tag("div"),
271                                               error_log
272                                               ),
273                                          html_attr("xmlns", "http://www.w3.org/1999/xhtml"),
274                                          html_attr("xml:lang", "en"),
275                                          html_attr("lang", "en")
276                                          )
277                             )
278               );
279
280   html_fprint (stdout, page);
281   html_free (page);
282   return 10;
283 }
284