lang.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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. * Convert a document from ../html, or redirect the server to it.
  40. */
  41. #include "dsgw.h"
  42. #include "dbtdsgw.h"
  43. #ifdef XP_WIN
  44. #define PATH_SLASH "\\"
  45. #else
  46. #define PATH_SLASH "/"
  47. #endif
  48. static int
  49. doc_is_UTF_8 (const char* docname)
  50. {
  51. static const char* suffixes [] = {".html", ".htm", NULL};
  52. const size_t doclen = strlen (docname);
  53. const char** suf = suffixes;
  54. for (suf = suffixes; *suf; ++suf) {
  55. const size_t suflen = strlen (*suf);
  56. if (doclen >= suflen && !strcasecmp (*suf, docname + doclen - suflen)) {
  57. return 1;
  58. }
  59. }
  60. return 0;
  61. }
  62. static const char*
  63. skip_prefix (const char* prefix, const char* s)
  64. {
  65. const size_t prelen = strlen (prefix);
  66. if (!strncmp (prefix, s, prelen)) return s + prelen;
  67. return s;
  68. }
  69. static int
  70. doc_convert( FILE** fpp, char* stop_at_directive, int erropts )
  71. {
  72. char **argv, line[ BIG_LINE ];
  73. int argc;
  74. while ( dsgw_next_html_line( *fpp, line )) {
  75. if ( dsgw_parse_line( line, &argc, &argv, 0, dsgw_simple_cond_is_true,
  76. NULL )) {
  77. if ( stop_at_directive != NULL &&
  78. dsgw_directive_is( line, stop_at_directive )) {
  79. return( 0 );
  80. } else if ( dsgw_directive_is( line, DRCT_HEAD )) {
  81. dsgw_head_begin();
  82. dsgw_emits ("\n");
  83. } else if ( dsgw_directive_is( line, DRCT_DS_POSTEDVALUE )) {
  84. dsgw_emit_cgi_var (argc, argv);
  85. } else if ( dsgw_directive_is( line, DRCT_DS_CLOSEBUTTON )) {
  86. dsgw_emit_button (argc, argv, "onClick=\"top.close()\"");
  87. } else if ( dsgw_directive_is( line, "DS_CONFIRM_SCRIPT" )) {
  88. {
  89. auto char* yes = dsgw_get_cgi_var ("YES", DSGW_CGIVAR_OPTIONAL);
  90. auto char* no = dsgw_get_cgi_var ("NO", DSGW_CGIVAR_OPTIONAL);
  91. dsgw_emitf ("<SCRIPT LANGUAGE=JavaScript><!--\n"
  92. "function OK() {\n");
  93. if (yes) dsgw_emitf (" %s\n", yes);
  94. dsgw_emits (" top.close();\n"
  95. "}\n"
  96. "\n"
  97. "function Cancel() {\n");
  98. if (no) dsgw_emitf (" %s\n", no);
  99. dsgw_emits (" top.close();\n"
  100. "}\n"
  101. "// -->\n"
  102. "</SCRIPT>\n");
  103. }
  104. } else if ( dsgw_directive_is( line, "DS_CONFIRM_BUTTON_OK" )) {
  105. dsgw_emitf ("<INPUT TYPE=BUTTON VALUE=\"%s\" onClick=\"parent.OK()\">\n",
  106. XP_GetClientStr(DBT_ok_2));
  107. } else if ( dsgw_directive_is( line, "DS_CONFIRM_BUTTON_CANCEL" )) {
  108. dsgw_emitf ("<INPUT TYPE=BUTTON VALUE=\"%s\" onClick=\"parent.Cancel()\">\n",
  109. XP_GetClientStr(DBT_cancel_2));
  110. } else {
  111. dsgw_emits (line);
  112. }
  113. }
  114. }
  115. fclose( *fpp );
  116. *fpp = NULL;
  117. return( 0 );
  118. }
  119. int
  120. main( int argc, char *argv[]
  121. #ifdef DSGW_DEBUG
  122. , char *env[]
  123. #endif
  124. )
  125. {
  126. /*static char* docdir = ".." PATH_SLASH "html" PATH_SLASH;*/
  127. static char* docdir = NULL;
  128. static char* helpdir = NULL;
  129. char* docname = NULL;
  130. char* tfname;
  131. int result = 0;
  132. char *qs = NULL;
  133. int manual_file = 0; /* Flag: is the file a documentation file? */
  134. /* Parse out the file=blah.html */
  135. if (( qs = getenv( "QUERY_STRING" )) != NULL && *qs != '\0' ) {
  136. /* parse the query string: */
  137. auto char *p, *iter = NULL;
  138. qs = dsgw_ch_strdup( qs );
  139. for ( p = ldap_utf8strtok_r( qs, "&", &iter ); p != NULL;
  140. p = ldap_utf8strtok_r( NULL, "&", &iter )) {
  141. /*
  142. * Get the conf file name. It'll be translated
  143. * into /dsgw/context/CONTEXT.conf if
  144. * CONTEXT is all alphanumeric (no slahes,
  145. * or dots). CONTEXT is passed into the cgi.
  146. * if context=CONTEXT is not there, or PATH_INFO
  147. * was used, then use dsgw.conf
  148. */
  149. if ( !strncasecmp( p, "context=", 8 )) {
  150. context = dsgw_ch_strdup( p + 8 );
  151. dsgw_form_unescape( context );
  152. continue;
  153. }
  154. /*Get the filename and check it for naughtiness -RJP*/
  155. if ( !strncasecmp( p, "file=", 5 )) {
  156. /*If there is no file specified, go with index.html*/
  157. if (strlen(p) == 5) {
  158. docname = dsgw_ch_strdup("index.html");
  159. } else {
  160. docname = dsgw_ch_strdup( p + 5 );
  161. dsgw_form_unescape( docname );
  162. }
  163. /*If we're handling a help page, forgo the filename check*/
  164. if ( strlen( docname ) > DSGW_MANUALSHORTCUT_LEN &&
  165. strncmp( docname, DSGW_MANUALSHORTCUT,
  166. DSGW_MANUALSHORTCUT_LEN ) == 0 ) {
  167. manual_file = 1;
  168. }
  169. /*
  170. * Make sure the person isn't trying to get
  171. * some file not in the gateway.
  172. */
  173. if (manual_file == 0 && !dsgw_valid_docname(docname)) {
  174. dsgw_error( DSGW_ERR_BADFILEPATH, docname,
  175. DSGW_ERROPT_EXIT, 0, NULL );
  176. }
  177. continue;
  178. }
  179. }
  180. free( qs ); qs = NULL;
  181. }
  182. (void)dsgw_init( argc, argv, DSGW_METHOD_GET | DSGW_METHOD_POST );
  183. docdir = dsgw_get_docdir();
  184. /*If there is no docname, default to index.html*/
  185. if (docname == NULL) {
  186. docname = dsgw_ch_strdup("index.html");
  187. }
  188. if (!strcmp (docname, "/")) {
  189. printf( "Location: %s?context=%s\n\n",
  190. dsgw_getvp( DSGW_CGINUM_SEARCH ), context );
  191. return( result );
  192. } else {
  193. char* p;
  194. if (*docname == '/') ++docname;
  195. docname = dsgw_ch_strdup( docname );
  196. if (( p = strrchr( docname, '&' )) != NULL ) {
  197. *p++ = '\0';
  198. if ( strncasecmp( p, "info=", 5 ) == 0 ) {
  199. dsgw_last_op_info = dsgw_ch_strdup( p + 5 );
  200. dsgw_form_unescape( dsgw_last_op_info );
  201. }
  202. }
  203. }
  204. if (manual_file) {
  205. helpdir = dsgw_file2path ( DSGW_MANROOT, "slapd/gw/manual/" );
  206. tfname = (char *)dsgw_ch_malloc( strlen( helpdir ) +
  207. strlen( docname + DSGW_MANUALSHORTCUT_LEN ) +
  208. 1 );
  209. sprintf( tfname, "%s%s",
  210. helpdir, docname + DSGW_MANUALSHORTCUT_LEN);
  211. free( helpdir );
  212. } else {
  213. tfname = dsgw_file2path (docdir, docname);
  214. }
  215. if ( ! doc_is_UTF_8 (tfname)) { /* Redirect the Web server: */
  216. printf ("Location: %s%s%s\n\n",
  217. getenv("SERVER_URL"), gc->gc_gwnametrans, skip_prefix (docdir, tfname));
  218. /* It's tempting to also redirect if is_UTF_8(gc->gc_charset).
  219. But it would be wrong: the Web server would transmit an
  220. HTTP Content-type with no charset parameter. The header
  221. must include ";charset=UTF-8". So we transmit it:
  222. */
  223. } else { /* Transmit the document: */
  224. const int erropts = DSGW_ERROPT_EXIT;
  225. auto FILE* docfile;
  226. dsgw_send_header();
  227. #ifdef DSGW_DEBUG
  228. dsgw_logstringarray( "env", env );
  229. #endif
  230. if ((docfile = fopen(tfname, "r")) == NULL) {
  231. dsgw_error( DSGW_ERR_OPENHTMLFILE, tfname, erropts, 0, NULL );
  232. return( -1 );
  233. }
  234. result = doc_convert( &docfile, NULL, erropts );
  235. }
  236. /*
  237. * XXXmcs: the following free() causes a crash on NT... so don't do it!
  238. */
  239. #if 0
  240. free( tfname );
  241. #endif
  242. return result;
  243. }