webgit_tree_action() dereferences an treeish to the tree object
[webgit] / src / query.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 "query.h"
24 #include "repo.h"
25
26 #include "cwa.h"
27
28 #include <stdint.h>
29 #include <time.h>
30
31 void
32 webgit_query_init (struct webgit_query* q)
33 {
34   q->request = NULL;
35   q->now = time (NULL);
36
37   q->deref_to_tree = 0;
38   q->content_type = "text/html";
39
40   q->repo = NULL;
41   q->action = NULL;
42   q->object = NULL;
43   q->head = NULL;
44   llist_init (&q->repos);
45 }
46
47 struct webgit_query*
48 webgit_query_destroy (struct webgit_query* q)
49 {
50   cgi_free (q->request);
51
52   free (q->repo);
53   free (q->action);
54   free (q->object);
55   free (q->head);
56
57   LLIST_WHILE_HEAD (&q->repos, head)
58     webgit_repoinfo_free ((struct webgit_repo_info*) head);
59
60   return q;
61 }
62
63
64 void
65 webgit_query_add_repo (struct webgit_query* q, const char* path)
66 {
67   struct webgit_repo_info* ri = webgit_repoinfo_new (q, path);
68   if (!ri)
69     return;
70
71   LList p = &q->repos;
72   LLIST_FOREACH (&q->repos, node)
73     {
74       struct webgit_repo_info* n = (struct webgit_repo_info*)node;
75       if (strcmp (n->name, ri->name) > 0)
76         break;
77       p = node;
78     }
79   llist_insert_next (p, &ri->node);
80 }
81
82 const int
83 webgit_validate_string (const char *s, size_t v_sz)
84 {
85   for (const char* c = ";$&|<>!`#"; *c; ++c)
86     if (memchr (s, *c, v_sz))
87       return 0;
88
89   return 1;
90 }
91
92 static void
93 webgit_repo_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
94 {
95   (void) self;
96   struct webgit_query* q = (struct webgit_query*) u_dat;
97
98   /* TODO validate that v is a probably legal repo name (alnum()) */
99   if (webgit_validate_string (v, v_sz))
100     {
101       free (q->repo);
102       q->repo = cwa_strndup (v, v_sz);
103     }
104 }
105
106
107 static void
108 webgit_action_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
109 {
110   (void) self;
111   struct webgit_query* q = (struct webgit_query*) u_dat;
112
113   /* TODO validate that v is a probably legal action name alpha() */
114   if (webgit_validate_string (v, v_sz))
115     {
116       free (q->action);
117       q->action = cwa_strndup (v, v_sz);
118     }
119 }
120
121
122 static void
123 webgit_object_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
124 {
125   (void) self;
126   struct webgit_query* q = (struct webgit_query*) u_dat;
127
128   if (!q->action)
129     q->action = cwa_strndup ("object", SIZE_MAX);
130
131   /* TODO validate that v is a probably sha1 (<=40 chars, hex) */
132   if (webgit_validate_string (v, v_sz))
133     {
134       free (q->object);
135       q->object = cwa_strndup (v, v_sz);
136     }
137 }
138
139
140 static void
141 webgit_ref_param (const Cgi self, const char* v, size_t v_sz, void* u_dat)
142 {
143   (void) self;
144   struct webgit_query* q = (struct webgit_query*) u_dat;
145
146   /* TODO validate that v is a probably legal reference (alnum() || one of '_/.') */
147   if (webgit_validate_string (v, v_sz))
148     {
149       free (q->head);
150       q->head = cwa_strndup (v, v_sz);
151     }
152 }
153
154
155 void
156 webgit_param_dispatch (const Cgi self,
157                       const char* name,
158                       const char* value,
159                       size_t value_len,
160                       void* user_data)
161 {
162 #define WEBGIT_PARAM(name, _) {#name, webgit_##name##_param},
163   struct param_table{
164     char* name;
165     void (*cb)(const Cgi, const char* v, size_t v_sz, void* u_dat);
166   } cmds[] = {WEBGIT_PARAMS {"", NULL}};
167 #undef WEBGIT_PARAMS
168
169   for (struct param_table* j = cmds; j->cb; ++j)
170     {
171       if (!strcmp (j->name, name))
172         {
173           j->cb (self, value, value_len, user_data);
174           break;
175         }
176     }
177 }