adding header.inc and footer.inc (for skinning) to webgit.c
[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 static 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
56 void
57 webgit_err (const char *err, ...)
58 {
59   va_list args;
60   va_start (args, err);
61   webgit_err_vargs (err, args);
62   va_end (args);
63 }
64
65
66 static void
67 webgit_warn_vargs (const char *err, va_list params)
68 {
69   html_list_append (error_log, html (html_fmt_vargs (err, params), html_tag("br")));
70 }
71
72
73 void
74 webgit_warn (const char *err, ...)
75 {
76   va_list args;
77   va_start (args, err);
78   webgit_warn_vargs (err, args);
79   va_end (args);
80 }
81
82
83 static void
84 webgit_setup (void)
85 {
86   set_die_routine (webgit_err_vargs);
87   set_error_routine (webgit_err_vargs);
88   set_warn_routine (webgit_warn_vargs);
89 }
90
91
92 Html
93 webgit_email_link (Html name, Html email)
94 {
95   return html (
96                html_tag("a",
97                         html_attr ("href",
98                                    html ("mailto:", email))
99                         ),
100                name
101                );
102 }
103
104
105 char*
106 webgit_mimetype (const char* name)
107 {
108   char buf[256];
109
110   if (!name)
111     return NULL;
112
113   char* ext = strrchr (name, '.');
114   if (!ext)
115     return NULL;
116   ++ext;
117   if (!*ext)
118     return NULL;
119
120   FILE* mime_types = fopen ("/etc/mime.types", "r");
121   if (!mime_types)
122     return NULL;
123
124   while (fgets (buf, 256, mime_types))
125     {
126       if (buf[0] == '#' || !strtok (buf, " \t\n"))
127         continue;
128
129       char* suffix;
130       while ((suffix = strtok (NULL, " \t\n")))
131         if (!strcmp (suffix, ext))
132           {
133             fclose (mime_types);
134             return cwa_strndup (buf, SIZE_MAX);
135           }
136     }
137   return NULL;
138 }
139
140 static Html
141 webgit_header (struct webgit_query* query)
142 {
143   (void) query;
144   return html (
145                            html_tag("h1"),
146                            "webgit"
147                            );
148 }
149
150 int
151 main (int argc, char**argv)
152 {
153   Html page;
154   struct webgit_query query;
155
156   webgit_setup();
157
158   error_log = html_list();
159
160   clock_t timestat = clock();
161
162   webgit_query_init (&query);
163
164   /* set some defaults if not already set */
165   setenv ("REQUEST_METHOD", "GET", 0);
166   setenv ("SCRIPT_NAME", argv[0], 0);
167   setenv ("WEBGIT_CONFIG", WEBGIT_CONFIG, 0);
168
169   /* we can only longjmp out of libgit's error handling */
170   if (setjmp (err_jmp))
171     goto error;
172
173   if (webgit_commandline_dispatch (argc, argv, &query))
174     goto error;
175
176   // read config
177   if (webgit_configfile_dispatch (getenv("WEBGIT_CONFIG"), &query))
178     goto error;
179
180
181   // parse request/query What to show?
182
183   query.request = cgi_new ();
184
185   cgi_run_query (query.request, webgit_param_dispatch, &query);
186
187   if (query.count < 0)
188     query.count = query.count_def;
189
190   /* TODO: if no object given but repo+path+ref are given then compute object */
191
192   /* default action is to show the main page with the list of repos */
193   if (!query.action)
194     query.action = cwa_strndup ("main", SIZE_MAX);
195
196
197   // query to cache-line
198
199   // check if in cache
200
201   // generate page
202
203   Html content = webgit_action_dispatch (&query);
204
205   if (query.content_type && !strcmp (query.content_type, "text/html"))
206     {
207       /* generate html page */
208       page = html(
209                   html_httpheader(
210                                   html_httpfield(
211                                                  "Content-type",
212                                                  query.content_type,
213                                                  html_attr("charset", "UTF-8")
214                                                  )//,
215                                   //html_httpfield("Last-Modified", cgit_page.modified),
216                                   //html_httpfield("Expires", cgit_page.expires)
217                                   ),
218                   html_document(
219                                 "-//W3C//DTD XHTML 1.0 Transitional//EN",
220                                 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
221                                 html_content(
222                                              /*head*/
223                                              html(
224                                                   html(html_tag("title"), "webgit"),
225                                                   html_nl(),
226                                                   html_meta("generator", "webgit"),
227                                                   html_link_rel("stylesheet", "text/css", query.stylesheet),
228                                                   html_link_rel("icon", "image/png", "/skins/default/icons/favicon.png")
229                                                   ),
230                                              /*body*/
231                                              html (
232                                                    html (
233                                                          html_tag("div",
234                                                                                                                                   html_attr("id", "container")
235                                                                                                                                   ),
236                                                                                                                  /* TODO header.inc should be configurable and may not exist
237                                                                                                                   The idea is to have a project header and footer available
238                                                                                                                   as plain html so that someone can install webgit
239                                                                                                                   and quickly add their project logo, menu back to the main
240                                                                                                                   project website and any other notices they may wish to add
241                                                                                                                   */
242                                                                                                                  html_include ("/home/cillian/webgit/skins/default/inc/header.inc"),
243                                                                                                                  content,
244                                                                                                                  html(
245                                                                                                                           html_tag("div",
246                                                                                                                                            html_attr("id", "errors")
247                                                                                                                                            ),
248                                                                                                                           error_log
249                                                                                                                           )//,
250                                                                                                                  // See TODO header.inc above
251                                                                                                                  // html_include ("/home/cillian/webgit/skins/default/inc/footer.inc"),
252
253                                                          )
254                                             
255                                                    ),
256                                              html_attr("xmlns", "http://www.w3.org/1999/xhtml"),
257                                              html_attr("xml:lang", "en"),
258                                              html_attr("lang", "en")
259                                              )
260                                 )
261                   );
262
263       timestat = clock() - timestat;
264       html_list_append (error_log, html (
265                                          html_tag("div", html_attr ("id", "timestat")),
266                                                                                  html_fmt ("processing took %g secs\n", timestat/(float)CLOCKS_PER_SEC)
267                                          
268                                          )
269                         );
270
271
272     }
273   else
274     {
275       /* diffrent content type, raw content */
276       html_free (error_log);
277
278       page = html(
279                   html_httpheader (
280                                    html_httpfield ("Content-type",
281                                                    query.content_type ?
282                                                    query.content_type
283                                                    : "application/octet-stream")
284                                   ),
285                   content
286                   );
287     }
288
289   html_fprint (stdout, page);
290
291   html_free (page);
292
293   webgit_query_destroy (&query);
294
295   return 0;
296
297  error:
298   page = html(
299               html_httpheader(
300                               html_httpfield(
301                                              "Content-type",
302                                              "text/html",
303                                              html_attr("charset", "UTF-8")
304                                              )                              ),
305               html_document(
306                             "-//W3C//DTD XHTML 1.0 Transitional//EN",
307                             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",
308                             html_content(
309                                          /*head*/
310                                          html(
311                                               html(html_tag("title"), "ERROR: webgit"),
312                                               html_nl(),
313                                               html_meta("generator", "webgit")
314                                               ),
315                                          /*body*/
316                                          html(
317                                               html_tag("div"),
318                                               error_log
319                                               ),
320                                          html_attr("xmlns", "http://www.w3.org/1999/xhtml"),
321                                          html_attr("xml:lang", "en"),
322                                          html_attr("lang", "en")
323                                          )
324                             )
325               );
326
327   html_fprint (stdout, page);
328   html_free (page);
329   return 10;
330 }
331