20030321;4.000 The release. 20030327;4.001 HAM tweaks. Omit port from style URL. 20030403;4.002 Did I leave a dangling fprintf and fclose on an invalid FP in hazel.c::do_daily_tasks? GARGH! Also, added hmac.[ch] in an attempt to do MD5 and HMAC inside Hazel. Added Hazel-HMAC element. 20030403;4.003 Implemented MD5 and HMAC into Hazel via Hazel-Digest (a reworked and renamed version of the now-gone Hazel-HMAC above.) 20030403;4.004 store.c: Added get_themed_pathname_only and get_themed_pathname_or_default to handle conditional fetching of either a themed or (if such a themed file does not exist) default CAT_DIR version of a particular file. store.c: Added get_products_file_pathname_readonly for calls which intend only to read the returned filename. That filename will point to whatever has the best chance of existing. Old get_products_file_pathname will return the themed version, if applicable, whether or not it exists, and can be considered a _write version of the other. 20030408;4.005 Added SECONDS attribute for Hazel-Date to output as seconds since epoch. 20030410;4.006 Removed hardcoded blanking of %HZM_*_KEY* fields from hzml.c. 20030414;4.007 Added location of hazel.config to commented SHOWREG_CONFIG area in SHOWREG. 20030415;4.008 Commented out the "if cost is your primary concern" from ham_install.c when choosing whether to install H3 or H4, and added a little note about H4 being so cool. 20030415;4.009 Damn. text.c::quote_html_specials was not quoting unless there were quotable punctuation characters. Thus, it would not quote whitespace. ARGH. (Fixed.) 20030422;4.010 Removed mention of actual filepaths in CLEANUP action. Added Hazel_get_(orders,pending_orders,users)_dir functions to store.c. Subject DEBUG and SHOWREG actions to a maybe_disallow_cmdline_action check, so that they may be disallowed via CMDLINE_ACTIONS config value. 20030424;4.011 Goddamned typo in the new Hazel_get_*_dir functions caused a missing config field to be interpreted as /. ARGH. 20030508;4.012 Pass TEMPLATE when redirecting to secure or nonsecure. 20030513;4.013 hzml.c: Upped GROUP_LOOP_MAXHITS to 1,000,000, and hacked render_HZML_Query_Loop to use GROUP_LOOP_MAXHITS as its default max. text.c: my_srandom uses getpid as its base seed rather than the time in seconds. 20030610;4.014 Added BlessCmdline tweak to skip check for shell specials in my_run_command. 20030624;4.015 Added SUBST_HIGH_BASE hazel.config support for inserting the Hazel BASE tag after the opening HEAD instead of before the closing. 20030626;4.016 Added support for DISABLE_FOO_NAMES:1 in hazel.config, to prevent Hazel from automagically interpolating %HZE_FOO_NAME from loops and NAMES blocks in custom.rules. 20030630;4.017 Added Root="SELECTED" to Hazel-Vset. 20030701;4.018 Added check in hzml.c::parse_tag for a closing /> in a tag, indicating that it usually takes a body but that body is explicitly absent. 20030711;4.019 Added interpret_HZML_File to read and render but discard output. Added support for templates/hooks/hookname.hzml where hookname is one of pre_action, post_action, confirm, finish, filter_cart, welcome, login, birth, chpass, or daily. Fixed bug in parse_namespace_root where "SELECTED" was case sensitive (eg. for Hazel-Vset Root="Selected".) 20030723;4.020 Added support for [Body="..." Template] attributes to products loops, to avoid slurping in loop bodies for each iteration of a loop. 20030808;4.021 Added . 20030812;4.022 Added %HZH_DBQ_INSERT_ID as a result of a Hazel-DB-Query call. 20030813;4.023 Added Hazel_writable_userfiles to check both DISABLE_USERFILES and ARG_NOWUSER when determining whether or not Hazel can write userfiles. Added that check to client.c to prevent writing the "reserved for" lines in these cases. Doing so allows one to put the following into hazel-cat/templates/hooks/pre_action.hzml: ...and thereby avoiding writing any userfiles for Googlebots. 20030821;4.024 Allow %HZ{'...'} to force complex token quoting off. Allow %HZ{"..."} to force complex token quoting on. 20030826;4.025 Added text.c::Hazel_random_word(int) to generate random words (passwords.) Added Hazel-Vset Random=wordsize option for generating random english-sounding values a la Hazel_random_word above. 20030829;4.026 Fixed obscure bug wherein a search could possibly overwrite already-read product file information, thereby obliterating any special post-processing performed on a particular product. This manifested itself in a BxFyE type discount which was reverting in the middle of a rendered HZML page. Found by tracing every get_HZML_DBREF_Info call and debugging for the Var pointer address itself, which revealed it changing in mid-session. Then grepped for all set_var on DICT_PRODUCTS, traced to new_product, debugged before every line which called it, and finally found the culprit in get_product_fp. In retrospect, I should have known it was a problem with the DICT_PRODUCTS dictionary specifically, as order totals (in DICT_TOTALS) were not being affected. Anyhoo, SQUASH SQUISH STOMP! 20030829;4.027 Added BASE=[2..62] optional attribute to Hazel-Math to return the result in a particular base alphabet. (Eg. 255 w/Base=16 = FF) If Base has a fractional part with two digits, space the result to that width. (Eg. 255 w/Base=16.04 = 00FF) 20030901;4.028 Added FROMBASE optional attribute to Hazel-Math. If given, convert Value from the given FROMBASE base alphabet before any other computations. Added new encapsulation version HzSt02, encoding clientid and expireseconds into a single 12-character string of fixed 6-character base-62 encodings of each. Set HZST_VERSION:2 in hazel.config to use it. 20030909;4.029 Added optional RefDate=YYYYMMDD[HHMMSS] and RefSeconds=seconds attributes to Hazel-Date for supplying a reference time for date calculations. Also added HAZELDATE boolean attribute to return date in Hazel's YYYYMMDDHHMMSS format. 20030909;4.030 Added "hooks/" as a bypassing directory in get_template_pathname, so a passed TEMPLATE isn't prematurely blown on it. (Didn't affect H3 since there were no hooks.) 200309241;4.031 If a Hazel-Loop Type="File" HZML="Full", then render the entire file as HZML before its results are given. This allows more flexible loops/ files describing dynamically generated options for the shopper. 20030926;4.032 Hacked render_HZML_File_Loop to re-add newlines to the file slurped in, so that HZML rendering does not leave us with one big string instead of several lines, then parsable by the File loop. 20031001;4.033 Added Reversed=1 attribute for product loops, to reverse the order of entries. Also, aliased Scramble=1 to Scrambled=1. Fixed bug with loopnames wherein (eg.) INTL would use the loopnamed value for IN as its pretty name. (stribeg used, was too loose.) 20031008;4.034 Hacked variables.c::Hazel_explode_into_list to skipping past multiple delimiters within the string only when collapse_mults is sent. Should fix problem with HAM imports ignoring empty fields. 20031016;4.035 Added optional Complement attribute to Hazel-Strip, to strip all but the given chars. 20031021;4.036 Added Adjust="[PF]x[MDY]" attribute for Hazel-Date, just like %HZD_*. 20031028;4.037 Added DISABLE_SEARCH_RANKING config value to turn off sorting search results by their match strength. 20031028;4.038 Added support in store.c::interpret_api_script_output for writing %HZV variables from an API script. 20031030;4.039 Moved setting of local action and item variables in main() to just after the plugin_pre_validate hook, to allow a hook to change them. 20031118;4.040 Added implied override of Hazel-HAM-Header and Hazel-HAM-Footer. For cases where header.html or footer.html exist in the HAM templates directory, just slurp those out instead. 20031119;4.041 Filled in some holes in the HAM install process. 20031120;4.042 Use FORM_SECURE when redirecting to secure server. Restored PLUGIN_KEY checks for plugins with a plugin_token, now just MySQL. Moved plugin_init call to /after/ the keys are checked. Otherwise, an init may register some HZML functions, then later the addresses of those functions will be inaccessible since the plugin will have been closed. 20031125;4.043 Initial work on element. Reworking new_SearchQuery, create_SearchSpec to return NULL rather than dying, and all the calling functions must check it. Whoopsie-- fixed bug causing Hazel to crash if no plugins present. 20031204;4.044 Added text.c::Hazel_datecmp and Before|After="date" and Past|Present|Future attributes to Hazel-Choice. Added "Result" attribute support for Hazel-Email, Hazel-API, Hazel-Slurp, and Hazel-Belch. Added alias "Value" for "Src" attributes in Hazel-Strip, Hazel-Explode. 20031204;4.045 Fixed another bug for cases without plugins, this time in poll_plugin_versions. (Only occurred with a showreg, though.) Gutted WIN32_PLUGINS section in os.c. Funk dat snit. 20031218;4.046 Hacked rulecmp_* functions in rules.c to recognize a left-hand rule value of "*" as matching anything. Hacked validate_fields in rules.c to check for "*" as the first character on a line, in which case the value checked for is always an empty string, but the `fkey' is retained as the rest of the left-hand-before-the-colon key. As such, you can do your own HZML syntax checks, and still cause an error such as "*BILL_FNAME:+your name cannot be Fred". This change is particularly useful if you'd like to create a templates/custom/input_error.html template with something like this:

The following fields were missing:

%HZV_WORD2
With %HZH_FIELDS_MISSING being an undocumented string so above parsed. You can also access %HZH_FIELDS_INVALID, but *FIELDNAME won't trigger that. Hacked Hazel-Subst to recursively replace all instances of RE. Also, to allow use of HZML tokens in the replacement string, so the replacement can use the replaced text itself, eg. %HZV_RE0, %HZV_RE1, etc. There is a maximum replacement of 100 to avoid an infinite recursive replacement. This until I implement the better solution of replacing the string in-place rather than passing off to strsub and doing the whole damn thing over, which is f-ing stupid. So, for now, be careful what you use in the RE. Something like RE="[^0-9]" with a Replace="anythingnotanumberonethroughnine" is not going to work proper. 20031219;4.047 Added Hazel_regsub to do in-place regular expression replacements, but not sure whether or not to initially hzmlsub the Replace attribute value (eg. someone wants to use an HZML token as of the calling of the loop as the replacement) or to do it for each replacement iteration (eg. they want to use something like %HZV_RE0 to reference a match). For now, the replacement will be parsed anew for each time it is needed. The better solution is to allow escaping %HZ with backslashes, and backslashes with another backslash. (Or to allow $[0-9] subs in this replacement only.) Instead of aborting the save of a historical query if an SKUID is too long, complain via hzdebug and write up to MAX_SKU_LEN. (In save_historical_query.) 20031223;4.048 Hacked evaluate_HZML_Choice to take "Value" attribute before "Token" for the subject value. %HZN namespace can now be used to access DICT_INPUT values. 20031230;4.049 Added DISABLE_PICKUP_REDIRECTION to, well, disable redirection in action=pickup to a URL ending with the actual filename. 20040107;4.050 Added X_javascript ... Javascript plugin, with simple HZML(str) function to render a string as HZML. 20040113;4.051 Added init.hzml HZML hook called just after init_plugins in main.c (after the config file has been read and validated.) Added ability to set %HZA/DICT_ARGS with Vset. Make plugin redirection explicitly use MAIN_NONSECURE rather than MAIN URL. 20040113;4.052 Added %HZI_PICKUP_URL to initialized pickups, using new Hazel_pickup_url_extended to give what redirect usually shows. (Could be a problem for anyone who has embedded an explicit PICKUP_URL field in their products file.) 20040119;4.053 Allow one to use Value instead of Src for source string of Word loop. 20040123;4.054 Added MEMBER_DOSSIER_FORCE_SAVE config setting for saving the dossier after every hit. 20040206;4.055 Added DEMAX_COOKIE_EXPIRES and DEMAX_USER_FILE_AGE hazel.config toggles to avoid the internal MAX_USER_REAP_THRESHOLD (of a week.) However, setting cookies to expire after the user file is deleted is probably a bad idea. 20040210;4.056 Hack for sf1000.registeredsite.com which doesn't identify itself as secure by the usual methods. Set HTTPS_IF_URL_SAYS_SO:secure, make a "secure" link in cgi-bin to the same cgi-bin, and use that as HTTPS to know when we're secure. (Upported from H3.) If LONG_CLIENT_ID:1, prefix new_client_id with an integer tying it to a specific time period, to avoid re-assigning the same id over that particular period. 20040210;4.057 Fixed text.c::my_vsnprintf to copy cooked string a maximum of `size' characters and not `maxlen' (the internal buffer limit.) 20040212;4.058 Fixed pointer trespass in variables.c::to_fields which would cause a crash when an opening HZML tag ended in a boolean attribute (without a value) followed by a single space. Crikey, that to_fields code is scary. Added new HZST_VERSION 3 with the brevity of v2 and nearly as much flexibility as v1. It chunks an all-numeric clientid and the expiration seconds into a series of base62-encoded pieces. Supports LONG_CLIENT_ID. 20040219;4.059 Added check for old H3-style products filename in HAM_action_products_home. 20040226;4.060 Fixed bug in do_HZML_Explode. UPPERCASE(prefix) required to canonically set the proper %HZV key. H3 still inserts the iteration index directly, rather than snprintfing it, so its initial UPPERCASE(namebuff) is sufficient. 20040312;4.061 Added support for %HZE_SEARCH_SORT and %HZM_DEFAULT_SEARCH_SORT of format "[+-]FIELDNAME" to sort matching products of an entire sort, as opposed to the Sort parameter of a (eg. matches) loop, which sorts only that loop's contents. 20040313;4.063 Various Win32 fixes? 20040330;4.064 Added ROLL_COMPLEX_TOKENS config field. If true, always replace newlines with spaces in complex tokens, regardless of complex token quoting policy. 20040401;4.065 Added Hazel-Digest Type="Crypt" Salt="whatever". 20040407;4.066 Begin debugging search.c::search_spec_to_where_statement. 20040408;4.067 Default OR logic in search.c::search_spec_to_where_statement, for PARAND or OR requests. Use AND only if search logic is explicitly AND. 20040409;4.068 If NOT logic, use AND instead of OR. Wtf? Oh yeah, that was for the above search_spec_to_where_statement. 20040426;4.070 Preliminary support for MAINFRAME:filename config value. If present, render templates/ instead of any served page. filename should contain a call to to read in the actual page content. 20040504;4.071 Support for HTML_QUOTABLES config field to override which characters Hazel will quote within complex tokens. Always quotes whitespace. 20040504;4.072 Very rough attempt at an action=categorize which (temporarily, RORY) references a CATEGORY field in the products file to build a category, and uses templates/categories/default.html like a matches.html template, categories/empty.html for a category with no members, and categories/foo.html as a custom override for a category with code foo. Syntax is action=categorize&item=catcode&mode=|new|again|next|prev|goto. 20040519;4.073 Hacked doSearch to return -1 if the products file could not be opened (instead of cgidie dying.) Noting here in case it causes problems down the line. 20040526;4.074 More aisle tweaks, officially calling the feature "aisles" instead of "categories." Some TAX_SHIPPING debugging steps. 20040527;4.075 Moved tax calculation after surcharge and credit. This may affect certain calculations which assumed surcharges and credit were not taxable. If %HZM_TAX_TAXABLE, set final tax to the tax rate (returned by the sales_tax.rules file, or %HZT_TAX_RATE from a MY_TAX script) times %HZT_TAXABLE. Thus, one can set both with Hazel-Vset in sales_tax.rules, and allow the rate computed there to be applied to a more specific taxable amount. 20040527;4.076 Moved init.hzml hook to just /before/ plugin initialization, rather than immediately after. 20040528;4.077 stupid funking grumble grumble taxes 20040528;4.078 Added HAZEL_STATE_LOG, so state (adding state to stateless HTTP, tracking users through hits to the CGI) debugging isn't including by default in hazel.bug anymore. To add it back, just set HAZEL_STATE_LOG:hazel.bug to hazel.config. State tracking is pretty solid now, and its debugging is very noisy. Added %HZT to recognized Tokens via parse_vset_token_spec. (d'oh) 20040528;4.079 plugins/mysql.c: Added optional Prefix="COLUMN" attribute for Hazel-DB-Rows for specifying prefix for %HZH_DBR_COLUMNx for each field/column in a row, filled with the value, as an indexible alternative to %HZH_DBR_fieldname. 20040530;4.080 Added CUSTOM_TEMPLATE_RE config field, if the template id matches that field value (a regular expression), allow it to be customizable. 20040601;4.081 Added hzml.c::Hazel_regmatch for minimal regex matching without the bloat of the HZML-centric functions. Hacked store.c to use it for CUSTOM_TEMPLATE_RE checks. 20040602;4.082 Changed products.c::product_sort_func to make empty strings lose, then backed out of the change realizing it isn't what I was trying to do. Added DICT_AISLE for aisle matches. 20040611;4.083 Check "sales_tax" (in addition to just "tax") in HZML_RULES for possible HZMLification. 20040617;4.084 Added checkout, view to default CUSTOM_TEMPLATE_RE value in store.c. 20040630;4.085 Added support for wildcard rule header [*], and initialize all rules headers to that value, so a (eg.) *:_0_ rule line can now be given before any header is present. However, rule header blocks don't have any scope, so be aware that the active header will be either * or whichever header was last encountered. 20040709;4.086 Beginnings of support for optionally encrypted values in member dossiers, starting with rules.c::Hazel_postprocess_prefs and text.c::Hazel_possibly_decrypt_value. Encrypted (or otherwise encoded/obscured) strings are noted by a $HzEnXX$ prefix, where XX is some index to a decrypt/code method. 20040712;4.087 Moved word->logic != PARAND check up in the search.c::maybe_exclude_match loop-- avoids the striword/key lookup. That "key lookup" is for an optional third arg of a product namespace to check instead of a delimited fields string, to facilitate what I'm actually working on, which is a search over a loaded products dictionary. Added DB_SEARCH_RESCORE for re-scoring the result of a database search. (Actually adding scores, since there are none from a search spec converted to an executed SQL query.) Moved copy of search_spec_to_where_statement to mysql.c for it to do its own special mutations. I am not happy with it, it's a hack, but OK then. 20040714;4.088 Hazel-Encode HZML element, and members.c support for reading and decoding field values beginning with $HzEn02$. I don't like this approach. 20040715;4.089 Hacked action=test to not blow away current values, d'oh, only fill with defaults if they don't already exist. 20040728;4.090 Removed need for empty.html and error.html to exist. Will use message.html if they don't. Two less templates to modify for look-n-feel. 20040728;4.091 Added . 20040813;4.092 Removed search_spec_to_where_statement and skuid_list_to_where_statement from search.c, putting them in the search plugins (or plugin, mysql) itself for engine-specific processing. Also added escape function to mysql plugin, and use it in the new functions. 20040817;4.093 Try sending a "session" cookie with only the name and value (no domain, path, expiration, etc.) 20040820;4.094 If one wants credits to be taxable, set TAX_CREDIT:1. To tax surcharges, set TAX_SURCHARGE:1. This affects changes in 4.075, making the old behaviour default. 20040825;4.095 Emergency hack to Hazel_regsub to prevent infinite loops for recursive RE subs. Will only perform one iteration of a search. 20040910;4.096 Added optional MSGID for ERROR action to use Hazel's method of determining which template should be used for displayed for an error. Useful for payflowpro and other payment gateway options. 20040916;4.097 Uh, updated 4.093 change by sending path (as /), so HzSt doesn't cause browsers to set a cookie for every damned hit to Hazel. Delete the user's *.matches file when deleting client files. 20041004;4.098 Hacked preprocess_search_term interpretation in search.c to skip the search term if it is substituted into an empty string. 20041013;4.099 Make cmdline argument reader put fields into DICT_INPUT (as well as DICT_SHOPPER), so that userfile reads do not overwrite them. (And this should have the side-effect of parse batch product working with cmdline calls.) 20041129;4.100 Added support for Type=FLOATx in Hazel-Math, where X is a single-digit precision for the output. Seems to carry through for subsequent Hazel-Maths on the result... 20041208;4.101 Made increment_order_id() function in client.c a little safer. Fixed file locking. Hazel will try harder to lock file...and if she can't, she will die instead of resetting counter. Also modified plugin_search in mysql plugin. It will fill product info now. I also added SQL_CACHE to select queries in case user has that enabled in mysql (meb) 20051012;4.102: note: bunch of little fixes with mysql plugin and file locking Added support for custom my.cnf file for mysql plugin. Described here: http://dev.mysql.com/doc/mysql/en/mysql-options.html Specify the file and group in hazel.config like so: MYSQL_DEFAULT_FILE:/home/user/cgi-bin/my.cnf MYSQL_DEFAULT_GROUP:hazel The my.cnf file has same spec as global MySQL file usually found here: /etc/my.cnf. I used it to define the (non-standard location of) "socket" file on customer's MacOSX server: [hazel] socket=/var/lib/mysql/mysql.sock ------- Added -lz (zlib) to MYSQL_LIBS in configure.ac ------ In os.c - Hazel_dlerror(), changed this to map to dlerror() ------ Inserted INCLUDES = $(mysql_la_CFLAGS) Just before this line: COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) in Makefile.in file inside plugins directory (and Makefile.am) ------- Tightened up file locking a little more in client.c hopefully to fix orderid getting upped btw pending & order steps. fp_lock in os.c will DIE if locking fails -- this is better than missing info, orders, etc. * Increased MAX_LOCK_TRIES to 20 and LOCK_SLEEP_SECONDS to 1 by default Fixed HTTP Status: codes which has been bugging me for years... OK was "200 200" to work around a crappy Windows 2000 webserver that didn't properly support CGIs (called Website, I think). 20051107;4.103: new_client_id_md5() using MD5 hashing and a little more randomness to generate a better client id. 20051208;4.104: Added functionality for CLIENT_ID_16 to allow for 16 char client id and for PICKUP_ID_LENGTH (allowed values are btw 5 - 16 inclusive) for adjusting the length of the pickup ids. Use: In hazel.config, "CLIENT_ID_16: TRUE" will make all the successive new client ids 16 chars long. In hazel.config, "PICKUP_ID_LENGTH: 13" will make all pickup ids 13 characters in length. If you enter a value out of range or no value, the length will default to 32 characters. 20051209;4.105: In mysql.c plugin, SQL_CACHE was hardcoded in queries. I made it optional so there's a new field option available in hazel.config called MYSQL_USE_SQL_CACHE. Set true or '1', 'SQL_CACHE' will be used in queries that Hazel performs internally otherwise, it will not be used. MYSQL3.x does not support SQL_CACHE so do not enable it if you're using MYSQL3.x. 20051222;4.106: Using new_client_id_md5() to generate the PICKUP_ID. new_client_id_md5() modified to take one argument for adding randomness.