htmlparse.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /** --- BEGIN COPYRIGHT BLOCK ---
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. --- END COPYRIGHT BLOCK --- */
  38. /*
  39. * htmlparse.c -- routines to parse HTML templates -- HTTP gateway.
  40. * Stolen from libadmin/template.c and libadmin/form_get.c, originally
  41. * by Mike McCool.
  42. */
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <stdarg.h>
  47. #include "dsgw.h"
  48. #include "dbtdsgw.h"
  49. extern char *Versionstr; /* from Versiongw.c */
  50. /* global variables */
  51. char *dsgw_last_op_info; /* set in edit.c and genscreen.c */
  52. char *dsgw_dnattr; /* set in edit.c */
  53. char *dsgw_dndesc; /* set in edit.c */
  54. /*
  55. * Save yourself a lot of grief and put a space after the name.
  56. */
  57. static struct template_s templates[] = {
  58. {"IF ", "FUNC conditional"},
  59. {"ELSE ", "FUNC conditional"},
  60. {"ELIF ", "FUNC conditional"},
  61. {"ENDIF ", "FUNC conditional"},
  62. {"TITLE ", "FUNC title"},
  63. {"BODY ", "FUNC body"},
  64. {"COLORS ", "FUNC colors"},
  65. {"PAGEHEADER ", "FUNC pageheader"},
  66. {"BEGININFO ", "<table border=2 width=100%% cellpadding=2>\n"
  67. "<tr><td align=center colspan=2>"
  68. "<b><FONT size=+1>%s</FONT></b></td></tr>"
  69. "<td colspan=2>\n"},
  70. {"ADDINFO ", "</td></tr><tr><td colspan=2>"},
  71. {"ENDINFO ", "</td></tr></table>\n<hr width=10%%>\n"},
  72. {"SUBMIT ", "FUNC submit\n"},
  73. {"BEGINELEM ", "<pre>"},
  74. {"ELEM ", "\n<b>%s</b>"},
  75. {"ENDELEM ", "</pre>\n"},
  76. {"ELEMADD ", "<b>%s</b>"},
  77. {"ELEMDIV ", "\n"},
  78. {"INDEX ", "<a href=\"index\">%s</a>\n"},
  79. {"HELPBUTTON", "FUNC helpbutton"},
  80. {"DIALOGSUBMIT", "FUNC dialogsubmit"},
  81. {DRCT_DS_LAST_OP_INFO, "FUNC emit_last_op_info"},
  82. {DRCT_DS_GATEWAY_VERSION, "FUNC emit_version_str"},
  83. {DRCT_DS_ALERT_NOENTRIES " ", "FUNC emit_alert_noentries"},
  84. {"ENDHTML", "</BODY></HTML>"},
  85. {"GCONTEXT ", "context=%s"},
  86. {"PCONTEXT ", "<INPUT TYPE=\"hidden\" NAME=\"context\" VALUE=\"%s\">\n"},
  87. { NULL, NULL }
  88. };
  89. /* global to track output status */
  90. #define DSGW_PARSE_STATUS_NO_IF_SEEN -1
  91. #define DSGW_PARSE_STATUS_NO_OUTPUT 0
  92. #define DSGW_PARSE_STATUS_OUTPUT 1
  93. static int parse_status = DSGW_PARSE_STATUS_NO_IF_SEEN;
  94. static int dsgw_get_directive(char *string);
  95. static char **dsgw_get_vars(char *string, int *argc);
  96. static void dsgw_pageheader(int argc, char **argv);
  97. static void dsgw_title(int argc, char **argv);
  98. static void dsgw_body(int argc, char **argv);
  99. static void dsgw_colors(int argc, char **argv);
  100. static void dsgw_submit(int verify, char **vars);
  101. static void dsgw_dialogsubmit(void);
  102. static void dsgw_conditional(char *name, int argc, char **argv,
  103. condfunc conditionalfn, void *condarg);
  104. static int dsgw_condition_true( int argc, char **argv,
  105. condfunc conditionalfn, void *condarg );
  106. static void emit_last_op_info(int argc, char **argv);
  107. static void emit_version_str( void );
  108. static void emit_alert_noentries( void );
  109. static void template_error( char *msg );
  110. /* Filter a page. Takes the page to filter as an argument. Uses above
  111. * filters to process. If we encounter a directive we don't know about,
  112. * we set argc and argv, and return -1. The caller is responsible for
  113. * figuring out what to do with the directive and arg vector.
  114. *
  115. * If parseonly is non-zero, this routine will just parse lines that contain
  116. * directives -- nothing will be written to stdout.
  117. */
  118. int
  119. dsgw_parse_line(
  120. char *line_input,
  121. int *argc,
  122. char ***argv,
  123. int parseonly,
  124. condfunc conditionalfn,
  125. void *condarg
  126. )
  127. {
  128. register int index;
  129. char *position;
  130. int dirlen = strlen(DIRECTIVE_START);
  131. char **vars;
  132. int func_flag = 0;
  133. *argc = 0;
  134. *argv = NULL;
  135. if ( !strncmp( line_input, DIRECTIVE_START, dirlen )) {
  136. position = (char *) ( line_input + dirlen );
  137. if ( parseonly ) {
  138. index = -1; /* treat all directives as "unknown" */
  139. } else {
  140. index = dsgw_get_directive( position );
  141. }
  142. /* did we get one? */
  143. if ( index != -1 ) {
  144. /* if so, get the vars. */
  145. position += strlen( templates[index].name );
  146. vars = dsgw_get_vars( position, argc );
  147. /* Dispatch the correct function (done for readability) */
  148. if ( !strncmp(templates[ index ].format, "FUNC ", 5 )) {
  149. func_flag = 1;
  150. }
  151. /* Don't check the parse_status for conditionals -RJP */
  152. if (func_flag == 1 &&
  153. !strncmp( templates[index].format+5, "conditional", 11 )) {
  154. dsgw_conditional( templates[index].name, *argc, vars,
  155. conditionalfn, condarg );
  156. /* But do so for the other directives */
  157. } else if (func_flag == 1 && parse_status != DSGW_PARSE_STATUS_NO_OUTPUT) {
  158. if ( !strncmp( templates[ index ].format+5, "pageheader",10 ))
  159. dsgw_pageheader( *argc, vars );
  160. else if ( !strncmp( templates[index].format+5,"title",5))
  161. dsgw_title( *argc, vars );
  162. else if ( !strncmp( templates[index].format+5,"body",4))
  163. dsgw_body( *argc, vars );
  164. else if ( !strncmp( templates[index].format+5,"colors",6))
  165. dsgw_colors( *argc, vars );
  166. else if ( !strncmp( templates[ index ].format+5, "submit",6 ))
  167. dsgw_submit( 0, vars );
  168. else if ( !strncmp( templates[ index ].format+5, "verify",6 ))
  169. dsgw_submit( 1, vars );
  170. else if ( !strncmp( templates[index].format+5,
  171. "dialogsubmit",12 ))
  172. dsgw_dialogsubmit();
  173. else if ( !strncmp( templates[index].format+5, "helpbutton", 10 ) && ( *argc > 0 ))
  174. dsgw_emit_helpbutton( vars[ 0 ] );
  175. else if ( !strncmp( templates[index].format+5,"emit_last_op_info", 17 ))
  176. emit_last_op_info( *argc, vars );
  177. else if ( !strncmp( templates[index].format+5, "emit_version_str", 16 ))
  178. emit_version_str();
  179. else if ( !strncmp( templates[index].format+5, "emit_alert_noentries", 20 ))
  180. emit_alert_noentries();
  181. else { /* We don't know what this template is. Send it back. */
  182. *argv = vars;
  183. return -1;
  184. }
  185. /*
  186. * Handle the context case specially, because there is no
  187. * vars generated, yet the format has a %s in it. Handle
  188. * both the GCONTEXT and the PCONTEXT case (GET AND POST)
  189. */
  190. } else if ( parse_status != DSGW_PARSE_STATUS_NO_OUTPUT &&
  191. !strcmp(templates[ index ].name + 1, "CONTEXT ")) {
  192. char line[ BIG_LINE ];
  193. PR_snprintf( line, BIG_LINE, templates[ index ].format, context);
  194. dsgw_emits( line );
  195. } else if ( parse_status != DSGW_PARSE_STATUS_NO_OUTPUT ) {
  196. /* I just can't believe there's no easy way to create
  197. * a va_list. */
  198. char line[ BIG_LINE ];
  199. PR_snprintf( line, BIG_LINE, templates[ index ].format,
  200. ( *argc > 0 && vars[ 0 ] != NULL ) ? vars[ 0 ]: "",
  201. ( *argc > 1 && vars[ 1 ] != NULL ) ? vars[ 1 ]: "",
  202. ( *argc > 2 && vars[ 2 ] != NULL ) ? vars[ 2 ]: "",
  203. ( *argc > 3 && vars[ 3 ] != NULL ) ? vars[ 3 ]: "");
  204. dsgw_emits( line );
  205. }
  206. } else if ( parse_status != DSGW_PARSE_STATUS_NO_OUTPUT ) {
  207. /* We found a directive, but we can't identify it. Return non-zero
  208. * value so caller knows to deal with it.
  209. */
  210. vars = dsgw_get_vars( position, argc );
  211. *argv = vars;
  212. return -1;
  213. }
  214. } else if ( !parseonly && parse_status != DSGW_PARSE_STATUS_NO_OUTPUT ) {
  215. auto char *gcontext = NULL;
  216. auto char *start_of_newline = (char *) dsgw_ch_strdup(line_input);
  217. auto char *new_line_input = start_of_newline;
  218. /* We found no directive at the beginning. Look for GCONTEXT
  219. * It could be anywhere in the line. Sorry, but that's the way
  220. * It has to be. - RJP
  221. */
  222. for (gcontext = strstr(new_line_input, GCONTEXT_DIRECTIVE);
  223. gcontext != NULL;
  224. gcontext = strstr(new_line_input, GCONTEXT_DIRECTIVE)){
  225. *gcontext = '\0';
  226. /*
  227. * Print the new_line_input (everything up to the first
  228. * GCONTEXT_DIRECTIVE
  229. */
  230. dsgw_HTML_emits( new_line_input );
  231. /*Now print "context=whatever"*/
  232. dsgw_emitf("context=%s", context);
  233. /* Now skip past the directive */
  234. new_line_input = gcontext + strlen(GCONTEXT_DIRECTIVE);
  235. }
  236. /* If there's anything left, output it*/
  237. if (*new_line_input) {
  238. dsgw_HTML_emits( new_line_input );
  239. }
  240. free ((void*)start_of_newline);
  241. }
  242. /* If we're here, we either handled it correctly or the line was benign.*/
  243. return 0;
  244. }
  245. FILE *
  246. dsgw_open_html_file(char *filename, int erropts)
  247. {
  248. FILE *f;
  249. char *tfname = NULL;
  250. tfname = dsgw_file2path( gc->gc_tmpldir, filename);
  251. if (!(f = fopen(tfname, "r"))) {
  252. /* punt */
  253. dsgw_error(DSGW_ERR_OPENHTMLFILE, tfname, erropts, 0, NULL );
  254. }
  255. free( tfname );
  256. return f;
  257. }
  258. #define DSGW_INCLUDE_DRCT "<!-- INCLUDE "
  259. #define DSGW_INCLUDE_DRCT_LEN 13
  260. #define DSGW_INCLSET_DRCT "<!-- INCLUDESET "
  261. #define DSGW_INCLSET_DRCT_LEN 16
  262. int
  263. dsgw_next_html_line(FILE *f, char *line)
  264. {
  265. char *p, *incfile;
  266. int linelen;
  267. static FILE *incfp = NULL;
  268. static FILE *parentfp = NULL;
  269. static int incset_index = 0;
  270. static dsgwinclset *incsetp = NULL;
  271. if ( incfp != NULL && parentfp == f ) {
  272. /* we're in the midst of an include -- read from include file */
  273. if ( fgets(line, BIG_LINE, incfp ) != 0 ) {
  274. return 1; /* success */
  275. }
  276. /* end of include file */
  277. fclose( incfp );
  278. /* if in middle of an include set, open and use next file in set */
  279. if ( incsetp != NULL && ++incset_index < incsetp->dsiset_itemcount ) {
  280. incfp = dsgw_open_html_file(
  281. incsetp->dsiset_filenames[ incset_index ],
  282. DSGW_ERROPT_EXIT );
  283. return( dsgw_next_html_line( f, line ));
  284. }
  285. incfp = NULL;
  286. incsetp = NULL;
  287. }
  288. if(!(fgets(line, BIG_LINE, f))) {
  289. return 0; /* end of file */
  290. }
  291. if ( incfp != NULL ) {
  292. return 1; /* ignore nested includes */
  293. }
  294. /* check for start of a simple or an include set based include */
  295. incfile = NULL;
  296. linelen = strlen( line );
  297. if ( linelen > DSGW_INCLUDE_DRCT_LEN && strncasecmp( line,
  298. DSGW_INCLUDE_DRCT, DSGW_INCLUDE_DRCT_LEN ) == 0 ) {
  299. incfile = line + DSGW_INCLUDE_DRCT_LEN;
  300. if (( p = strchr( incfile, ' ' )) != NULL ) {
  301. *p = '\0';
  302. }
  303. } else if ( linelen > DSGW_INCLSET_DRCT_LEN && strncasecmp( line,
  304. DSGW_INCLSET_DRCT, DSGW_INCLSET_DRCT_LEN ) == 0 ) {
  305. char *sethandle;
  306. sethandle = line + DSGW_INCLSET_DRCT_LEN;
  307. if (( p = strchr( sethandle, ' ' )) != NULL ) {
  308. *p = '\0';
  309. }
  310. for ( incsetp = gc->gc_includesets; incsetp != NULL;
  311. incsetp = incsetp->dsiset_next ) {
  312. if ( strcasecmp( sethandle, incsetp->dsiset_handle ) == 0 ) {
  313. break;
  314. }
  315. }
  316. if ( incsetp == NULL ) { /* set not found -- ignore it */
  317. if ( p != NULL ) {
  318. *p = ' ';
  319. }
  320. return( 1 );
  321. }
  322. incset_index = 0;
  323. incfile = incsetp->dsiset_filenames[ 0 ];
  324. }
  325. if ( incfile != NULL ) {
  326. incfp = dsgw_open_html_file( incfile, DSGW_ERROPT_EXIT );
  327. parentfp = f;
  328. return( dsgw_next_html_line( f, line ));
  329. }
  330. return 1;
  331. }
  332. static void
  333. dsgw_pageheader(int argc, char **argv)
  334. {
  335. char line[BIG_LINE];
  336. dsgw_emits("<center><table border=2 width=100%%>\n");
  337. util_snprintf(line, BIG_LINE, "<tr>");
  338. dsgw_emits(line);
  339. util_snprintf(line, BIG_LINE, "<td align=center width=100%%>");
  340. dsgw_emits(line);
  341. util_snprintf(line, BIG_LINE, "<hr size=0 width=0>");
  342. dsgw_emits(line);
  343. util_snprintf(line, BIG_LINE, "<FONT size=+2><b>%s</b></FONT>"
  344. "<hr size=0 width=0>"
  345. "</th>", ( argc > 0 ) ? argv[0] : "" );
  346. dsgw_emits(line);
  347. dsgw_emits("</tr></table></center>\n");
  348. }
  349. static void
  350. dsgw_title( int argc, char **argv)
  351. {
  352. char line[BIG_LINE];
  353. dsgw_emits("<HTML>");
  354. dsgw_head_begin();
  355. util_snprintf(line, BIG_LINE, "\n<TITLE>%s</TITLE></HEAD>\n"
  356. "<BODY %s>\n", ( argc > 0 ) ? argv[0] : "", dsgw_html_body_colors );
  357. dsgw_emits(line);
  358. }
  359. static void
  360. dsgw_body( int argc, char **argv)
  361. {
  362. char line[BIG_LINE];
  363. if ( argc > 0 ) {
  364. util_snprintf(line, BIG_LINE, "<BODY %s %s>\n", dsgw_html_body_colors,
  365. ( argc > 0 ) ? argv[0] : "" );
  366. } else {
  367. util_snprintf(line, BIG_LINE, "<BODY %s>\n", dsgw_html_body_colors );
  368. }
  369. dsgw_emits(line);
  370. }
  371. static void
  372. dsgw_colors( int argc, char **argv)
  373. {
  374. if ( argc > 0 ) {
  375. dsgw_html_body_colors = dsgw_ch_strdup( argv[0] );
  376. } else {
  377. dsgw_html_body_colors = "";
  378. }
  379. }
  380. static void
  381. dsgw_submit(int verify, char **vars)
  382. {
  383. if(verify) {
  384. dsgw_emits ("<SCRIPT language=JavaScript><!--\n"
  385. "function verify(form)\n{\n"
  386. " window.confirmedForm = form;\n");
  387. dsgw_emit_confirm (NULL, "opener.confirmedForm.submit();", NULL /* no */,
  388. XP_GetClientStr(DBT_doYouReallyWantToWindow_), 1,
  389. XP_GetClientStr(DBT_doYouReallyWantTo_), vars[0]);
  390. dsgw_emits ("}\n"
  391. "// -->\n"
  392. "</SCRIPT>\n");
  393. }
  394. dsgw_emits("<center><table border=2 width=100%%><tr>");
  395. if(!verify) {
  396. char outstr[256];
  397. PR_snprintf(outstr, 256, "<td width=50%% align=center>"
  398. "<input type=submit value=\"%s\">"
  399. "</td>\n",
  400. XP_GetClientStr(DBT_ok_1));
  401. dsgw_emits(outstr);
  402. } else {
  403. char outstr[256];
  404. PR_snprintf(outstr, 256, "<td width=50%% align=center>"
  405. "<input type=button value=\"%s\" "
  406. "onclick=\"verify(this.form)\">"
  407. "</td>\n",
  408. XP_GetClientStr(DBT_ok_2));
  409. dsgw_emits(outstr);
  410. }
  411. {
  412. char outstr[256];
  413. PR_snprintf(outstr, 256, "<td width=50%% align=center>"
  414. "<input type=reset value=\"%s\"></td>\n",
  415. XP_GetClientStr(DBT_reset_));
  416. dsgw_emits(outstr);
  417. }
  418. dsgw_emits("</tr></table></center>\n");
  419. dsgw_emits("</form>\n");
  420. dsgw_emits("<SCRIPT language=JavaScript>\n");
  421. dsgw_emits("</SCRIPT>\n");
  422. }
  423. static void
  424. dsgw_dialogsubmit(void)
  425. {
  426. char outstr[256];
  427. dsgw_emits("<center><table border=2 width=100%%><tr>");
  428. PR_snprintf(outstr, 256, "<td width=50%% align=center>"
  429. "<input type=submit value=\"%s\">"
  430. "</td>\n",
  431. XP_GetClientStr(DBT_done_));
  432. dsgw_emits(outstr);
  433. PR_snprintf(outstr, 256, "<td width=50%% align=center>"
  434. "<input type=button value=\"%s\" "
  435. "onClick=\"top.close()\"></td>\n",
  436. XP_GetClientStr(DBT_cancel_2));
  437. dsgw_emits(outstr);
  438. dsgw_emits("</tr></table></center>\n");
  439. dsgw_emits("</form>\n");
  440. dsgw_emits("<SCRIPT language=JavaScript>\n");
  441. dsgw_emits("</SCRIPT>\n");
  442. }
  443. static void
  444. dsgw_conditional( char *name, int argc, char **argv, condfunc conditionalfn,
  445. void *condarg )
  446. {
  447. #define DSGW_COND_STATUS_NO_COND_SEEN 0
  448. #define DSGW_COND_STATUS_IN_IF 1
  449. #define DSGW_COND_STATUS_IN_ELSE 2
  450. #define DSGW_COND_STATUS_IN_ELIF 3
  451. static int cond_status = DSGW_COND_STATUS_NO_COND_SEEN;
  452. static int cond_was_true = 0;
  453. if ( strncmp( name, "IF", 2 ) == 0 ) {
  454. if ( cond_status != DSGW_COND_STATUS_NO_COND_SEEN ) {
  455. template_error( XP_GetClientStr(DBT_foundAnotherIfNestedIfsAreNotSup_) );
  456. return;
  457. }
  458. cond_was_true = dsgw_condition_true( argc, argv, conditionalfn,
  459. condarg );
  460. parse_status = cond_was_true ? DSGW_PARSE_STATUS_OUTPUT
  461. : DSGW_PARSE_STATUS_NO_OUTPUT;
  462. cond_status = DSGW_COND_STATUS_IN_IF;
  463. } else if ( strncmp( name, "ELSE", 4 ) == 0 ) {
  464. if ( cond_status == DSGW_COND_STATUS_NO_COND_SEEN ) {
  465. template_error( XP_GetClientStr(DBT_foundElseButDidnTSeeAnIf_) );
  466. return;
  467. }
  468. if ( cond_status == DSGW_COND_STATUS_IN_ELSE ) {
  469. template_error( XP_GetClientStr(DBT_foundElseAfterElseExpectingEndif_) );
  470. return;
  471. }
  472. parse_status = cond_was_true ? DSGW_PARSE_STATUS_NO_OUTPUT
  473. : DSGW_PARSE_STATUS_OUTPUT;
  474. cond_status = DSGW_COND_STATUS_IN_ELSE;
  475. } else if ( strncmp( name, "ELIF", 4 ) == 0 ) {
  476. if ( cond_status == DSGW_COND_STATUS_NO_COND_SEEN ) {
  477. template_error( XP_GetClientStr(DBT_foundElifButDidnTSeeAnIf_) );
  478. return;
  479. }
  480. if ( cond_status == DSGW_COND_STATUS_IN_ELSE ) {
  481. template_error( XP_GetClientStr(DBT_foundElifAfterElseExpectingEndif_) );
  482. return;
  483. }
  484. if ( cond_was_true ) {
  485. parse_status = DSGW_PARSE_STATUS_NO_OUTPUT;
  486. } else {
  487. cond_was_true = dsgw_condition_true( argc, argv, conditionalfn,
  488. condarg );
  489. parse_status = cond_was_true ? DSGW_PARSE_STATUS_OUTPUT
  490. : DSGW_PARSE_STATUS_NO_OUTPUT;
  491. }
  492. cond_status = DSGW_COND_STATUS_IN_ELIF;
  493. } else if ( strncmp( name, "ENDIF", 5 ) == 0 ) {
  494. if ( cond_status == DSGW_COND_STATUS_NO_COND_SEEN ) {
  495. template_error( XP_GetClientStr(DBT_foundEndifButDidnTSeeAnIf_) );
  496. }
  497. parse_status = DSGW_PARSE_STATUS_NO_IF_SEEN;
  498. cond_status = DSGW_COND_STATUS_NO_COND_SEEN;
  499. }
  500. }
  501. static void
  502. emit_last_op_info( int argc, char **argv )
  503. {
  504. char *s;
  505. if ( dsgw_last_op_info != NULL ) {
  506. if (( s = get_arg_by_name( "prefix", argc, argv )) != NULL ) {
  507. dsgw_emits( s );
  508. }
  509. dsgw_emits( dsgw_last_op_info );
  510. if (( s = get_arg_by_name( "suffix", argc, argv )) != NULL ) {
  511. dsgw_emits( s );
  512. }
  513. }
  514. }
  515. static void
  516. emit_version_str()
  517. {
  518. dsgw_emits( Versionstr );
  519. }
  520. static void
  521. emit_alert_noentries()
  522. {
  523. dsgw_emit_alertForm();
  524. dsgw_emits( "<SCRIPT LANGUAGE=JavaScript><!--\n" );
  525. dsgw_emit_alert (NULL, NULL, XP_GetClientStr(DBT_SearchFound0Entries_),
  526. 0L, "", "", "");
  527. dsgw_emits( "// -->\n</SCRIPT>\n");
  528. }
  529. static void
  530. template_error( char *msg )
  531. {
  532. dsgw_emitf( XP_GetClientStr(DBT_BrBTemplateErrorBSBrN_), msg );
  533. }
  534. static int
  535. dsgw_condition_true( int argc, char **argv, condfunc conditionalfn,
  536. void *condarg )
  537. {
  538. char *save_argv0;
  539. int rc;
  540. if ( argc < 1 || conditionalfn == NULL ) {
  541. return( 1 ); /* unknown, but we default to true */
  542. }
  543. if ( argv[0][0] == '!' ) { /* NOT */
  544. save_argv0 = argv[0];
  545. argv[0] = save_argv0 + 1;
  546. } else {
  547. save_argv0 = NULL;
  548. }
  549. rc = (*conditionalfn)( argc, argv, condarg );
  550. if ( save_argv0 != NULL ) {
  551. argv[0] = save_argv0;
  552. rc = !rc; /* '!' was seen -- reverse the result */
  553. }
  554. return( rc );
  555. }
  556. static int
  557. dsgw_get_directive(
  558. char *string
  559. )
  560. {
  561. int index = -1;
  562. register int x;
  563. for ( x = 0; templates[ x ].name != NULL; x++ ) {
  564. if ( !strncmp( string, templates[ x ].name,
  565. strlen( templates[ x ].name ))) {
  566. index = x;
  567. break;
  568. }
  569. }
  570. return index;
  571. }
  572. int
  573. dsgw_directive_is(char *target, char *directive)
  574. {
  575. char *position = (target + strlen(DIRECTIVE_START));
  576. return(!(strncmp(directive, position, strlen(directive))));
  577. }
  578. static char **
  579. dsgw_get_vars(
  580. char *string,
  581. int *argc
  582. )
  583. {
  584. char **vars = (char **) NULL;
  585. register int x;
  586. int isvar;
  587. char scratch[BIG_LINE];
  588. char lastchar, *p;
  589. int numvars = 0;
  590. isvar = -1;
  591. x = 0;
  592. scratch[0] = '\0';
  593. lastchar = ' ';
  594. while ( *string != '\0' ) {
  595. if (( *string == '\"' ) && ( lastchar != '\\' )) {
  596. if ( isvar != -1 ) {
  597. numvars++;
  598. vars = (char **)dsgw_ch_realloc( vars,
  599. ( numvars + 1 ) * sizeof ( char * ));
  600. vars[ numvars - 1 ] = (char *) dsgw_ch_strdup( scratch );
  601. if (( p = strchr( vars[ numvars - 1 ], '=' )) != NULL ) {
  602. dsgw_form_unescape( p + 1 );
  603. }
  604. vars[ numvars ] = NULL;
  605. isvar = -1;
  606. } else {
  607. isvar = 0;
  608. }
  609. } else {
  610. if ( isvar != -1 ) {
  611. isvar += LDAP_UTF8COPY(scratch + isvar, string);
  612. scratch[ isvar ] = '\0';
  613. } else {
  614. if ( *string == DIRECTIVE_END ) {
  615. break;
  616. }
  617. }
  618. }
  619. lastchar = *string;
  620. LDAP_UTF8INC(string);
  621. }
  622. *argc = numvars;
  623. return vars;
  624. }
  625. /*
  626. * Search the given arg vector for a "tag=value" string where "tag" is
  627. * the same string as "name". If found, return a pointer to the beginning
  628. * of the "value" string. If the value string is missing (e.g. "tag="
  629. * was given), return a zero-length string. If no matching tag was found,
  630. * return NULL.
  631. */
  632. char *
  633. get_arg_by_name( char *name, int argc, char **argv )
  634. {
  635. int i;
  636. if (( i = dsgw_get_arg_pos_by_name( name, argc, argv )) >= 0 ) {
  637. return( &argv[ i ][ strlen( name ) + 1 ] );
  638. } else {
  639. return( NULL );
  640. }
  641. }
  642. int
  643. dsgw_get_arg_pos_by_name( char *name, int argc, char **argv )
  644. {
  645. int i;
  646. int nl = strlen( name );
  647. for ( i = 0; i < argc; i++ ) {
  648. if ( argv[ i ] != NULL ) {
  649. if ( !strncasecmp( name, argv[ i ], nl )) {
  650. if (( argv[ i ][ nl ] == '=' )) {
  651. return( i );
  652. }
  653. }
  654. }
  655. }
  656. return( -1 );
  657. }
  658. void
  659. dsgw_argv_free( char **argv )
  660. {
  661. char **p;
  662. if ( argv != NULL ) {
  663. for ( p = argv; *p != NULL; ++p ) {
  664. free( *p );
  665. }
  666. free( argv );
  667. }
  668. }
  669. savedlines *
  670. dsgw_savelines_alloc()
  671. {
  672. savedlines *slp;
  673. slp = dsgw_ch_malloc( sizeof( savedlines ));
  674. memset( slp, 0, sizeof( savedlines ));
  675. return( slp );
  676. }
  677. void
  678. dsgw_savelines_free( savedlines *svlp )
  679. {
  680. int i;
  681. for ( i = 0; i < svlp->svl_count; ++i ) {
  682. free( svlp->svl_line[ i ] );
  683. }
  684. free( svlp );
  685. }
  686. void
  687. dsgw_savelines_rewind( savedlines *svlp )
  688. {
  689. svlp->svl_current = 0;
  690. }
  691. void
  692. dsgw_savelines_save( savedlines *svlp, char *line )
  693. {
  694. svlp->svl_line = (char **)dsgw_ch_realloc( svlp->svl_line,
  695. (1 + svlp->svl_count ) * sizeof( char * ));
  696. svlp->svl_line[ svlp->svl_count++ ] = dsgw_ch_strdup( line );
  697. }
  698. char *
  699. dsgw_savelines_next( savedlines *svlp )
  700. {
  701. char *p;
  702. if ( svlp->svl_current >= svlp->svl_count ) {
  703. return( NULL );
  704. }
  705. p = svlp->svl_line[ svlp->svl_current ];
  706. ++svlp->svl_current;
  707. return( p );
  708. }