* calculate dirs right
[citadel.git] / webcit / subst.c
1 /*
2  * $Id$
3  */
4 /**
5  * \defgroup Subst Variable substitution type stuff
6  * \ingroup CitadelConfig
7  */
8
9 /*@{*/
10
11 #include "sysdep.h"
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 #include "webcit.h"
17
18 /**
19  * \brief Clear out the list of substitution variables local to this session
20  */
21 void clear_local_substs(void) {
22         struct wcsubst *ptr;
23
24         while (WC->vars != NULL) {
25                 ptr = WC->vars->next;
26
27                 if ((WC->vars->wcs_type == WCS_STRING)
28                    || (WC->vars->wcs_type == WCS_SERVCMD)) {
29                         free(WC->vars->wcs_value);
30                 }
31
32                 free(WC->vars);
33                 WC->vars = ptr;
34         }
35
36         WC->vars = NULL;
37 }
38
39
40 /*
41  * \brief Add a substitution variable (local to this session)
42  * \param keyname the replacementstring to substitute
43  * \param keytype the kind of the key
44  * \param format the format string ala printf
45  * \param ... the arguments to substitute in the formatstring
46  */
47 void svprintf(char *keyname, int keytype, const char *format,...)
48 {
49         va_list arg_ptr;
50         char wbuf[SIZ];
51         struct wcsubst *ptr = NULL;
52         struct wcsubst *scan;
53
54         /**
55          * First scan through to see if we're doing a replacement of
56          * an existing key
57          */
58         for (scan=WC->vars; scan!=NULL; scan=scan->next) {
59                 if (!strcasecmp(scan->wcs_key, keyname)) {
60                         ptr = scan;
61                         free(ptr->wcs_value);
62                 }
63         }
64
65         /** Otherwise allocate a new one */
66         if (ptr == NULL) {
67                 ptr = (struct wcsubst *) malloc(sizeof(struct wcsubst));
68                 ptr->next = WC->vars;
69                 safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key);
70                 WC->vars = ptr;
71         }
72
73         /** Format the string and save it */
74
75         va_start(arg_ptr, format);
76         vsnprintf(wbuf, sizeof wbuf, format, arg_ptr);
77         va_end(arg_ptr);
78
79         ptr->wcs_type = keytype;
80         ptr->wcs_value = strdup(wbuf);
81 }
82
83 /**
84  * \brief Add a substitution variable (local to this session) that does a callback
85  * \param keyname the keystring to substitute
86  * \param fcn_ptr the function callback to give the substitution string
87  */
88 void svcallback(char *keyname, void (*fcn_ptr)() )
89 {
90         struct wcsubst *ptr;
91
92         ptr = (struct wcsubst *) malloc(sizeof(struct wcsubst));
93         ptr->next = WC->vars;
94         ptr->wcs_type = WCS_FUNCTION;
95         strcpy(ptr->wcs_key, keyname);
96         ptr->wcs_function = fcn_ptr;
97         WC->vars = ptr;
98 }
99
100
101
102 /**
103  * \brief back end for print_value_of() ... does a server command
104  * \param servcmd server command to execute on the citadel server
105  */
106 void pvo_do_cmd(char *servcmd) {
107         char buf[SIZ];
108
109         serv_puts(servcmd);
110         serv_getln(buf, sizeof buf);
111
112         switch(buf[0]) {
113                 case '2':
114                 case '3':
115                 case '5':
116                         wprintf("%s\n", &buf[4]);
117                         break;
118                 case '1':
119                         fmout("CENTER");
120                         break;
121                 case '4':
122                         wprintf("%s\n", &buf[4]);
123                         serv_puts("000");
124                         break;
125         }
126 }
127
128
129
130 /**
131  * \brief Print the value of a variable
132  * \param keyname get a key to print
133  */
134 void print_value_of(char *keyname) {
135         struct wcsubst *ptr;
136         void *fcn();
137
138         if (keyname[0] == '=') {
139                 do_template(&keyname[1]);
140         }
141
142         if (!strcasecmp(keyname, "SERV_PID")) {
143                 wprintf("%d", WC->ctdl_pid);
144         }
145
146         else if (!strcasecmp(keyname, "SERV_NODENAME")) {
147                 escputs(serv_info.serv_nodename);
148         }
149
150         else if (!strcasecmp(keyname, "SERV_HUMANNODE")) {
151                 escputs(serv_info.serv_humannode);
152         }
153
154         else if (!strcasecmp(keyname, "SERV_FQDN")) {
155                 escputs(serv_info.serv_fqdn);
156         }
157
158         else if (!strcasecmp(keyname, "SERV_SOFTWARE")) {
159                 escputs(serv_info.serv_software);
160         }
161
162         else if (!strcasecmp(keyname, "SERV_REV_LEVEL")) {
163                 wprintf("%d.%02d",
164                         serv_info.serv_rev_level / 100,
165                         serv_info.serv_rev_level % 100
166                 );
167         }
168
169         else if (!strcasecmp(keyname, "SERV_BBS_CITY")) {
170                 escputs(serv_info.serv_bbs_city);
171         }
172
173         else if (!strcasecmp(keyname, "CURRENT_USER")) {
174                 escputs(WC->wc_fullname);
175         }
176
177         else if (!strcasecmp(keyname, "CURRENT_ROOM")) {
178                 escputs(WC->wc_roomname);
179         }
180
181         /** Page-local variables */
182         else for (ptr = WC->vars; ptr != NULL; ptr = ptr->next) {
183                 if (!strcasecmp(ptr->wcs_key, keyname)) {
184                         if (ptr->wcs_type == WCS_STRING) {
185                                 wprintf("%s", ptr->wcs_value);
186                         }
187                         else if (ptr->wcs_type == WCS_SERVCMD) {
188                                 pvo_do_cmd(ptr->wcs_value);
189                         }
190                         else if (ptr->wcs_type == WCS_FUNCTION) {
191                                 (*ptr->wcs_function) ();
192                         }
193                 }
194         }
195 }
196
197 extern char *static_dirs[PATH_MAX];  /**< Disk representation */
198
199 /**
200  * \brief Display a variable-substituted template
201  * \param templatename template file to load
202  */
203 void do_template(void *templatename) {
204         char flat_filename[PATH_MAX];
205         char filename[PATH_MAX];
206         FILE *fp;
207         char inbuf[1024];
208         char outbuf[sizeof inbuf];
209         char key[sizeof inbuf];
210         int i, pos;
211         struct stat mystat;
212
213         strcpy(flat_filename, templatename);
214         if (WC->is_wap)
215                 strcat(flat_filename, ".wml");
216         else
217                 strcat(flat_filename, ".html");
218         
219         strcpy(filename, static_dirs[1]);
220         strcat(filename, flat_filename);
221         if (stat(filename, &mystat) == -1)
222         {
223                 strcpy(filename, static_dirs[0]);
224                 strcat(filename, flat_filename);
225         }
226
227         fp = fopen(filename, "r");
228         if (fp == NULL) {
229                 wprintf(_("ERROR: could not open template "));
230                 wprintf("'%s' - %s<br />\n",
231                         templatename, strerror(errno));
232                 return;
233         }
234
235         strcpy(inbuf, "");
236
237         while (fgets(inbuf, sizeof inbuf, fp) != NULL) {
238                 int len;
239
240                 strcpy(outbuf, "");
241                 len = strlen(inbuf);
242                 while (len > 0) {
243                         pos = (-1);
244                         for (i=len; i>=0; --i) {
245                                 if ((inbuf[i]=='<')&&(inbuf[i+1]=='?')) pos = i;
246                         }
247                         if (pos < 0) {
248                                 wprintf("%s", inbuf);
249                                 strcpy(inbuf, "");
250                                 len = 0;
251                         }
252                         else {
253                                 strncpy(outbuf, inbuf, pos);
254                                 outbuf[pos] = 0;
255                                 wprintf("%s", outbuf);
256                                 memmove(inbuf, &inbuf[pos], len - pos +1);
257                                 len -= pos;
258                                 pos = 1;
259                                 for (i=len; i>=0; --i) {
260                                         if (inbuf[i]=='>') pos = i;
261                                 }
262                                 strncpy(key, &inbuf[2], pos-2);
263                                 key[pos-2] = 0;
264                                 print_value_of(key);
265                                 pos++;
266                                 memmove(inbuf, &inbuf[pos], len - pos + 1);
267                                 len -= pos;
268                         }
269                 }
270         }
271
272         fclose(fp);
273 }
274
275
276
277 /*@}*/