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