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