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