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