5 * \defgroup Subst Variable substitution type stuff
6 * \ingroup CitadelConfig
12 #include <sys/types.h>
17 #include "webserver.h"
20 * \brief debugging function to print array to log
22 void VarPrintTransition(void *vVar1, void *vVar2, int odd){}
24 * \brief debugging function to print array to log
26 void VarPrintEntry(const char *Key, void *vSubst, int odd)
29 lprintf(1,"Subst[%s] : ", Key);
30 ptr = (wcsubst*) vSubst;
32 switch(ptr->wcs_type) {
34 lprintf(1, " -> %s\n", ptr->wcs_value);
37 lprintf(1, " -> Server [%s]\n", ptr->wcs_value);
40 lprintf(1, " -> function at [%0xd]\n", ptr->wcs_function);
43 lprintf(1," WARNING: invalid type: [%ld]!\n", ptr->wcs_type);
50 * \brief Clear out the list of substitution variables local to this session
52 void clear_substs(struct wcsession *wc) {
54 if (wc->vars != NULL) {
56 DeleteHash(&wc->vars);
61 * \brief Clear out the list of substitution variables local to this session
63 void clear_local_substs(void) {
68 * \brief destructor; kill one entry.
70 void deletevar(void *data)
72 wcsubst *ptr = (wcsubst*)data;
73 // if ((wc->vars->wcs_type == WCS_STRING)
74 // || (wc->vars->wcs_type == WCS_SERVCMD)) {
75 if (ptr->wcs_type != WCS_FUNCTION)
81 * \brief Add a substitution variable (local to this session) (strlen version...)
82 * \param keyname the replacementstring to substitute
83 * \param keytype the kind of the key
84 * \param format the format string ala printf
85 * \param ... the arguments to substitute in the formatstring
87 void SVPRINTF(char *keyname, int keytype, const char *format,...)
94 struct wcsession *WCC = WC;
96 keylen = strlen(keyname);
98 * First look if we're doing a replacement of
101 /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
102 if (GetHash(WCC->vars, keyname, keylen, &vPtr)) {
103 ptr = (wcsubst*)vPtr;
104 if (ptr->wcs_value != NULL)
105 free(ptr->wcs_value);
107 else /** Otherwise allocate a new one */
109 ptr = (wcsubst *) malloc(sizeof(wcsubst));
110 safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key);
111 Put(WCC->vars, keyname, keylen, ptr, deletevar);
114 /** Format the string and save it */
116 va_start(arg_ptr, format);
117 vsnprintf(wbuf, sizeof wbuf, format, arg_ptr);
120 ptr->wcs_function = NULL;
121 ptr->wcs_type = keytype;
122 ptr->wcs_value = strdup(wbuf);
126 * \brief Add a substitution variable (local to this session)
127 * \param keyname the replacementstring to substitute
128 * \param keytype the kind of the key
129 * \param format the format string ala printf
130 * \param ... the arguments to substitute in the formatstring
132 void svprintf(char *keyname, size_t keylen, int keytype, const char *format,...)
138 struct wcsession *WCC = WC;
142 * First look if we're doing a replacement of
145 /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
146 if (GetHash(WCC->vars, keyname, keylen, &vPtr)) {
147 ptr = (wcsubst*)vPtr;
148 if (ptr->wcs_value != NULL)
149 free(ptr->wcs_value);
151 else /** Otherwise allocate a new one */
153 ptr = (wcsubst *) malloc(sizeof(wcsubst));
154 safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key);
155 Put(WCC->vars, keyname, keylen, ptr, deletevar);
158 /** Format the string and save it */
160 va_start(arg_ptr, format);
161 len = vsnprintf(wbuf, sizeof wbuf, format, arg_ptr);
164 ptr->wcs_value = (char*) malloc(len + 1);
165 memcpy(ptr->wcs_value, wbuf, len + 1);
166 ptr->wcs_function = NULL;
167 ptr->wcs_type = keytype;
171 * \brief Add a substitution variable (local to this session)
172 * \param keyname the replacementstring to substitute
173 * \param keytype the kind of the key
174 * \param format the format string ala printf
175 * \param ... the arguments to substitute in the formatstring
177 void SVPut(char *keyname, size_t keylen, int keytype, char *Data)
181 struct wcsession *WCC = WC;
185 * First look if we're doing a replacement of
188 /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
189 if (GetHash(WCC->vars, keyname, keylen, &vPtr)) {
190 ptr = (wcsubst*)vPtr;
191 if (ptr->wcs_value != NULL)
192 free(ptr->wcs_value);
194 else /** Otherwise allocate a new one */
196 ptr = (wcsubst *) malloc(sizeof(wcsubst));
197 safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key);
198 Put(WCC->vars, keyname, keylen, ptr, deletevar);
201 ptr->wcs_function = NULL;
202 ptr->wcs_type = keytype;
203 ptr->wcs_value = strdup(Data);
207 * \brief Add a substitution variable (local to this session) that does a callback
208 * \param keyname the keystring to substitute
209 * \param fcn_ptr the function callback to give the substitution string
211 void SVCallback(char *keyname, size_t keylen, var_callback_fptr fcn_ptr)
215 struct wcsession *WCC = WC;
218 * First look if we're doing a replacement of
221 /*PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
222 if (GetHash(WCC->vars, keyname, keylen, &vPtr)) {
223 ptr = (wcsubst*)vPtr;
224 if (ptr->wcs_value != NULL)
225 free(ptr->wcs_value);
227 else /** Otherwise allocate a new one */
229 ptr = (wcsubst *) malloc(sizeof(wcsubst));
230 safestrncpy(ptr->wcs_key, keyname, sizeof ptr->wcs_key);
231 Put(WCC->vars, keyname, keylen, ptr, deletevar);
234 ptr->wcs_value = NULL;
235 ptr->wcs_type = WCS_FUNCTION;
236 ptr->wcs_function = fcn_ptr;
238 inline void SVCALLBACK(char *keyname, var_callback_fptr fcn_ptr)
240 SVCallback(keyname, strlen(keyname), fcn_ptr);
246 * \brief back end for print_value_of() ... does a server command
247 * \param servcmd server command to execute on the citadel server
249 void pvo_do_cmd(char *servcmd) {
253 serv_getln(buf, sizeof buf);
259 wprintf("%s\n", &buf[4]);
265 wprintf("%s\n", &buf[4]);
272 * \brief Print the value of a variable
273 * \param keyname get a key to print
275 void print_value_of(char *keyname, size_t keylen) {
276 struct wcsession *WCC = WC;
281 /*if (WCC->vars != NULL) PrintHash(WCC->vars, VarPrintTransition, VarPrintEntry);*/
282 if (keyname[0] == '=') {
283 do_template(&keyname[1]);
285 /** Page-local variables */
286 if ((WCC->vars!= NULL) && GetHash(WCC->vars, keyname, keylen, &vVar)) {
287 ptr = (wcsubst*) vVar;
288 switch(ptr->wcs_type) {
290 wprintf("%s", ptr->wcs_value);
293 pvo_do_cmd(ptr->wcs_value);
296 (*ptr->wcs_function) ();
299 lprintf(1,"WARNING: invalid value in SV-Hash at %s!", keyname);
302 else if (!strcasecmp(keyname, "SERV_PID")) {
303 wprintf("%d", WCC->ctdl_pid);
306 else if (!strcasecmp(keyname, "SERV_NODENAME")) {
307 escputs(serv_info.serv_nodename);
310 else if (!strcasecmp(keyname, "SERV_HUMANNODE")) {
311 escputs(serv_info.serv_humannode);
314 else if (!strcasecmp(keyname, "SERV_FQDN")) {
315 escputs(serv_info.serv_fqdn);
318 else if (!strcasecmp(keyname, "SERV_SOFTWARE")) {
319 escputs(serv_info.serv_software);
322 else if (!strcasecmp(keyname, "SERV_REV_LEVEL")) {
324 serv_info.serv_rev_level / 100,
325 serv_info.serv_rev_level % 100
329 else if (!strcasecmp(keyname, "SERV_BBS_CITY")) {
330 escputs(serv_info.serv_bbs_city);
333 else if (!strcasecmp(keyname, "CURRENT_USER")) {
334 escputs(WCC->wc_fullname);
337 else if (!strcasecmp(keyname, "CURRENT_ROOM")) {
338 escputs(WCC->wc_roomname);
343 extern char *static_dirs[PATH_MAX]; /**< Disk representation */
346 * \brief Display a variable-substituted template
347 * \param templatename template file to load
349 void do_template(void *templatename) {
350 char flat_filename[PATH_MAX];
351 char filename[PATH_MAX];
354 char outbuf[sizeof inbuf];
355 char key[sizeof inbuf];
359 strcpy(flat_filename, templatename);
361 strcat(flat_filename, ".m.html");
363 strcat(flat_filename, ".html");
365 strcpy(filename, static_dirs[1]);
366 strcat(filename, flat_filename);
367 if (stat(filename, &mystat) == -1)
369 strcpy(filename, static_dirs[0]);
370 strcat(filename, flat_filename);
373 fp = fopen(filename, "r");
375 wprintf(_("ERROR: could not open template "));
376 wprintf("'%s' - %s<br />\n",
377 templatename, strerror(errno));
383 while (fgets(inbuf, sizeof inbuf, fp) != NULL) {
390 for (i=len; i>=0; --i) {
391 if ((inbuf[i]=='<')&&(inbuf[i+1]=='?')) pos = i;
394 wprintf("%s", inbuf);
399 strncpy(outbuf, inbuf, pos);
401 wprintf("%s", outbuf);
402 memmove(inbuf, &inbuf[pos], len - pos +1);
405 for (i=len; i>=0; --i) {
406 if (inbuf[i]=='>') pos = i;
408 strncpy(key, &inbuf[2], pos-2);
410 print_value_of(key, pos-2);
412 memmove(inbuf, &inbuf[pos], len - pos + 1);