advantage: hawxy.php is not to be modified again in case of // upgrade to higher version @include("hawxy_config.php"); // modify path according actual location of hawhaw.inc if (!defined("HAW_VERSION")) require("hawhaw.inc"); // maximum size of remote XML file in byte if (!defined("HAX_MAX_FILE_SIZE")) define("HAX_MAX_FILE_SIZE", 65536); // treatment of element (disallow per default) if (!defined("HAX_RAW_HTML_ALLOWED")) define("HAX_RAW_HTML_ALLOWED", false); if (!defined("HAX_RAW_WML_ALLOWED")) define("HAX_RAW_WML_ALLOWED", false); if (!defined("HAX_RAW_HDML_ALLOWED")) define("HAX_RAW_HDML_ALLOWED", false); if (!defined("HAX_RAW_VXML_ALLOWED")) define("HAX_RAW_VXML_ALLOWED", false); // filename prefix for user-defined plugins if (!defined("HAX_PLUGIN_PREFIX")) define("HAX_PLUGIN_PREFIX", "HAW_plugin_"); ############################ # # # SIMULATOR SKIN # # # ############################ // HAWHAW skin is used per default // direct $skin towards your personal CSS file for skin customization // (take a look at the CSS file below to learn how to perform skinning) if (!isset($skin)) $skin = "http://skin.hawhaw.de/skin.css"; // set to false if users are not allowed to modify skin if (!isset($allow_skin_attribute)) $allow_skin_attribute = true; // error message can be displayed in special error skin // if no skin is defined, error is displayed in standard HAWHAW output if (!isset($error_skin)) $error_skin = ""; ############################ # # # BANNER PLACEMENT # # # ############################ if (!isset($banner)) $banner = array(); // Here you can define banners which are displayed above the simulated device // Feel free to link towards your own website. // un-comment the next 5 lines and see what happens ... //$banner[0]["url"] = "http://www.hawhaw.de/"; //$banner[0]["img"] = "http://www.hawhaw.de/hawhaw.gif"; //$banner[0]["alt"] = "HAWHAW"; //$banner[0]["width"] = 170; //$banner[0]["height"] = 70; //$banner[1]["url"] = "http://www.hawhaw.de/"; //$banner[1]["img"] = "http://www.hawhaw.de/hawhaw.gif"; //$banner[1]["alt"] = "HAWHAW"; //$banner[1]["width"] = 170; //$banner[1]["height"] = 70; // ... continue like this for more banners ... ############################ # # # LOGFILE HANDLING # # # ############################ // enable/disable error logging if (!isset($log_hawxy_errors)) $log_hawxy_errors = false; ############################## # # # BLACKLIST HANDLING # # # ############################## // all webservers in the domains listed below are blocked from service //$blacklist = array( //"www.foo.com", //"www.bar.com" //); ##################################### # # # IMAGE CONVERSION HANDLING # # # ##################################### // before enabling image conversion your webserver should be configured as follows: // GD Support: enabled // GD version: 1.6.2 or higher // GIF Read Support: enabled // PNG Support: enabled // WBMP Support: enabled if (!isset($img_conversion_enabled)) $img_conversion_enabled = true; // set to false if requirements are not fulfilled if (!isset($img_maxsize)) $img_maxsize = 30000; // maximum size of remote image file ####### HAWXY CONFIGURATION PART (END) ################################ // error messages $err = array(); $err[0] = "Could not connect to remote XML server:"; $err[1] = "Maximum XML file size exceeded!"; $err[2] = "XML error"; $err[3] = "Invalid redirection attribute"; $err[4] = "Error"; $err[5] = "Second declaration not allowed!"; $err[6] = "not allowed here"; $err[7] = "requires attribute:"; $err[8] = "Second not allowed!"; $err[9] = "Second
not allowed!"; $err[10]= "line"; $err[11]= "Invalid address"; $err[12]= "403: Forbidden - Connection to remote XML server not allowed"; $err[13]= "This proxy does not support automatic image conversion!"; $err[14]= "invalid attribute:"; $err[15]= "plugin not found:"; $err[16]= "error in plugin"; // constants for XML parsing define("HAX_PARSE_BEGIN", 1); define("HAX_PARSE_END", 2); // constants for XML tags define("HAX_TAG_UNDEFINED", 0); define("HAX_TAG_HAWHAW", 1); define("HAX_TAG_DECK", 2); define("HAX_TAG_FORM", 3); define("HAX_TAG_TEXT", 4); define("HAX_TAG_RULE", 5); define("HAX_TAG_LINK", 6); define("HAX_TAG_LINKSET", 7); define("HAX_TAG_INPUT", 8); define("HAX_TAG_SUBMIT", 9); define("HAX_TAG_RADIO", 10); define("HAX_TAG_BUTTON", 11); define("HAX_TAG_CHECKBOX", 12); define("HAX_TAG_SELECT", 13); define("HAX_TAG_OPTION", 14); define("HAX_TAG_HIDDEN", 15); define("HAX_TAG_IMAGE", 16); define("HAX_TAG_TABLE", 17); define("HAX_TAG_ROW", 18); define("HAX_TAG_TD", 19); define("HAX_TAG_PHONE", 20); define("HAX_TAG_VOICE_TEXT", 21); define("HAX_TAG_VOICE_HELP", 22); define("HAX_TAG_VOICE_NOMATCH", 23); define("HAX_TAG_VOICE_NOINPUT", 24); define("HAX_TAG_RAW", 25); define("HAX_TAG_PLUGIN", 26); class HAX_tagstack { // stack class for storage of HAWHAW tags, read by PHP's XML parser var $pointer; var $stack = array(); function HAX_tagstack() { // Constructor $this->pointer = 0; } function push($element, $tag) { $this->stack[$this->pointer]["element"] = $element; $this->stack[$this->pointer]["tag"] = $tag; $this->pointer++; return; } function pop() { $this->pointer--; return($this->stack[$this->pointer]); } function get_size() { return($this->pointer); } function get_previous_tag() { if ($this->pointer == 0) return(HAX_TAG_UNDEFINED); else return($this->stack[$this->pointer - 1]["tag"]); } }; class HAX_td { // pseudo HAWHAW class for td element var $element; // points to HAW_text, HAW_image, HAW_link or NONE object var $tag; // type of stored element function HAX_td() { // Constructor $this->element = 0; $this->tag = HAX_TAG_UNDEFINED; } }; class HAX_voice_event { // pseudo class for help/nomatch/noinput events var $tag; var $text; var $audio_src; var $url; function HAX_voice_event($tag, $text, $audio_src="", $url="") { // Constructor $this->tag = $tag; $this->text = $text; $this->audio_src = $audio_src; $this->url = $url; } }; function handleParsedElement($parser, $pos, $name, $attrs) { global $tag_stack; global $err; global $banner; global $img_conversion_enabled; global $skin; global $allow_skin_attribute; static $number_of_decks = 0; static $number_of_forms = 0; static $number_of_linksets = 0; static $markup_language = 0; static $raw_mode = false; if (function_exists("xml_get_current_line_number")) $line = xml_get_current_line_number($parser); else $line = "???"; switch ($name) { case "HAWHAW": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_HAWHAW, $parser); $tag_stack->push(0, HAX_TAG_HAWHAW); } else { // HAX_PARSE_END $tag_stack->pop(); } break; } case "DECK": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_DECK, $parser); if ($number_of_decks++ > 0) error($err[5], $parser, $line); // determine contructor arguments of HAW_deck if (isset($attrs["TITLE"])) $title = $attrs["TITLE"]; else $title = HAW_NOTITLE; if (isset($attrs["ALIGN"]) && ($attrs["ALIGN"] == "center")) $alignment = HAW_ALIGN_CENTER; elseif (isset($attrs["ALIGN"]) && ($attrs["ALIGN"] == "right")) $alignment = HAW_ALIGN_RIGHT; else $alignment = HAW_ALIGN_LEFT; $output = HAW_OUTPUT_AUTOMATIC; if (isset($attrs["OUTPUT"])) { switch ($attrs["OUTPUT"]) { case "bigscreen": { $output = HAW_OUTPUT_BIGSCREEN; break; } case "wap": { $output = HAW_OUTPUT_WAP; break; } case "hdml": { $output = HAW_OUTPUT_HDML; break; } case "pda": { $output = HAW_OUTPUT_PDA; break; } case "imode": { $output = HAW_OUTPUT_IMODE; break; } case "mml": { $output = HAW_OUTPUT_MML; break; } case "voicexml": { $output = HAW_OUTPUT_VOICEXML; break; } case "xhtml": { $output = HAW_OUTPUT_XHTML; break; } } } // initiate HAW_deck object $deck = new HAW_deck($title, $alignment, $output); $markup_language = $deck->ml; // modify HAW_deck objects according attribute list if (isset($attrs["REDIRECTION"])) { $redirection = explode(";", $attrs["REDIRECTION"]); $redirection[0] = trim($redirection[0]); // strip whitespace $redirection[1] = trim($redirection[1]); if (isset($redirection[2])) $redirection[2] = trim(strtolower($redirection[2])); if (($redirection[0] < 1) || ($redirection[0] > 3600)) error($err[3], $parser, $line); // invalid time value if (substr(strtolower($redirection[1]), 0, 4) != "url=") error($err[3], $parser, $line); // invalid URL declaration if (isset($redirection[2]) && ($redirection[2] == "proxy=no")) // redirect directly to target (needed for HawTags) $deck->set_redirection($redirection[0], substr($redirection[1], 4)); else // redirect via HAWXY $deck->set_redirection($redirection[0], determine_url(qualify_url(substr($redirection[1], 4)))); } if (isset($attrs["CACHE"]) && (strtolower($attrs["CACHE"]) == "no")) $deck->disable_cache(); if (isset($attrs["CHARSET"])) $deck->set_charset($attrs["CHARSET"]); if (isset($attrs["LANGUAGE"])) $deck->set_language($attrs["LANGUAGE"]); if (isset($attrs["CSS"])) $deck->set_css($attrs["CSS"]); if (isset($attrs["CSS_CLASS"])) $deck->set_css_class($attrs["CSS_CLASS"]); if (isset($attrs["BACKGROUND"])) $deck->set_background($attrs["BACKGROUND"]); if (isset($attrs["BGCOLOR"])) $deck->set_bgcolor($attrs["BGCOLOR"]); if (isset($attrs["SIZE"])) $deck->set_size($attrs["SIZE"]); if (isset($attrs["COLOR"])) $deck->set_color($attrs["COLOR"]); if (isset($attrs["LINK_COLOR"])) $deck->set_link_color($attrs["LINK_COLOR"]); if (isset($attrs["VLINK_COLOR"])) $deck->set_vlink_color($attrs["VLINK_COLOR"]); if (isset($attrs["LINK_BRACKETS"]) && (strtolower($attrs["LINK_BRACKETS"]) == "no")) $deck->use_link_brackets(false); if (isset($attrs["FACE"])) $deck->set_face($attrs["FACE"]); if (isset($attrs["WAPHOME"])) $deck->set_waphome($attrs["WAPHOME"]); else $deck->set_waphome("http://" . getenv("HTTP_HOST") . getenv("REQUEST_URI")); if (isset($attrs["VOICE_JINGLE"])) $deck->set_voice_jingle($attrs["VOICE_JINGLE"]); if (isset($attrs["SKIN"]) && $allow_skin_attribute) { if (strtolower($attrs["SKIN"]) == "none") $deck->use_simulator(HAW_SIM_NONE); else if (strtolower($attrs["SKIN"]) == "classic") $deck->use_simulator(HAW_SIM_CLASSIC); else $deck->use_simulator($attrs["SKIN"]); } else $deck->use_simulator($skin); // display banners on top of simulator device while (list($key, $val) = each($banner)) { // edit config file for banner control $top_banner[$key] = new HAW_banner($val["img"], $val["url"], $val["alt"]); $top_banner[$key]->set_size($val["width"], $val["height"]); $deck->add_banner($top_banner[$key], HAW_TOP); } $tag_stack->push($deck, HAX_TAG_DECK); } else { // HAX_PARSE_END $element = $tag_stack->pop(); $deck = $element["element"]; $deck->create_page(); } break; } case "FORM": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_FORM, $parser); if ($number_of_forms++ > 0) error($err[9], $parser, $line); if (!isset($attrs["ACTION"])) error(" " . $err[7] . " action", $parser, $line); // action attribute is missing // initiate HAW_form object if (isset($attrs["PROXY"]) && (strtolower($attrs["PROXY"]) == "no")) { // send form data to action script (needed for HawTags) $form = new HAW_form($attrs["ACTION"]); } else { // send form data to hawxy server $form = new HAW_form($_SERVER['SCRIPT_NAME']); // add info about XML source where form input has to be propagated to $hidden = new HAW_hidden("code", qualify_url($attrs["ACTION"])); $form->add_hidden($hidden); } $tag_stack->push($form, HAX_TAG_FORM); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_form object $form = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck) $base_element = $element["element"]; $base_element->add_form($form); // add HAW_form to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; } case "TEXT": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_TEXT, $parser); $format = "HAW_TEXTFORMAT_NORMAL"; if (isset($attrs["BOLD"]) && (strtolower($attrs["BOLD"]) == "yes")) $format |= HAW_TEXTFORMAT_BOLD; if (isset($attrs["ITALIC"]) && (strtolower($attrs["ITALIC"]) == "yes")) $format |= HAW_TEXTFORMAT_ITALIC; if (isset($attrs["UNDERLINE"]) && (strtolower($attrs["UNDERLINE"]) == "yes")) $format |= HAW_TEXTFORMAT_UNDERLINE; if (isset($attrs["BIG"]) && (strtolower($attrs["BIG"]) == "yes")) $format |= HAW_TEXTFORMAT_BIG; if (isset($attrs["SMALL"]) && (strtolower($attrs["SMALL"]) == "yes")) $format |= HAW_TEXTFORMAT_SMALL; if (isset($attrs["BOXED"]) && (strtolower($attrs["BOXED"]) == "yes")) $format |= HAW_TEXTFORMAT_BOXED; $text = new HAW_text("", $format); if (isset($attrs["BR"]) && ($attrs["BR"] >= 0)) $text->set_br($attrs["BR"]+0); // convert string to int! if (isset($attrs["CSS_CLASS"])) $text->set_css_class($attrs["CSS_CLASS"]); if (isset($attrs["COLOR"])) { $textcolor = $attrs["COLOR"]; if (isset($attrs["BOXCOLOR"])) $boxcolor = $attrs["BOXCOLOR"]; else $boxcolor = ""; $text->set_color($textcolor, $boxcolor); } $tag_stack->push($text, HAX_TAG_TEXT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_text object $text = $element["element"]; if (!$text->voice_text) $text->voice_text = $text->text; // update voice_text if not already set $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_form, ...) $base_element = $element["element"]; if ($element["tag"] == HAX_TAG_TD) { // include HAW_text object in HAX_td pseudo class $base_element->element = $text; $base_element->tag = HAX_TAG_TEXT; } else $base_element->add_text($text); // add HAW_text to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; } case "IMG": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_IMAGE, $parser); if (!($alt = $attrs["ALT"])) error(" " . $err[7] . " alt", $parser, $line); // alt attribute is missing if (isset($attrs["SRC"])) { // source attribute ==> perform automatic image conversion if (!$img_conversion_enabled) error($err[13], $parser, $line); // image conversion deactivated per config if (!function_exists("ImageTypes")) error($err[13], $parser, $line); // GD is not loaded if (!(ImageTypes() & (IMG_PNG | IMG_WBMP))) error($err[13], $parser, $line); // not all necessary image types supported $source = $attrs["SRC"]; $extension = strtolower(substr($source, -4)); $accept = strtolower($_SERVER['HTTP_ACCEPT']); if ( (($extension == ".gif") && ((strstr($accept, "image/gif")) || (($markup_language == HAW_HTML) && !(strstr($accept, "image/png"))))) || (($extension == ".png") && ((strstr($accept, "image/png")) || ($markup_language == HAW_HTML))) || (($extension == "wbmp") && ($markup_language == HAW_WML))) { // requesting browser accepts given src image file // ==> no conversion required $src_html = $source; $src_wbmp = $source; } else { // session-controlled image conversion // convert images of HAWHAW XML files only // (we don't want to act as conversion server for the whole world!) static $img_counter = 0; $varname = "i" . $img_counter; session_register($varname); $_SESSION[$varname] = $attrs["SRC"]; $_SESSION['img_ml'] = $markup_language; //$url = sprintf("%s?index=%d", $_SERVER['PHP_SELF'] , $img_counter); // auto-appending of SID does not work in some environments ?!?!? // PHPSESSID may appear twice in url - and if? ... $url = sprintf("%s?index=%d&%s", $_SERVER['PHP_SELF'] , $img_counter, SID); // create image with session ID instead of image URL's // ==> hawxy script will immediately receive a new request // and will create appropriate image on the fly $src_html = $url; $src_wbmp = $url; $img_counter++; } } if (!isset($src_wbmp) && !isset($attrs["WBMP"])) error(" " . $err[7] . " wbmp", $parser, $line); // wbmp attribute is missing elseif (isset($attrs["WBMP"])) $src_wbmp = $attrs["WBMP"]; // explicitely given WBMP file has precedence if (!isset($src_html) && !isset($attrs["HTML"])) error(" " . $err[7] . " html", $parser, $line); // html attribute is missing elseif (isset($attrs["HTML"])) $src_html = $attrs["HTML"]; // explicitely given HTML file has precedence if (isset($attrs["BMP"])) $image = new HAW_image($src_wbmp, $src_html, $alt, $attrs["BMP"]); else $image = new HAW_image($src_wbmp, $src_html, $alt); if (isset($attrs["HTML"]) && isset($attrs["HTML_WIDTH"])) $image->set_html_width($attrs["HTML_WIDTH"]); if (isset($attrs["HTML"]) && isset($attrs["HTML_HEIGHT"])) $image->set_html_height($attrs["HTML_HEIGHT"]); if (isset($attrs["BR"]) && ($attrs["BR"] >= 0)) $image->set_br($attrs["BR"]+0); // convert string to int! if (isset($attrs["LOCALSRC"])) $image->use_localsrc($attrs["LOCALSRC"]); if (isset($attrs["CHTML_ICON"])) $image->use_chtml_icon($attrs["CHTML_ICON"]+0); // convert string to int! if (isset($attrs["MML_ICON"]) && (strlen($attrs["MML_ICON"]) == 2)) $image->use_mml_icon($attrs["MML_ICON"]); $tag_stack->push($image, HAX_TAG_IMAGE); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_image object $image = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_deck, HAW_form, ...) $base_element = $element["element"]; if ($element["tag"] == HAX_TAG_TD) { // include HAW_text object in HAX_td pseudo class $base_element->element = $image; $base_element->tag = HAX_TAG_IMAGE; } else $base_element->add_image($image); // add HAW_image to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; } case "INPUT": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_INPUT, $parser); if (!($name = $attrs["NAME"])) error(" " . $err[7] . " name", $parser, $line); // name attribute is missing if (isset($attrs["FORMAT"])) $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"], $attrs["FORMAT"]); else $input = new HAW_input($name, $attrs["VALUE"], $attrs["LABEL"]); if (isset($attrs["SIZE"])) $input->set_size($attrs["SIZE"]); if (isset($attrs["MAXLENGTH"])) $input->set_maxlength($attrs["MAXLENGTH"]); if (isset($attrs["TYPE"]) && (strtolower($attrs["TYPE"]) == "password")) $input->set_type(HAW_INPUT_PASSWORD); if (isset($attrs["MODE"])) { if (strtolower($attrs["MODE"]) == "alphabet") $input->set_mode(HAW_INPUT_ALPHABET); if (strtolower($attrs["MODE"]) == "katakana") $input->set_mode(HAW_INPUT_KATAKANA); if (strtolower($attrs["MODE"]) == "hiragana") $input->set_mode(HAW_INPUT_HIRAGANA); if (strtolower($attrs["MODE"]) == "numeric") $input->set_mode(HAW_INPUT_NUMERIC); } if (isset($attrs["BR"]) && ($attrs["BR"] >= 0)) $input->set_br($attrs["BR"]+0); // convert string to int! if (isset($attrs["VOICE_TYPE"])) $input->set_voice_type($attrs["VOICE_TYPE"]); if (isset($attrs["VOICE_GRAMMAR_SRC"])) { // set external grammar if (isset($attrs["VOICE_GRAMMAR_TYPE"])) $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"], $attrs["VOICE_GRAMMAR_TYPE"]); else $input->set_voice_grammar($attrs["VOICE_GRAMMAR_SRC"]); // requires HAWHAW V5.5 or higher! } $tag_stack->push($input, HAX_TAG_INPUT); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_input object $input = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_input($input); // add HAW_input to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; } case "RADIO": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_RADIO, $parser); if (!($name = $attrs["NAME"])) error(" " . $err[7] . " name", $parser, $line); // name attribute is missing $radio = new HAW_radio($name); $tag_stack->push($radio, HAX_TAG_RADIO); } else { // HAX_PARSE_END $element = $tag_stack->pop(); // pop HAW_radio object $radio = $element["element"]; $element = $tag_stack->pop(); // pop base object (HAW_form) $base_element = $element["element"]; $base_element->add_radio($radio); // add HAW_radio to base object $tag_stack->push($base_element, $element["tag"]); // re-push base object } break; } case "BUTTON": { if ($pos == HAX_PARSE_BEGIN) { check_state(HAX_TAG_BUTTON, $parser); if (!($label = $attrs["LABEL"])) error("