Some of the more complex interfaces will provide input fields and buttons for the user to configure and control the Network Security Toolkit. This is the highest level of scripting available. In order to accomplish this, your script will need to do the following:
Output the necessary HTML to provide the input fields for the end user.
Determine if the user has already entered values (are we processing a user request). This is optional and only needed if you decide to keep the processing of the form submission within the same script that is used to generate the input form itself.
Provide output regarding the state of the form processing (or state of the machine). In general, there is typically a lot of similar output generated both when presenting the form to the user and processing the user's request.
The
wui/cgi-bin/networking/ntp_query.cgi
script
can be used as a simple example of this. It does the
following:
It uses the standard
@bashCgiBegin()
macro to generate the
standard start of a HTML document (keeps the pages generated
consistent).
Includes the file
../include/form.sh
which contains a set
of helper functions for processing forms. It then invokes
the set_query_options
function to parse
out any form parameters which might be present in the
QUERY_STRING
. This greatly simplifies life as
we can then simply check to see if the
QUERY_host
value has been set instead of
trying to parse the contents of the
QUERY_STRING
ourselves.
We then put out information about the page.
If the QUERY_host
is set (which happens
once the user presses the submit button to make a request),
we will go ahead and run the command and show the
results. If the QUERY_host
variable is not
set, then we omit this output.
Finally, we generate a HTML form to
allow the user to specify a host to make a
NTP query against (so the
QUERY_host
will be set if the user presses
the submit button).
The following shows the actual script which does the above:
@bashCgiBegin("$Id: ntp_query.cgi,v 1.18 2008/09/13 16:33:05 rwhalb Exp $","2003-10-22","NTP Time Synchronization (Query/Set)") # # ntp_query.cgi # # local defines... @define("exitAnchor","System") # # load in standard functions... . ../include/service.sh; . ../include/clock.sh; # # parse any cgi args... set_query_options; # # exit text... qrft="${QUERY_return_from:-"NST WUI Index"}"; qrlt="${QUERY_return_label:-"Exit"}" exit_hover_text="@jsn("${qrlt}") to page: @jsqh("${qrft}")..."; exit_hover_text_len="$(((${#qrft} * @dtm()) + 130))"; # # hidden forms... @bashCgiOutBegin() @comment("-------------------------------------------------------------- Hidden Form: \"returnExit\" - for exiting this script... -----------------------------------------------------------------------") @formBegin("${QUERY_return:-"@topDir()/index.cgi#System"}","returnExit") @wuiInputHidden("synckey","${QUERY_synckey}") @formEnd() @bashCgiOutEnd() # # update_config # # Loads/save configuration information from any previous # visit - session level save. update_config() { # # Save/restore session ipmitool parameters... # custom NTP custom URL address... wui_get_set_config NTP_CUSTOM_URL QUERY_custom_url "pool.ntp.org" session; # custom last ntptrace setting... if [ -n "${QUERY_host}" ]; then QUERY_ntptrace="${QUERY_ntptrace:-""}"; fi wui_get_set_config NTP_NTPTRACE QUERY_ntptrace "" session; # # save configuration... wui_save_config; } # # Load/save configuration... update_config; # # locate progs... check_required_program PS ps; check_required_program SUDO sudo; check_required_program NTPDATE ntpdate; check_required_program NTPTRACE ntptrace; # # If ntpd is running, we don't want to allow user to set time NTPD_RUNNING="false"; BUTTON_LABEL="Query/Set Time"; queryDomTT="@jsn("Query")/@jsn("Set")"; queryDomTTWidth="420"; if ${PS} -C ntpd &> /dev/null; then NTPD_RUNNING=true BUTTON_LABEL="Query Time" queryDomTT="@jsn("Query")"; queryDomTTWidth="380"; fi # # See if we need to query/set time if [ "${QUERY_host}" != "" ]; then # # If "custom" button selected, change host to value in custom field if [ "${QUERY_host}" = "custom" ]; then QUERY_host="${NTP_CUSTOM_URL}" fi # # resolve hostname if not and IP address... hostIPArray=(); # init array... hostnameResolved="true"; # init flag... if (! is_IP4_Addr "${QUERY_host}"); then # is a hostname... hostIPArray=($(get_ip_for_host "${QUERY_host}" 2>/dev/null)); if [ $? -ne 0 ]; then hostnameResolved="false"; fi else # is a IPv4 address... hostIPArray=("${QUERY_host}"); fi if [ "${hostnameResolved}" = "false" ]; then @bashCgiOutBegin() @warningMessage("We were unable to resolve the host name: \"@bold("${QUERY_host}")\" to and IP address. Correct the host name entry and try again.") @verticalGap() @bashCgiOutEnd() else # # how many ip columns to display... IP_COLUMNS=4; # # Show hostname resolution information... @bashCgiOutBegin() @nstWUIHeader("hostnameresolve","NTP Server Host Name Resolution") @p("The selected host name: \"@bold("${QUERY_host}")\" resolves to the following @bold("IP address(es)"):") @verticalGapSmall() <center> <table@htmlAttr("border","1") @htmlAttr("width","90%")> <colgroup> <col@htmlAttr("width","25%")> <col@htmlAttr("width","25%")> <col@htmlAttr("width","25%")> <col@htmlAttr("width","25%")> </colgroup> <tr> $(for ((i=0; i < IP_COLUMNS; i++)); do echo "<th>NTP Server</th>"; done) </tr> @bashCgiOutEnd() EVENODD="even"; for ((i=0; i < ${#hostIPArray[@]}; i++)); do if [ "$((i%IP_COLUMNS))" == "0" ]; then echo "<tr>"; if [ "${EVENODD}" = "even" ]; then EVENODD=odd; else EVENODD=even; fi fi @bashCgiOutBegin() <td@htmlAttr("class","${EVENODD}")> @wuiIpWizardLink("${hostIPArray[i]}","${hostIPArray[i]}","${QUERY_return}","@toolTipAttr("@jsn("Click") on the @jsqh("Link") to further @jsn("Inspect") this @jstc("NTP Server","@toolTipEmphasis()"): @jsdh("${hostIPArray[i]}")...","520")") </td> @bashCgiOutEnd() if [ "$((i%IP_COLUMNS+1))" == "${IP_COLUMNS}" ]; then echo "</tr>" fi done # # complete columns and row if necessary... if [ "$((i%IP_COLUMNS))" != "0" ]; then completeTD="$((IP_COLUMNS - i%IP_COLUMNS))"; for ((i=0; i < completeTD; i++)); do echo "<td@htmlAttr("class","${EVENODD}")> </td>" done echo "</tr>" fi @bashCgiOutBegin() <tr> $(for ((i=0; i < IP_COLUMNS; i++)); do echo "<th>IP Address</th>"; done) </tr> </table> </center> @verticalGapSmall() @p("The first resolved IP address: \"@bold("${hostIPArray[0]}")\" will be used for the following queries. Results will be available in <u>few</u> moments...") @bashCgiOutEnd() # # See if they check the "set time" box, then go ahead and do if [ "${QUERY_settime}" = "yes" ]; then @bashCgiOutBegin() @nstWUIHeader("ntptimeset","NTP Time Set") @p("The following shows the <u>results</u> of the attempt to set the @nst() system's time based on the current time at @acroNTP() server: \"@bold("${QUERY_host}")\":") @runCommand("${SUDO} ${NTPDATE} -v ${hostIPArray[0]} 2>&1;") @verticalGap() @bashCgiOutEnd() fi # # Display information about the server @bashCgiOutBegin() @nstWUIHeader("ntpqueryresult","NTP Query Results") @p("The following shows the time synchonization difference results by using the @manPageLink("ntpdate") command to query the time from @acroNTP() host: \"@bold("${QUERY_host}")\":") @runCommand("${NTPDATE} -d -q -v ${hostIPArray[0]} 2>&1;") @bashCgiOutEnd() # # see if we need to also do a ntp trace... if [ "${NTP_NTPTRACE}" = "checked" ]; then @bashCgiOutBegin() @verticalGapSmall() @p("Now perform a @manPageLink("ntptrace") to this NTP server.") @runCommand("${NTPTRACE} ${hostIPArray[0]} 2>&1;") @bashCgiOutEnd() fi clock_navigation; fi else QUERY_host="pool.ntp.org"; fi # # Show area to make next query from if [ "${NTPD_RUNNING}" = "false" ]; then @bashCgiOutBegin() @nstWUIHeader("chkserv","NTP Time Synchronization: "Query/Set"") @p("Use this form to check the @bold("time synchronization") <u>difference</u> between an @acroNTP() server and this @nst() probe's system time. Since the @manPageLink("ntpd","NTP") service (@manPageLink("ntpd")) is @stress("not") running on this @nst() probe, one may automatically <u>set</u> the @nst() probe's system time based on the returned query time value from the selected @acroNTP() server. Select either one of the public @acroNTP() server <u>pools</u> (See the: @appExtRef("NTP Pool Project","http://www.pool.ntp.org/")) or a <u>specific</u> @manPageLink("ntpd","NTP") server for time \"@bold("Querying/Setting")\".") @bashCgiOutEnd() else @bashCgiOutBegin() @nstWUIHeader("chkserv","NTP Time Synchronization: "Query"") @p("Use this form to check the @bold("time synchronization") <u>difference</u> between an @acroNTP() server and this @nst() probe's system time. Select either one of the public @acroNTP() server <u>pools</u> (See the: @appExtRef("NTP Pool Project","http://www.pool.ntp.org/")) or a <u>specific</u> @manPageLink("ntpd","NTP") server for time \"@bold("Querying")\".") @bashCgiOutEnd() fi @bashCgiOutBegin() @verticalGapSmall() <center> <form@htmlAttr("id","queryformid") @htmlAttr("action","ntp_query.cgi")> @wuiInputHidden("action","query") @wuiInputHidden("return","${QUERY_return}") @wuiInputHidden("return_from","${QUERY_return_from}") @wuiInputHidden("return_label","${QUERY_return_label}") @wuiInputHidden("synckey","${QUERY_synckey}") <table@htmlAttr("border","1") @htmlAttr("width","50%")> <tr@htmlAttr("onmouseover","enterRow(this);") @htmlAttr("onmouseout","exitRow(this);")> @bashCgiOutEnd() EVENODD="even"; even_odd '<td@htmlAttr("align","left")@htmlAttr("class","%s")>\n' @bashCgiOutBegin() @wuiInputRadio("host","pool.ntp.org","<span@htmlAttr("class","labeledFieldLabelRight")>On Internet (pool.ntp.org)</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("pool.ntp.org") to ${queryDomTT} the time...","${queryDomTTWidth}")") <br /> <span@htmlAttr("style","font-size: 80%;")>See: "@appExtRef("NTP Pool Project","http://www.pool.ntp.org/")"</span> </td> </tr> @bashCgiOutEnd() # # Dump hosts found in: "/etc/ntp.conf"... for s in $(/bin/awk -- '$1 == "server" { print $2 };' /etc/ntp.conf); do even_odd '<tr@htmlAttr("onmouseover","enterRow(this);") @htmlAttr("onmouseout","exitRow(this);")> <td@htmlAttr("align","left")@htmlAttr("class","%s")>\n' @bashCgiOutBegin() @wuiInputRadio("host","${s}","<span@htmlAttr("class","labeledFieldLabelRight")>${s}</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("${s}") to ${queryDomTT} the time...","${queryDomTTWidth}")") <br /> <span@htmlAttr("style","font-size: 80%;")> Server found in: "@bold("@tailLinkEval("/etc/ntp.conf","all","/etc/ntp.conf","../time/ntp_query.cgi",,"ASCII")")" </span> </td> </tr> @bashCgiOutEnd() done # # If ntpd is running, include probe... if [ "${NTPD_RUNNING}" = "true" ]; then even_odd '<tr@htmlAttr("onmouseover","enterRow(this);") @htmlAttr("onmouseout","exitRow(this);")> <td@htmlAttr("align","left")@htmlAttr("class","%s")>\n' @bashCgiOutBegin() @wuiInputRadio("host","127.0.0.1","<span@htmlAttr("class","labeledFieldLabelRight")>This NST Probe</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("127.0.0.1") to ${queryDomTT} the time...","${queryDomTTWidth}")") <br /> <span@htmlAttr("style","font-size: 80%;")> Checks @acroNTP() service on: "@bold("127.0.0.1")" </span> </td> </tr> @bashCgiOutEnd() fi # # Browser client... even_odd '<tr@htmlAttr("onmouseover","enterRow(this);") @htmlAttr("onmouseout","exitRow(this);")> <td@htmlAttr("align","left")@htmlAttr("class","%s")>\n' @bashCgiOutBegin() @wuiInputRadio("host","${REMOTE_ADDR}","<span@htmlAttr("class","labeledFieldLabelRight")>Your System</span>",,"@toolTipAttr("@jsn("Use") @jsqh("NTP") server: @jsdh("${REMOTE_ADDR}") to ${queryDomTT} the time...","${queryDomTTWidth}")") <br /> <span@htmlAttr("style","font-size: 80%;")> Checks @acroNTP() service on: "@bold("${REMOTE_ADDR}")" </span> </td> </tr> @bashCgiOutEnd() # # Custom... @bashCgiOutBegin() <tr@htmlAttr("onmouseover","enterRow(this);") @htmlAttr("onmouseout","exitRow(this);")> <td@htmlAttr("align","left") @htmlAttr("class","odd")> <table@htmlAttr("width","96%") @htmlAttr("border","0")> <colgroup> <col@htmlAttr("width","25%") @htmlAttr("align","left")> <col@htmlAttr("width","75%")> </colgroup> <tr> <td> @wuiInputRadio("host","custom","<span@htmlAttr("class","labeledFieldLabelRight")>Custom</span>","checked","@toolTipAttr("@jsn("Allows") one to @jsn("Specify") the \\'@jstc("IP Address","@toolTipEmphasis()")/@jstc("Host Name","@toolTipEmphasis()")\\' of an @jsdh("NTP") server used to ${queryDomTT} the time...","400")") </td> <td> @wuiInputText("custom_url","${NTP_CUSTOM_URL}","256","40","@toolTipAttr("@jsn("Enter") the \\'@jstc("IP Address","@toolTipEmphasis()")/@jstc("Host Name","@toolTipEmphasis()")\\' of an @jsdh("NTP") server used to ${queryDomTT} the time when the @jsqh("Custom") radio button is @jsn("Selected")...","430")") </td> </tr> </table> </td> </tr> @bashCgiOutEnd() # # If ntpd is NOT running, include option to set the probe's time if [ "${NTPD_RUNNING}" = "false" ]; then @bashCgiOutBegin() <tr> <td@htmlAttr("align","left") @htmlAttr("class","note")> <input@toolTipAttr("@jsn("Check") to @jsn("Set") the @jsqh("System Clock") for this @jsdh("NST") probe with the @jsn("Returned") @jsdh("Query Time") value...","400") @wuiInputCheckboxAttr("settime","yes") /> <span@htmlAttr("class","labeledFieldLabelRight")>Set @bold("System Clock") from returned query time.</span> </td> </tr> @bashCgiOutEnd() fi # # check box to include ntp tracing... @bashCgiOutBegin() <tr> <td@htmlAttr("align","left") @htmlAttr("class","note")> <input@toolTipAttr("@jsn("Check") to @jsn("Perform") an @jsqh("ntptrace") to the @jsn("Queried") @jsdh("NTP") server...","410") @wuiInputCheckboxAttr("ntptrace","checked") ${NTP_NTPTRACE} /> <span@htmlAttr("class","labeledFieldLabelRight")>Perform an @manPageLink("ntptrace").</span> </td> </tr> @bashCgiOutEnd() # # Add on submit button and finish up HTML @bashCgiOutBegin() </table> </form> @verticalGapSmall() <table@htmlAttr("border","0")> <tr> <td> @wuiButtonSubmit("queryformid","${BUTTON_LABEL}","@toolTipAttr("\\'@jstc("Query","@toolTipEmphasis()")/@jstc("Set","@toolTipEmphasis()")\\' the above @jsn("Selected") @jsdh("NTP") server...","310")") </td> <td> @wuiButtonSubmit("returnExit","${qrlt}","@toolTipAttr("${exit_hover_text}","${exit_hover_text_len}")") </td> </tr> </table> </center> @verticalGapSmall() @bashCgiOutEnd() # # Put in custom navigation at end @define("exitAnchor","") clock_navigation_section; @bashCgiEnd()