exit if ($not_running_Perl); #==========================================================# # Print introductory messages to the config.web installer. # #==========================================================# print <<'EOF'; This Perl script configures and installs web-based tools for viewing the SCA Ordinary and searching the SCA Armorial. This portion of the installation should be performed ON THE WEBSERVER. EOF $opt = shift; $Cgibin = 0; if ($opt eq '-c') { $Cgibin = 1; $opt = shift; } $Y = 'n'; if ($opt eq '-f') { $Y = 'y'; $opt = shift; } $Rcs = 0; if ($opt eq '-r') { $Rcs = 1; } %pages = ( 'SearchMenu', 'search menu:index', 'NameHintsPage', 'name search hints:hints_name', 'DateHintsPage', 'date search hints:hints_date', 'DescHintsPage', 'armory description search hints:hints_desc', 'NpHintsPage', 'name pattern search hints:hints_np', 'BpHintsPage', 'blazon pattern search hints:hints_bp', 'ComplexHintsPage', 'complex search hints:hints_complex', 'OverviewPage', 'about SCA heraldry:heraldry_overview', 'LimitPage', 'about search limits:search_limits', 'DownloadPage', 'about obtaining the database:data_obtain', 'DbFormatPage', 'about the database format:data_format', 'DbSymbolsPage', 'non-ASCII symbols:data_symbols' ); %scripts = ( 'Glossary', 'glossary:glossary', 'Copyright', 'database copyright:data_copyright', 'Version', 'database version:version', 'NameSearch', 'name search:oanda_name', 'DescSearch', 'armory description search:oanda_desc', 'NpSearch', 'name pattern search:oanda_np', 'BpSearch', 'blazon pattern search:oanda_bp', 'DateSearch', 'date/kingdom search:oanda_date', 'ComplexSearch', 'complex search:oanda_complex' # 'Correction', 'correction request:correction' ); #==============================================# # Functions specific to the config.web script. # #==============================================# # config.web function to install an HTML page in a file, # taking the path from %config. sub page_install { #global (%pages); local ($text, $tag) = @_; local ($what, $file) = split (/\:/, $pages{$tag}); &key_install ($text, $tag, 0444, $what); } # config.web function to install a CGI script in a file, # taking the path from %config. sub script_install { #global (%scripts); local ($text, $tag) = @_; local ($what, $file) = split (/\:/, $scripts{$tag}); &key_install ($text, $tag, 0555, $what); } # config.web function to print a list. sub print_list { local ($i) = 0; foreach $file (sort @_) { local ($what, $name) = split (/\:/, $file); printf " + %-35s", $what; if ($i++%2) { printf "\n"; } else { printf ' '; } } printf "\n" if ($i%2); } # config.web function to set the path and URL of an HTML page. sub set_page_info { #global (%config, %pages); local ($tag) = @_; local ($what, $file) = split (/\:/, $pages{$tag}); $config{'XX'.$tag.'PathXX'} = $config{'XXPagePathXX'} . "/$file.html"; $config{'XX'.$tag.'UrlXX'} = $config{'XXPageUrlXX' } . "/$file.html"; } # config.web function to set the path and URL of a CGI script. sub set_script_info { #global (%config, %scripts); local ($tag) = @_; local ($what, $file) = split (/\:/, $scripts{$tag}); $config{'XX'.$tag.'PathXX'} = $config{'XXScriptPathXX'} . "/$file.cgi"; $config{'XX'.$tag.'UrlXX'} = $config{'XXScriptUrlXX' } . "/$file.cgi"; } # config.web function to get the URL for an HTML page. sub get_html_url { #global (%config, $ServerName, $ServerPort); local ($tag, $what, $path) = @_; local ($url, $_); $url = $config{$tag}; if ($url eq '') { $url = $path; $url =~ s/^$DocumentRoot//; $url = "http://$ServerName:$ServerPort$url"; } print "\nURL for $what:\n[$url] "; $url = &input ($url); $config{$tag} = $url; return $url; } # config.web function to set the URL for a CGI script. sub get_cgi_url { #global (%config, $ServerName, $ServerPort, $Cgibin); local ($tag, $what, $path) = @_; local ($url, $_); $url = $config{$tag}; if ($url eq '') { $url = $path; if ($Cgibin) { $url =~ s/^$ScriptAlias//; $url = "http://$ServerName:$ServerPort/cgi-bin$url"; } else { $url =~ s/^$DocumentRoot//; $url = "http://$ServerName:$ServerPort$url"; } } print "\nURL for $what:\n[$url] "; $url = &input ($url); $config{$tag} = $url; return $url; } #===============================================# # Slurp hunks of text into config.web's memory. # #===============================================# # # config.web slurps common config functions into $Helpers. # $Helpers = <<'XXEOFXX'; # Common config function to advise user on machine questions. sub machine_questions { local ($pptag, $afitag, $sstag) = @_; print <<'EOF'; Now I need you to answer a few questions about this machine. For each question: + The default answer is given in [brackets]. + To override the default answer, enter the correct answer in the space next to the brackets. + To accept the default answer, enter a blank line. EOF # Set $PerlPath. &set_perl_path ($pptag); # Set $AF_INET and $SOCK_STREAM. &set_network_constants ($afitag, $sstag); } # Common config function to read input from terminal unless $Y is set to 'y'. sub input { #global ($Y); local ($_) = ''; local ($default) = @_; if ($Y eq 'y') { printf "\n"; } else { $_ = <>; } s/\s//g; $_ = $default if ($_ eq ''); return $_; } # Common config function to get AF_INET and SOCK_STREAM. sub set_network_constants { #global ($AF_INET, $SOCK_STREAM, %config); local ($tag_AF_INET, $tag_SOCK_STREAM) = @_; $AF_INET = $config{$tag_AF_INET}; $AF_INET = 2 if ($AF_INET eq ''); print <<'EOF'; What is the numeric code (AF_INET) defined for the Internet domain in `/usr/include/sys/socket.h'? EOF print "[$AF_INET] "; $AF_INET = &input ($AF_INET); $config{$tag_AF_INET} = $AF_INET; $SOCK_STREAM = $config{$tag_SOCK_STREAM}; $SOCK_STREAM = 1 if ($SOCK_STREAM eq ''); print <<'EOF'; What is the numeric code (SOCK_STREAM) defined for the `stream' socket type in `/usr/include/sys/socket.h'? EOF print "[$SOCK_STREAM] "; $SOCK_STREAM = &input ($SOCK_STREAM); $config{$tag_SOCK_STREAM} = $SOCK_STREAM; } # Common config function to read the configuration from $conf_file. sub read_config_file { #global (%config, $conf_file); local (*CONF, $_, $tag, $value); %config = (); if (-r $conf_file && open (CONF, $conf_file)) { print "\nReading previous configuration from $conf_file ..."; while () { next if (/^\#/); chop; ($tag, $value) = split (/\|/); $config{$tag} = $value; } close (CONF); print " done.\n"; } } # Common config function to save the configuration to $conf_file. sub save_config { #global (%config, $conf_file); local (*CONF, $tag, $value); if (open (CONF, ">$conf_file")) { print "\nSaving new configuration to $conf_file ..."; while (($tag, $value) = each %config) { printf CONF "%s|%s\n", $tag, $value; } close (CONF); print " done.\n"; } } # Common config function to configure a text string. sub configure { #global (%config); local ($tag, $value); local ($_) = @_; print "\nConfiguring $what.\n"; while (($tag, $value) = each %config) { s/$tag/$value/g; } return $_; } # Common config function to install a text string in a file, # taking the path from %config. sub key_install { #global (%config); local ($text, $tag, $mode, $what) = @_; &install ($text, $config{'XX'.$tag.'PathXX'}, $mode, $what); } # Common config function to install a text string in a file. sub install { #global ($Y); local ($text, $path, $mode, $what) = @_; $text = &configure ($text); printf "Installing $what at\n `$path'\n with mode 0%03o.\n", $mode; if (-e $path) { if (-w $path) { print "Is it okay to overwrite existing file\n `$path'? [$Y] "; $_ = &input ($Y); die "\nUnable to complete installation" unless (/^y/i); } elsif ($Rcs) { print "Checking out `$path'.\n"; system ('co', '-l', $path); die if ($?); } else { print "Is it okay to delete existing file\n `$path' first? [$Y] "; $_ = &input ($Y); die "\nUnable to complete installation" unless (/^y/i); unlink ($path) || die "Cannot delete `$path'"; } } &makeparent ($path, 0755); # Create (or overwrite) the file. open (OUT, ">$path") || die "Cannot open `$path' in sub install"; print OUT $text; close (OUT) || die "Cannot close `$path'"; # Set the permissions. chmod $mode, $path || die "Cannot chmod `$path'"; if ($Rcs) { print "Checking `$path' back in.\n"; system ('ci', '-u', $path); die if ($?); } } # Common config function to create directories needed for install. sub makeparent { local ($path, $mode) = @_; local ($parent); $path =~ m#^(.*)[/][^/]+[/]?$#; $parent = $1; return if ($parent eq ''); if (!-e $parent) { &makeparent ($parent, $mode); print "Creating `$parent'\n"; mkdir ($parent, $mode) || die "Cannot mkdir `$parent'"; } die "$parent is not a directory" unless (-d $parent); die "$parent is not writeable" unless (-w $parent); } # Common config function to set a path for installing a normal file. sub get_filepath { #global ($cwd, %config); local ($tag, $what, $default, $root) = @_; local ($path); while ($path eq '') { $path = $config{$tag}; $path = $default if ($path eq ''); $path = "$cwd/$path" if ($path =~ m#^[^/]#); print "\nLocal install-path of $what:\n[$path] "; $path = &input ($path); $path = "$cwd/$path" if ($path =~ m#^[^/]#); if (-e $path && !-f $path) { print "Sorry, `$path' exists and is not a normal file.\n"; print "Try again...\n"; $path = ''; } if (index ($path, $root) != $[) { print "Sorry, `$path' must be under `$root'.\n"; print "Try again...\n"; $path = ''; } } $config{$tag} = $path; return $path; } # Common config function to set a path for an installation directory. sub get_dirpath { #global ($cwd, %config); local ($tag, $what, $default, $root) = @_; local ($path); while ($path eq '') { $path = $config{$tag}; $path = $default if ($path eq ''); $path = "$cwd/$path" if ($path =~ m#^[^/]#); print "\nLocal directory for $what:\n[$path] "; $path = &input ($path); $path = "$cwd/$path" if ($path =~ m#^[^/]#); if (-e $path && !-d $path) { print "Sorry, `$path' exists and is not a directory.\n"; print "Try again...\n"; $path = ''; } if (index ($path, $root) != $[) { print "Sorry, `$path' must be under `$root'.\n"; print "Try again...\n"; $path = ''; } } $config{$tag} = $path; return $path; } # Common config function to set $PerlPath. sub set_perl_path { #global (%config, $PerlPath, $cwd); local ($tag) = @_; local ($default, $tmp, @apath, $done, $_); $default = $^X; if ($default =~ m#^[^/]#) { @apath = split (/:/, $ENV{'PATH'}, 9999); $tmp = $default; foreach (reverse @apath) { $default = "$_/$tmp" if (m#^[/]# && -x "$_/$tmp"); } } $done = 'no'; while ($done eq 'no') { $PerlPath = $config{$tag}; $PerlPath = $default if ($PerlPath eq ''); $PerlPath = "$cwd/$PerlPath" if ($PerlPath =~ m#^[^/]#); print <<'EOF'; What is the full pathname of the `Perl' executable on this machine? EOF print "[$PerlPath] "; $PerlPath = &input ($PerlPath); $PerlPath = "$cwd/$PerlPath" if ($PerlPath =~ m#^[^/]#); if (!-e $PerlPath) { print "Sorry, `$PerlPath' does not exist.\n"; } elsif (!-f $PerlPath) { print "Sorry, `$PerlPath' is not a normal file.\n"; } elsif (!-x $PerlPath) { print "Sorry, `$PerlPath' is not executable.\n"; } else { $done = 'yes'; } print "Try again...\n" if ($done eq 'no'); } $config{$tag} = $PerlPath; } # end of common config functions XXEOFXX # # config.web slurps up $SearchMenu. # $SearchMenu = <<'XXEOFXX'; Search Forms for the SCA Armorial XXHeadXX

Search Forms for the SCA Armorial

You can find currently-registered armory starting at the index for the on-line SCA Ordinary. If you are trying to look armory by its description, or doing conflict checking, you almost certainly want to start here.

There are also six search forms available:

  1. A Name Search Form which allows you to search the SCA Armorial database for items associated with a particular name. This form is fast and simple, but not very powerful. For instance, your search will fail if you don't type the name exactly right.

  2. An Armory Description Search Form which allows you to search for registered items that appear under a particular heading in the SCA Ordinary. This form is difficult to use because you must know how the headings are coded in the database. This difficulty will be corrected eventually, but for now the SCA Ordinary is much more useful.

  3. A Name Pattern Search Form which allows you to search for items associated with a name, even if you don't know the exact spelling of the name. Very useful.

  4. A Blazon Pattern Search Form which allows you to search for blazons containing particular words or text patterns.

  5. A Date/Kingdom Search Form which allows you to search for registrations during a particular time-period or via a particular kingdom.

  6. A Complex Search Form which allows you to do sophisticated searches on the database by combining the results of multiple searches. This form is tricky to use, because there are more things to configure.

You can also find currently-registered armory using the on-line SCA Ordinary.

Related Web Pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $NameHintsPage. # $NameHintsPage = <<'XXEOFXX'; Name Search Hints XXHeadXX

Name Search Hints

Here are some hints for using the Name Search Form. The purpose of the form is to find all items associated with a particular name. This form is fast and simple to use, but not convenient or powerful. In particular, your search will fail if you don't type the name exactly right.

The form has a text entry field and a "submit" button. You simply type the name you are looking for in the box then click on the button. For instance, you could type "John of Skye" (without the quotes) and click on the "submit" button. This should display the two registrations by John of Skye.

The name search form is case-sensitive, so "john of skye" won't work. Also, the spacing and hyphenation of the name must be exactly right, or the search will fail. If you are at all unsure of the spelling of the name you are looking for, try the Name Pattern Search Form instead.

If you are searching for a name containing accented characters or ligatures, you should use their nearest ASCII equivalents. For instance, to search for Edelgard Erzsébet von Württemberg you should type "Edelgard Erzsebet von Wurttemberg".

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $DateHintsPage. # $DateHintsPage = <<'XXEOFXX'; Date/Kingdom Search Hints XXHeadXX

Date/Kingdom Search Hints

Here are some hints for using the Date/Kingdom Search Form. The purpose of the form is to find all items registered during a particular period of time, through particular kingdoms of the SCA.

Search Criteria

  1. Select the inclusive starting and ending dates of the period of interest. With most browsers, months are selected from a menu, by dragging with the mouse. Years are selected by typing the common-era year (or the last two digits thereof) in the text-entry boxes.
  2. Select the kingdoms of interest. With most browsers, kingdoms are selected (or deselected) by clicking with the mouse on a box next to the Kingdom's name.

Maximum Number of Items to Display

You can control the size of your search result by typing a number of items (1-500) in this box. If you do not fill in the box, at most 25 items will be displayed. Note that there is a built-in limit of 500 items, which you cannot override.

Display Options

You can specify how you want your search results sorted. Currently there are two options: by name and by date. It is usually easiest to find items when they are sorted by name.

You can also specify whether you want dates shown in modern style (Common Era year/A.D.) or SCA style (Anno Societatis). The SCA calendar counts years from the SCA's "First Tournament" (1 May 1966) and traditionally uses Roman numerals.

You can also specify whether you want blazons to be displayed with links to the heraldic glossary. These links are helpful if you are unclear on the meanings of basic blazon terms.

Submitting the Search

The button at the bottom of the form marked "search for items matching the dates/kingdoms above" is used to launch the search. The server takes no action until you click on the button.

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $DescHintsPage. # $DescHintsPage = <<'XXEOFXX'; Armory Description Search Hints XXHeadXX

Armory Description Search Hints

Here are some hints for using the Armory Description Search Form.

The purpose of the form is to find all registered armory that matches a particular description, such as "FIELD DIV.-BENDY:complex line". It is used, for instance, to view a single category from the on-line SCA Ordinary.

Your search will probably fail if you don't type the description exactly right, so until a friendlier interface is available, you should probably access it only through the on-line SCA Ordinary.

The form has a text entry field and a "submit" button. Type the description you are looking for in the box, then click on the button. The armory description search form is case-sensitive.

A description consists of

The heading must always appear first, but the features may appear in any otder after it.

Here are some typical headings:

Here are some typical features:

Here are some examples of reasonable armory descriptions:

You can also find examples of valid descriptions by enabling the "Armory descriptions" option on the Blazon Pattern Search Form and doing a search.

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $NpHintsPage. # $NpHintsPage = <<'XXEOFXX'; Name Pattern Search Hints XXHeadXX

Name Pattern Search Hints

Here are some hints for using the Name Pattern Search Form. The purpose of the form is to find items associated with a name, even if you don't know the exact spelling of the name.

Patterns

The first text entry field is where you type the pattern. The simplest pattern is simply a portion of the name you are seeking. For instance, you could type "Peter" in this box to find all the names containing "Peter". This would bring up items such as Ulf Johannes Peter von Greiffenburg, and even Aelfwine of Peterborough.

You can specify that you want the pattern to appear at the beginning of the name, by placing a carat (^) in front of the pattern. For instance, you could type the pattern "^Peter" to find all names that begin with "Peter". This would exclude the examples above, but would match Peter Bentarrow, for instance.

You can specify that you want the pattern to appear at the end of the name by placing a dollar-sign ($) after the pattern. For instance, the pattern "wing$" would match Arthur Whitewing, for instance.

Some punctuation marks have special meaning in patterns. When your pattern includes punctuation marks such as periods (.) it is a good idea to put a backslash (\) in front of each punctuation mark. For instance, to search for names containing "St." you should use the pattern "St\.".

If you are unsure of a particular letter in a name, you can use wild-cards to find it quickly. For instance, if you are looking for someone Tatiana, you might use the pattern "Tat.ana" in case the person you were looking for happened to spell her name "Tatjana" or "Tatyana"; the period (.) matches any single character. Alternately, you could use "Tat[ijy]ana". The portion in square brackets matches a single character which must be one of the three listed (i, j, or y). To specify a wildcard that matches any character except whitespace, use "\S".

If there are multiple letters that you are unsure of, you can use multiple wildcards. For instance, "M\S\S\Swood" will match "Mirkwood", "Marewood", and "Muirwood". If you are unsure of the exact number of wildcards needed, a plus-sign (+) may be used after any wildcard to indicate repetions. For instance "M\S+wood" will match names containing "Mirkwood", "Maplewood", "Marionwood" and so on.

You can specify accented characters or ligatures in a "narrow" search (see below) by typing a backslash (\) followed by the three-digit "Oct" code. For instance, to find "Æthelric" you can type the pattern "\306thelric".

Search Types

You can specify a name search that is "broad" or "narrow". A broad search finds all items associated with a name. A narrow search excludes those items in which the name appears only as the owner of an order, title, household, or alternate name, as the target of a cross-reference, name-change, or transfer, or as the designation or joint holder of a badge. A broad search often finds more items than a narrow one; since this may or may not be what you want, both types of search are available.

Another difference between broad and narrow searches is in their handling of accented characters and ligatures. In broad searches (as in the name search form) non-ASCII symbols are reduced to their nearest ASCII equivalents. For instance, "Æthelric" is treated exactly like "AEthelric". In narrow searches the "Æ" is treated as a single character which matches "\306" but not "A" nor "E".

You can specify a name search that is "case-sensitive" or "case-insensitive". A case-sensitive search differentiates upper-case and lower-case letters. For instance, the name pattern "And" would match "Andrew" but not "Holland". In case-insensitive search would treat "A" and "a" as being the same, so that "And" would match both "Andrew" and "Holland".

Maximum Number of Items to Display

You can control the size of your search result by typing a number of items (1-500) in this box. If you do not fill in the box, at most 25 items will be displayed. Note that there is a built-in limit of 500 items, which you cannot override.

Display Options

You can specify how you want your search results sorted. Currently there are two options: by name and by date. It is usually easiest to find names when they are sorted by name, but you might want to sort by date if the item you are looking for is particularly old or particularly recent.

You can also specify whether you want dates shown in modern style (Common Era year/A.D.) or SCA style (Anno Societatis). The SCA calendar counts years from the SCA's "First Tournament" (1 May 1966) and traditionally uses Roman numerals.

You can also specify whether you want blazons to be displayed with links to the heraldic glossary. These links are helpful if you are unclear on the meanings of basic blazon terms.

Submitting the Search

The button at the bottom of the form marked "search for items matching the name pattern" is used to launch the search. The server takes no action until you click on the button.

Related Web Pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $BpHintsPage. # $BpHintsPage = <<'XXEOFXX'; Blazon Pattern Search Hints XXHeadXX

Blazon Pattern Search Hints

Here are some hints for using the Blazon Pattern Search Form. The purpose of the form is to find registered blazons that contain particular words or patterns.

Patterns

The first text entry field is where you type the pattern. The simplest pattern is simply a portion of the blazon you are seeking. For instance, you could type "bat" in this box to find all the blazons containing "bat". This would bring up not only blazons containing the word "bat", but also those containing words such as "batwing", "embattled", "combattant", and "baton".

You can seach for blazons that contain a particular word by sandwiching the word between "\b"s. ("\b" matches any word-boundary.) For instance, you could type the pattern "\bbat\b" to find all blazons containing the word "bat" ignoring words like "combattant" and "bats".

You can specify that you want the pattern to appear at the beginning of a word by placing "\b" in front of the pattern. For instance, you could type the pattern "\bbat" to find all items with batons, bats, and batwings, while ignoring words like "combattant" and "embattled".

You can specify that you want the pattern to appear at the beginning of the blazon by placing a carat (^) in front of the pattern. For instance, you could type the pattern "^Or" to find all registered items with fields Or.

Some punctuation marks have special meaning in patterns. When your pattern includes punctuation marks such as periods (.), question marks (?), or parentheses, it is a good idea to put a backslash (\) in front of each punctuation mark. For instance, to search for names containing "St." you should use the pattern "St\.".

Some common blazon-terms are not consistently spelled. For instance, if you are looking for the word "fleur-de-lys", you might use the pattern "\bfleur-de-l.s\b" to catch both common spellings of the word (fleur-de-lys, fleur-de-lis); the period (.) matches any single character. Alternately, you could use "\bfleur-de-l[iy]s". The portion in square brackets matches a single character which must be one of the two listed (i or y). To specify a wildcard that matches any character except whitespace, use "\S".

If there are multiple letters that you are unsure of, you can use multiple wildcards. If you are unsure of the exact number of wildcards needed, a plus-sign (+) may be used after any wildcard to indicate repetion. For instance, the pattern "\bchevron\b.+\bgules\b" matches any blazon that contains the words "chevron" and "gules" in that order.

You can specify accented characters (such as the ê in vêtu) by typing a backslash (\) followed by the three-digit "Oct" code. For instance, to find "vêtu" you can type the pattern "v\353tu".

Search Types

You can specify a name search that is "case-sensitive" or "case-insensitive". A case-sensitive search differentiates upper-case and lower-case letters. For instance, the pattern "or" would match "gore" but not "Or". A case-insensitive search would treat "O" and "o" as being the same, so that "or" would match both "gore" and "Or".

Maximum Number of Items to Display

You can control the size of your search result by typing a number of items (1-500) in this box. If you do not fill in the box, at most 25 items will be displayed. Note that there is a built-in limit of 500 items, which you cannot override.

Display Options

You can specify how you want your search results sorted. Currently there are three sort options: by name, by date, and by blazon. You might want to sort by date if you know that the item you are looking for is particularly old.

You can also specify whether you want dates to be shown in modern style (Common Era year/A.D.) or SCA style (Anno Societatis). The SCA calendar counts years from the SCA's "First Tournament" (1 May 1966) and traditionally uses Roman numerals.

You can also specify whether you want blazons to be displayed with links to the heraldic glossary. These links are helpful if you are unclear on the meanings of basic blazon terms.

Submitting the Search

The button at the bottom of the form marked "search for items matching the blazon pattern" is used to launch the search. No action is taken by the server until you click on the button.

Related Web Pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $ComplexHintsPage. # $ComplexHintsPage = <<'XXEOFXX'; Complex Search Hints XXHeadXX

Complex Search Hints

Here are some hints for using the Complex Search Form. The purpose of the form is to combine several search methods into a single search. Before using this form, you should familiarize yourself with the following search methods:

Scoring Criteria

This portion of the form allows you to specify up to five search criteria in order to find the registration(s) of interest to you. A certain number of registrations will match each criterion. Usually, the result of a complex search consists of all registrations which match one or more of the criteria specified.

In a search with multiple criteria, you may only be interested in registrations which match all the criteria. These are, of course, included in the result. To make these registrations easy to locate, each item in the search result is given a score based on how many criteria it satisfied. Items matching all the criteria naturally have the highest score; when you sort the results by their score, you can easily locate these items.

Sometimes you may want to give some criteria more weight than others. For instance, suppose you are looking for a registration connected the name "Alaric" which probably contains a chief (but you're less certain of the charge). In this case, you want the search results to appear in the following order:

  1. registrations containing "Alaric" and a chief
  2. registrations containing "Alaric" but no chief
  3. other registrations
You can achieve this results by giving the name pattern criterion a weight of 20 and the armory-description search a weight of only 10.

There are currently four methods available for specifying criteria:

Maximum Number of Items to Display

You can control the size of your search result by typing a number of items (1-500) in this box. If you do not fill in the box, at most 25 items will be displayed. Note that there is a built-in limit of 500 items, which you cannot override.

Display Options

You can specify how you want your search results sorted. Currently there are two options: by name and by date. It is usually easiest to find names when they are sorted by name. You might want to sort by date if you know that the item you are looking for is particularly old.

You can also specify whether you want dates shown in modern style (Common Era year/A.D.) or SCA style (Anno Societatis). The SCA calendar marks time from the "First Tournament" (1 May 1966) and its years are traditionally noted in Roman numerals.

Submitting the Search

The button at the bottom of the form marked "search for items matching the name pattern" is used to launch the search. The server takes no action until you press the button.

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $OverviewPage. # $OverviewPage = <<'XXEOFXX'; About SCA Heraldry XXHeadXX

About SCA Heraldry

Names and Armory

To enhance the medieval ambiance of SCA events, participants typically adopt pseudonyms and heraldic insignia with a medieval flavor, which they use on a long-term basis. Thus a person whose legal name is "John Doe" might choose to be known as "Hrolf Einarsson" to his SCA friends. And at SCA tournaments and wars he might bear a device on his sheild consisting of six black lions on a gold background.

An SCA device is a heraldic insignia which used to indicate that the owner of the device is present. The SCA uses the word armory to refer to heraldic insignia in general.

Participants generally select their own SCA name. It is considered bad form to assume a name too reminiscent of another participant or any famous person, be they modern, historical, or fictitious. Also, intrusively modern names should be avoided. Armory, too, must be chosen with care to avoid modern-style designs and designs that make inappropriate claims.

Every chapter of the SCA has an officer, called a herald or pursuivant to assist participants in choosing appropriate names and armory.

Registration

To reduce the chances of confusion or offense caused by inappropriate names and armory, the SCA has organized a registration service, to which participants may submit their proposed names and armory for approval. In addition, the SCA registers names and armory for SCA chapters (or branches), their officers and titled nobility, and the honors they may bestow on participants.

The registration process is administered by the SCA's own "College of Arms".

The SCA Armorial

An armorial is a reference book containing coats of arms, arranged alphabetically by their bearer's names. The SCA Armorial is an armorial of insignia registered with the College of Arms. It also lists registered names for individuals and groups that have no registered insignia. It is available as a 670-page loose-leaf document or as a 6 MB text-file. Search forms for the SCA Armorial enable access via the World Wide Web.

The SCA Ordinary

An ordinary is a reference book containing coats of arms, arranged in descriptive categories. The SCA Ordinary is an ordinary of insignia registered with the College of Arms. It is available as a 1000-page loose-leaf document and as a World Wide Web document.

Court and Voice Heraldry

SCA events may feature courts, tournaments, and other activities. A court is a general audience granted by a high-ranking SCA noble for the purpose of doing official business. The organization of courts is the resposibility of court heralds.

SCA heralds also assist the running of events by making public announcements, especially at tournaments. For instance, a herald is typically employed to announce the combattants before each bout of a tournament.

Since amplification is not used at SCA events, vocal training is very helpful for court and tournament work, which is called voice heraldry.

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $LimitPage. # $LimitPage = <<'XXEOFXX'; Search Limits XXHeadXX

Search Limits

The name pattern search form, blazon pattern search form, and complex search form each allow you to set a limit on the number of returned items. On these forms, if you do not specify a limit, your results will be limited to 25 items.

If your search is limited, you will see a message such as:

There were n other items for which details are not available, due to the limit feature.

at the bottom of your results listing. In this case, the item you were looking for may be one of the ones that was cut from the listing. There are several things you might do next: XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $DownloadPage. # $DownloadPage = <<'XXEOFXX'; SCA Armorial Database XXHeadXX

Obtaining the SCA Armorial Database

The database used by the search forms is the same data that is used to generate the printed SCA Armorial and SCA Ordinary. It is a flat text file roughly 6 megabytes in size. The file format is documented online.

The database is protected by copyright, but that broad blanket permissions have been granted for verbatim redistribution and personal use. See the copyright notice for details.

You should be able to download the database via HTTP from XXWebDataUrlXX (not compressed). XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $DbFormatPage. # $DbFormatPage = <<'XXEOFXX'; Format of the SCA Armorial Database XXHeadXX

Format of the SCA Armorial Database

by Iulstan Sigewealding
9 December 1998

This document describes the format used to record names and armory in the SCA Armorial Database. The database is actually a flat text file. The text is mostly ASCII, with a few Latin-1 encodings. (Latin-1 is an extension of ASCII and is an international standard. Unfortunately, its 8-bit codes are NOT compatible with the "437" code page normally active on PCs running MS-DOS in the United States.)

The file consists of a copyright notice followed by records.

NOTICE

The copyright notice begins with a line that reads "NOTICE:" and ends with a line that reads "END OF NOTICE." The records begin immediately after the end-of-notice.

RECORDS

Each record occupies a single line in the file, and each line contains one record. A record has at least five fields, separated by stiles (`|'). The five required fields are: name, source, type, text, and notes, in that order.

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $DbSymbolsPage. # $DbSymbolsPage = <<'XXEOFXX'; Title XXHeadXX

Non-ASCII Symbols in the SCA Armorial Database

by Iulstan Sigewealding
26 June 1999

Since January 1996, the SCA Ordinary database (oanda.db) has begun to encode non-ASCII symbols in names and blazons. The encoding is mostly complete for items registered since July 1980, but only sporadic before that date. In other words, over 90% of the database has been revised.

When a Latin-1 encoding exists, the non-ASCII symbol is encoded in accordance with that standard. The resulting code is an 8-bit byte with the most-significant bit set to 1, as detailed in the table below. (Unfortunately, these 8-bit codes are NOT compatible with the "437" code page normally active on PCs running MS-DOS in the United States.)

The columns in the table are as follows:

 Cnt Dec Oct Hx   Eq Daud Name..................................
   7 192 300 C0 À A  {'A} LATIN CAPITAL LETTER A WITH GRAVE
  54 193 301 C1 Á A  {A'} LATIN CAPITAL LETTER A WITH ACUTE
   3 194 302 C2 Â A  {A^} LATIN CAPITAL LETTER A WITH CIRCUMFLEX
  15 196 304 C4 Ä A  {A:} LATIN CAPITAL LETTER A WITH DIAERESIS
   6 197 305 C5 Å A  {Ao} LATIN CAPITAL LETTER A WITH RING ABOVE
 196 198 306 C6 Æ AE {AE} LATIN CAPITAL LIGATURE AE
   1 199 307 C7 Ç C  {C,} LATIN CAPITAL LETTER C WITH CEDILLA
 134 201 311 C9 É E  {E'} LATIN CAPITAL LETTER E WITH ACUTE
  12 205 315 CD Í I  {I'} LATIN CAPITAL LETTER I WITH ACUTE
   2 206 316 CE Î I  {I^} LATIN CAPITAL LETTER I WITH CIRCUMFLEX
   1 208 320 D0 Ð Dh {Dh} LATIN CAPITAL LETTER ETH
   6 210 322 D2 Ò O  {'O} LATIN CAPITAL LETTER O WITH GRAVE
 208 211 323 D3 Ó O  {O'} LATIN CAPITAL LETTER O WITH ACUTE
  18 214 326 D6 Ö O  {O:} LATIN CAPITAL LETTER O WITH DIAERESIS
  23 216 330 D8 Ø O  {O/} LATIN CAPITAL LETTER O WITH STROKE
  26 218 332 DA Ú U  {U'} LATIN CAPITAL LETTER U WITH ACUTE
   1 221 335 DD Ý Y  {Y'} LATIN CAPITAL LETTER Y WITH ACUTE
  17 222 336 DE Þ Th {Th} LATIN CAPITAL LETTER THORN
  10 223 337 DF ß s  {sz} LATIN SMALL LETTER SHARP S
  70 224 340 E0 à a  {'a} LATIN SMALL LETTER A WITH GRAVE
1280 225 341 E1 á a  {a'} LATIN SMALL LETTER A WITH ACUTE
  46 226 342 E2 â a  {a^} LATIN SMALL LETTER A WITH CIRCUMFLEX
   1 227 343 E3 ã a  {a~} LATIN SMALL LETTER A WITH TILDE
 288 228 344 E4 ä a  {a:} LATIN SMALL LETTER A WITH DIAERESIS
  57 229 345 E5 å a  {ao} LATIN SMALL LETTER A WITH RING ABOVE
 121 230 346 E6 æ ae {ae} LATIN SMALL LIGATURE AE
  48 231 347 E7 ç c  {c,} LATIN SMALL LETTER C WITH CEDILLA
 176 232 350 E8 è e  {'e} LATIN SMALL LETTER E WITH GRAVE
1250 233 351 E9 é e  {e'} LATIN SMALL LETTER E WITH ACUTE
  68 234 352 EA ê e  {e^} LATIN SMALL LETTER E WITH CIRCUMFLEX
  23 235 353 EB ë e  {e:} LATIN SMALL LETTER E WITH DIAERESIS
  15 236 354 EC ì i  {'i} LATIN SMALL LETTER I WITH GRAVE
1011 237 355 ED í i  {i'} LATIN SMALL LETTER I WITH ACUTE
  14 238 356 EE î i  {i^} LATIN SMALL LETTER I WITH CIRCUMFLEX
   3 239 357 EF ï i  {i:} LATIN SMALL LETTER I WITH DIAERESIS
 102 240 360 F0 ð dh {dh} LATIN SMALL LETTER ETH
  40 241 361 F1 ñ n  {n~} LATIN SMALL LETTER N WITH TILDE
  61 242 362 F2 ò o  {'o} LATIN SMALL LETTER O WITH GRAVE
 616 243 363 F3 ó o  {o'} LATIN SMALL LETTER O WITH ACUTE
  28 244 364 F4 ô o  {o^} LATIN SMALL LETTER O WITH CIRCUMFLEX
 391 246 366 F6 ö o  {o:} LATIN SMALL LETTER O WITH DIAERESIS
 104 248 370 F8 ø o  {o/} LATIN SMALL LETTER O WITH STROKE
  28 249 371 F9 ù u  {'u} LATIN SMALL LETTER U WITH GRAVE
 192 250 372 FA ú u  {u'} LATIN SMALL LETTER U WITH ACUTE
  30 251 373 FB û u  {u^} LATIN SMALL LETTER U WITH CIRCUMFLEX
 331 252 374 FC ü u  {u:} LATIN SMALL LETTER U WITH DIAERESIS
  28 253 375 FD ý y  {y'} LATIN SMALL LETTER Y WITH ACUTE
   4 254 376 FE þ th {th} LATIN SMALL LETTER THORN
   2 255 377 FF ÿ y  {y:} LATIN SMALL LETTER Y WITH DIAERESIS

Twenty-nine of the rarer symbols do not have Latin-1 encodings. In the database, these symbols have been reduced to the nearest ASCII equivalent:

 Cnt Eq Daud Name................................
   4 C  {Cv} LATIN CAPITAL LETTER C WITH CARON
   2 OE {OE} LATIN CAPITAL LIGATURE OE
   3 S  {S'} LATIN CAPITAL LETTER S WITH ACUTE
   3 S  {Sv} LATIN CAPITAL LETTER S WITH CARON
   8 Z  {Zv} LATIN CAPITAL LETTER Z WITH CARON
  12 a  {a-} LATIN SMALL LETTER A WITH MACRON
   2 b  {b-} LATIN SMALL LETTER B WITH TOPBAR
   8 c  {cv} LATIN SMALL LETTER C WITH CARON
   2 e  {e,} LATIN SMALL LETTER E WITH OGONEK
  12 e  {e-} LATIN SMALL LETTER E WITH MACRON
   2 e  {ev} LATIN SMALL LETTER E WITH CARON
  16 i  {i-} LATIN SMALL LETTER I WITH MACRON
   1 l  {l/} LATIN SMALL LETTER L WITH STROKE
   7 m  {m.} LATIN SMALL LETTER M WITH DOT BELOW
   1 n  {n'} LATIN SMALL LETTER N WITH ACUTE
   7 n  {n.} LATIN SMALL LETTER N WITH DOT BELOW
   9 o  {o,} LATIN SMALL LETTER O WITH OGONEK
   5 o  {o-} LATIN SMALL LETTER O WITH MACRON
   1 oe {oe} LATIN SMALL LIGATURE OE
   9 r  {rv} LATIN SMALL LETTER R WITH CARON
   7 s  {s.} LATIN SMALL LETTER S WITH DOT BELOW
   4 s  {sv} LATIN SMALL LETTER S WITH CARON
   2 u  {u,} LATIN SMALL LETTER U WITH OGONEK
  10 u  {u-} LATIN SMALL LETTER U WITH MACRON
   7 w  {w^} LATIN SMALL LETTER W WITH CIRCUMFLEX
   2 y  {y^} LATIN SMALL LETTER Y WITH CIRCUMFLEX
   1 y  {y~} LATIN SMALL LETTER Y WITH TILDE
   6 z  {z'} LATIN SMALL LETTER Z WITH ACUTE
   6 z  {zv} LATIN SMALL LETTER Z WITH CARON

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up master index page for Ordinary. # $IndexPage = <<'XXEOFXX'; Online SCA Ordinary - Master Index XXHeadXX

Online SCA Ordinary - Master Index

Select the first letter of the category you wish to view:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Related web pages:

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter A. # $IndexPage{'A'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter A XXHeadXX

Index of the SCA Ordinary - The Letter A

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter B. # $IndexPage{'B'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter B XXHeadXX

Index of the SCA Ordinary - The Letter B

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter C. # $IndexPage{'C'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter C XXHeadXX

Index of the SCA Ordinary - The Letter C

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter D. # $IndexPage{'D'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter D XXHeadXX

Index of the SCA Ordinary - The Letter D

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter E. # $IndexPage{'E'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter E XXHeadXX

Index of the SCA Ordinary - The Letter E

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter F. # $IndexPage{'F'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter F XXHeadXX

Index of the SCA Ordinary - The Letter F

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter G. # $IndexPage{'G'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter G XXHeadXX

Index of the SCA Ordinary - The Letter G

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter H. # $IndexPage{'H'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter H XXHeadXX

Index of the SCA Ordinary - The Letter H

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter I. # $IndexPage{'I'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter I XXHeadXX

Index of the SCA Ordinary - The Letter I

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter J. # $IndexPage{'J'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter J XXHeadXX

Index of the SCA Ordinary - The Letter J

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter K. # $IndexPage{'K'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter K XXHeadXX

Index of the SCA Ordinary - The Letter K

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter L. # $IndexPage{'L'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter L XXHeadXX

Index of the SCA Ordinary - The Letter L

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter M. # $IndexPage{'M'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter M XXHeadXX

Index of the SCA Ordinary - The Letter M

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter N. # $IndexPage{'N'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter N XXHeadXX

Index of the SCA Ordinary - The Letter N

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter O. # $IndexPage{'O'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter O XXHeadXX

Index of the SCA Ordinary - The Letter O

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter P. # $IndexPage{'P'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter P XXHeadXX

Index of the SCA Ordinary - The Letter P

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter Q. # $IndexPage{'Q'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter Q XXHeadXX

Index of the SCA Ordinary - The Letter Q

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter R. # $IndexPage{'R'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter R XXHeadXX

Index of the SCA Ordinary - The Letter R

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter S. # $IndexPage{'S'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter S XXHeadXX

Index of the SCA Ordinary - The Letter S

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter T. # $IndexPage{'T'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter T XXHeadXX

Index of the SCA Ordinary - The Letter T

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter U. # $IndexPage{'U'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter U XXHeadXX

Index of the SCA Ordinary - The Letter U

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter V. # $IndexPage{'V'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter V XXHeadXX

Index of the SCA Ordinary - The Letter V

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter W. # $IndexPage{'W'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter W XXHeadXX

Index of the SCA Ordinary - The Letter W

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter X. # $IndexPage{'X'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter X XXHeadXX

Index of the SCA Ordinary - The Letter X

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter Y. # $IndexPage{'Y'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter Y XXHeadXX

Index of the SCA Ordinary - The Letter Y

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up index page for the letter Z. # $IndexPage{'Z'} = <<'XXEOFXX'; Index of the SCA Ordinary - The Letter Z XXHeadXX

Index of the SCA Ordinary - The Letter Z

XXTrailerXX XXTrailer2XX XXCloseHtmlXX XXEOFXX # # config.web slurps up $GlossaryScript. # $GlossaryScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a lookup on the glossary of heraldic terms. # It is to be installed at XXGlossaryPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXGlossaryUrlXX'; # Set title for form. $form_title = 'Heraldic Glossary'; require 'XXCommonClientPathXX'; # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $p = $right if ($left eq 'p'); } %definition = ( 'Or', '#adj. (usually capitalized) in yellow or gold.', 'abased', '#adj. moved downward from its usual position (a chevron abased).', 'addorsed', '#adj. (of charges or wings) arranged back-to-back.', 'affronty', '#adj. (of creatures) seen from the front.', 'alaunt', '#n. a type of dog.', 'annulet', '#n. a circular ring.', 'antelope', '#n. a monster with the body of a stag, the tail of a unicorn, and a tusked nose. #n. (natural antelope) a straight-horned deer.', 'appaumy', '#adj. (of a hand) with the palm toward the viewer.', 'argent', '#adj. in white or silver.', 'armed', '#adj. having means of defense (beak, claws, horns, teeth, etc.) especially if they are in a contrasting tincture.', 'arrondi', '#adj. spiraling around the center (gyronny arrondi).', 'azure', '#adj. in blue.', 'barbed', '#adj. (of an arrow) having barbs of a contrasting tincture.', 'barrulet', '#n. a very narrow horizontal stripe across the middle.', 'barry', '#adj. divided into an even number of horizontal stripes of different tinctures.', 'bar', '#n. a narrow horizontal stripe across the middle.', 'bascinet', '#n. a close-fitting helmet.', 'base', '#n. a horizontal stripe covering the bottom point of the shield (a base azure). #n. the bottom portion of the shield (to base, in base).', 'baton sinister', '#n. a narrow diagonal stripe connecting the viewer\'s upper right and lower left.', 'battle axe', '#n. a spiked axe with a single outward-curving blade.', 'beaked', '#adj. having a beak in a contrasting tincture.', 'bellied', '#adj. having the belly in a contrasting tincture.', 'bendlet', '#n. a narrow diagonal stripe connecting the viewer\'s upper left and lower right.', 'bendwise sinister', '#adj. (of a charge) oriented so that the long axis lies diagonally, facing the viewer\'s upper right.', 'bendwise', '#adj. (of a charge) oriented so that the long axis lies diagonally, facing the viewer\'s upper left.', 'bendy', '#adj. divided into an even number of diagonal stripes oriented as a bend.', 'bend', '#n. a broad diagonal stripe connecting the viewer\'s upper left and lower right.', 'bezanty', '#adj. strewn with an indeterminate number of yellow or gold circular disks.', 'bezant', '#n. a yellow or gold circular disc.', 'billet', '#n. a charge representing a slab of wood, drawn as a featureless rectangle.', 'blazon', '#n. a heraldic description of a design. #vb. to describe a design in heraldic language.', 'bleu celeste', '#adj. in sky-blue.', 'bordure', '#n. a thick stripe covering all edges of the shield.', 'brunatre', '#adj. in brown.', 'canton', '#n. a large, square figure covering the corner in the viewer\'s upper left. #n. the corner in the viewer\'s upper left (in canton).', 'cartouche', '#n. an oval with straight sides.', 'celtic cross', '#n. a cross debruised by a small annulet.', 'cendree', '#adj. in light grey.', 'charged', '#adj. having another charge placed so it lies entirely on the first (a roundel charged with a mullet).', 'charge', '#n. an object or figure used as a distinct element of a heraldic design. #vb. to place a charge so that it lies entirely on another.', 'checky', '#adj. divided in a checker-board pattern with two tinctures.', 'chevron', '#n. a bent stripe that runs from side to side, rising to a sharp corner in the middle.', 'chief', '#n. a horizontal stripe covering the top edge of the shield (a chief gules). #n. the upper portion of the shield (in chief, to chief).', 'compass rose', '#n. a figure used to indicate the cardinal directions in a map.', 'compass star', '#n. a star with eight alternately long and short straight rays.', 'conjoined', '#adj. (of charges) touching.', 'contourny', '#adj. (of a creature or head) turned to the viewer\'s right (a raven contourny).', 'cotised', '#adj. (of an ordinary) flanked by two very narrow stripes, one to each side.', 'counterchanged', '#adj. (of a charge) in the same two tinctures as the underlying area, but the tinctures transposed.', 'counterermine', '#adj. in black, powdered with white or silver ermine spots.', 'couped', '#adj. (of a charge) the end(s) severed with a straight cut (a chevron couped).', 'courant', '#adj. (of a creature) running to the left, with all limbs in the air.', 'cross', '#n. an ordinary formed by two stripes, one vertical and one horizontal, that cross each other in the middle (a cross engrailed). #n. any of numerous conventional representation of the instrument upon which Jesus died (a Celtic cross).', 'crux ansata', '#n. a cross with the upper limb replaced by a loop, in other words, an ankh.', 'debruised', '#adj. partly obscured by a charge that lies partly on the field.', 'debruising', '#adj. partly obscuring another a charge but not lying entirely on it.', 'decrescent', '#n. a crescent with its opening to the viewer\'s right.', 'delf', '#n. a solid square.', 'dexter chief', '#n. the corner in the viewer\'s upper left.', 'dexter', '#n. the side to the viewer\'s left, which would be the shield-bearer\'s right. #adj. (of a left-right pair) right (a dexter glove).', 'displayed', '#adj. (of a creature) with its belly toward the viewer and its limbs splayed outward like a mounted butterfly (an eagle displayed).', 'dovetailed', '#adj. (of an edge) drawn with in a pattern resembling a dovetail joint.', 'drakkar', '#n. a Viking longship.', 'eclipsed', '#adj. (of a sun) obscured by a round disk of a contrasting tincture.', 'embattled', '#adj. (of an edge) drawn so as to resemble the battlements of a castle or a square wave.', 'emblazon', '#n. a graphical portrayal of a heraldic design. #vb. to portray a heraldic design graphically.', 'embowed', '#adj. bent.', 'endorsed', '#adj. (of a pale) flanked by two very narrow vertical stripes, one to each side.', 'engrailed', '#adj. (of an edge) drawn with circular bites taken from it.', 'erased', '#adj. (of a limb) severed with a jagged cut.', 'ermine spot', '#n. any conventional representation of the tail of an ermine.', 'ermines', '#adj. in black, powdered with white or silver ermine spots. #pl. n. weasels prized for their fur.', 'ermine', '#adj. in white or silver, powdered with black ermine spots. #n. a weasel prized for its fur.', 'erminois', '#adj. in yellow or gold, powdered with black ermine spots.', 'estencele', '#adj. strewn with triangular groupings of three dots, representing sparks.', 'estoile', '#n. a charge, representing a star, composed of wavy rays (usually six) radiating from a common center.', 'fesswise', '#adj. (of charges) oriented so that the long axis lies horizontally, facing to the viewer\'s left.', 'fess', '#n. a broad horizontal stripe across the middle of the shield.', 'fieldless', '#adj. a design which may be presented on any background, for example, a maker\'s mark.', 'field', '#n. the background of a heraldic design.', 'fimbriated', '#adj. surrounded by a thin outline with a contrasting tincture.', 'flaunches', '#n. large, rounded figures covering each side of the shield.', 'fret', '#n. a saltire interlaced with a mascle.', 'fructed', '#adj. (of a plant) bearing fruits or nuts, possibly in a contrasting tincture.', 'golpe', '#n. a purple circular disk.', 'goute', '#adj. a teardrop.', 'goutty', '#adj. strewn with an indeterminate number of teardrops.', 'guardant', '#adj. (of a creature) looking toward the viewer.', 'gules', '#adj. in red.', 'gunstone', '#n. a black circular disk.', 'gyron', '#n. a wedge-shaped figure reaching half-way across the shield.', 'gyronny', '#adj. divided into many parts by lines issuant from a central point.', 'harpy', '#n. a vulture with human head and breasts.', 'haurient', '#adj. swimming toward the top of the shield.', 'hurty', '#adj. strewn with an indeterminate number of blue circular disks.', 'hurt', '#n. a blue circular disk.', 'in annulo', '#adj. (of charges) arranged as if lying on an invisible circular ring.', 'in base', '#adj. (of charges) placed in the bottom of the shield.', 'in bend', '#adj. (of charges) arranged as if lying on an invisible bend.', 'in canton', '#adj. (of charges) placed in the viewer\'s upper left.', 'in chief', '#adj. (of charges) arranged as if lying on an invisible chief.', 'in cross', '#adj. (of charges) arranged as if lying on an invisible cross.', 'in fess', '#adj. (of charges) arranged as if lying on an invisible fess.', 'in pale', '#adj. (of charges) arranged as if lying on an invisible pale.', 'in saltire', '#adj. (of charges) arranged as if lying on an invisible saltire.', 'increscent', '#n. a crescent with its opening to the viewer\'s left.', 'indented', '#adj. (of edges) drawn so as to represent the teeth of a saw.', 'invected', '#adj. (of edges) drawn with circular bumps issuing from it.', 'inverted', '#adj. (of charges) having top and bottom transposed (a chevron inverted).', 'issuant', '#adj. (of charges) appearing to issue or emerge (issuant from chief).', 'label', '#n. a horizontal stripe with an embattled or dovetailed lower edge.', 'latin cross', '#n. a cross with the lower limb extended.', 'leaved', '#adj. (of plants) having leaves, often in a contrasting tincture.', 'lion', '#n. a ferocious cat with small rounded ears, long tongue and tail, and tufts of fur all over its body.', 'lozenge', '#n. a solid, conventional represenation of a diamond, namely, a rhombus standing on end.', 'lozengy', '#n. divided into diamond-shaped pieces by diagonal lines.', 'martlet', '#n. a bird with tufts of feathers in place of feet.', 'mascle', '#n. a hollow, conventional representation of a diamond, namely, a rhombus standing on end.', 'maunch', '#n. a charge representing the long sleeve of a gown.', 'mound', '#n. a symbol of royal authority consisting of a jewelled ball topped with a cross.', 'mount', '#n. an rounded figure covering the bottom point of the shield, a base enarched.', 'mullet', '#n. a charge representing a star or spur rowel, composed of a symmetric arrangement of straight rays or points.', 'naiant', '#adj. swimming to the viewer\'s left.', 'ogress', '#n. a black circular disk.', 'on', '#prep. obscuring part of (on a fess).', 'ordinary', '#n. a simple figure partly delimited by one or more edges of the shield.', 'orle', '#n. a stripe parallel to, and just inside, the edges of the shield.', 'palewise', '#adj. (of charges) oriented so that the long axis lies vertically, facing upwards.', 'pale', '#n. a vertical stripe through the middle of the shield.', 'pall', '#n. a Y-shaped figure, formed by three stripes that meet at the center of the shield.', 'paly', '#adj. divided into an even number of vertical stripes of different tinctures.', 'passant', '#adj. (of creatures) with one foot in the air, as if walking to the viewer\'s left (a bear passant).', 'pean', '#adj. in black, powdered with yellow or gold ermine spots.', 'pellety', '#adj. strewn with an indeterminate number of black circular disks.', 'pellet', '#n. a black circular disk.', 'pendant', '#adj. (of a crescent) opening toward the bottom of the shield.', 'per bend', '#adj. divided into two equal parts by a diagonal line connecting the viewer\'s upper left and lower right.', 'per chevron', '#adj. divided into equal upper and lower parts by a line that rises to a sharp corner in the middle.', 'per fess', '#adj. divided into two equal parts by a horizontal line (per fess argent and sable).', 'per pale', '#adj. divided into two equal parts by a vertical line.', 'per pall', '#adj. divided into three equal parts by a Y-shaped boundary.', 'per saltire', '#adj. divided into four equal parts by two diagonal lines that cross in the middle.', 'pheon', '#n. an arrowhead.', 'pheonix', '#n. the front half of a bird, issuant from flames.', 'pile', '#n. a triangular wedge, reaching from the top edge of the shield almost to the bottom point.', 'pily', '#adj. divided into long triangular wedges.', 'pithon', '#n. a bat-winged snake.', 'plate', '#n. a white or silver circular disc.', 'platy', '#adj. strewn with an indeterminate number of white or silver circular disks.', 'point', '#n. (of a star or weapon) any sharp tip. #n. a corner of the shield, especially the bottom one.', 'pomme', '#n. a green circular disk.', 'potent', '#adj. in a pattern of blue and white "T"-shaped pieces. #adj. (of a cross or edge) drawn with "T"-shaped limbs.', 'proper', '#adj. (of a charge) in its natural or most common coloration.', 'purpure', '#adj. in purple.', 'python', '#n. a type of serpent.', 'quarterly', '#adj. divided into four equal parts by two lines, one vertical and one horizontal, that cross each other in the middle.', 'rampant', '#adj. (of a creature) standing upon one hind-limb, facing the viewer\'s left.', 'rayonny', '#adj. (of an edge) drawn with wavy rays emerging from it.', 'reguardant', '#adj. (of a creature) looking back over its shoulder.', 'reversed', '#adj. (of a charge) having left and right transposed (an arrow fesswise reversed).', 'rose', '#n. a flower whose blossom consists of a circular seed surrounded by five symmetric lobes alternating with spiky barbs. #n. (garden rose) a flower with a blossom resembling a small cabbage. #adj. in pink.', 'roundel', '#n. a circular disc.', 'sable', '#adj. in black.', 'salient', '#adj. (of a creature) standing upon both hind-limbs, facing the viewer\'s left.', 'reguardant', '#adj. (of a creature) looking back over its shoulder.', 'saltire', '#n. a figure formed by two diagonal stripes that cross each other in the middle and extend to the edges of the shield.', 'saltorel', '#n. a figure formed by two diagonal segments that cross each other in the middle but do not extend to the edges of the shield.', 'scarpe', '#n. a narrow diagonal stripe connecting the viewer\'s upper right and lower left.', 'sejant', '#adj. (of creatures) seated, facing the viewer\'s left.', 'semy', '#adj. strewn with an indeterminate number (semy of bells).', 'shield', '#n. the conventional medium for heraldic display, a hand-held defensive armament.', 'sinister chief', '#n. the corner in the viewer\'s upper right.', 'sinister', '#n. the side to the viewer\'s right, which would be the shield-bearer\'s left (passant to sinister). #adj. having left and right transposed (a bend sinister). #adj. (of any left-right pair) left (a sinister foot).', 'slipped', '#adj. (of a plant) having a visible stem (a rose gules slipped vert).', 'sphinx', '#n. a monster composed of a lion with a human head.', 'tenne', '#adj. in orange.', 'tergiant', '#adj. (of a creature) with its back to the viewer.', 'tierce', '#n. a stripe covering one side of the shield from top to bottom.', 'tincture', '#n. one of the standard a heraldic colorations.', 'tinctureless', '#adj. a design which may be presented in any combination of colorations, for example, a seal.', 'torteau', '#n. a red circular disk.', 'tressure', '#n. a narrow stripe parallel to, and just inside, the edges of the shield.', 'trippant', '#adj. (of hoofed beasts) with one foot in the air, as if walking to the viewer\'s left (a stag trippant).', 'unicorn', '#n. a four-legged creature with single spiral horn, a beard, and a tuft at the end of its tail.', 'urdy', '#adj. (of an edge) drawn with hexagonal bumps emerging from it.', 'vair', '#adj. in a pattern of blue and white "bells".', 'vert', '#adj. in green.', 'voided', '#adj. hollowed out, so that the background is visible in the center.', 'volant', '#adj. (of a winged creature) flying toward the viewer\'s left.', 'wavy', '#adj. (of an edge) drawn so as to represent the curves of a river.', 'wyvern', '#n. a two-legged creature composed of the front half of a dragon joined to the rear half of a serpent.' ); %plink = ( 'Or', 'tinctures#or', 'annulet', 'geometrics#annulet', 'argent', 'tinctures#argent', 'azure', 'tinctures#azure', 'barry', 'fielddivisions#barry', 'bar', 'variants#bar', 'base', 'directions#base,ordinaries#base', 'bendlet', 'variants#bendlet', 'bendy', 'fielddivisions#bendy', 'bend', 'ordinaries#bend', 'billet', 'geometrics#billet', 'blazon', 'blazon#blazon_noun,blazon#blazon_verb', 'bleu celeste', 'tinctures#bleuceleste', 'bordure', 'ordinaries#bordure', 'brunatre', 'tinctures#brunatre', 'canton', 'ordinaries#canton', 'cartouche', 'geometrics#cartouche', 'cendree', 'tinctures#cendree', 'charge', 'layers1#charge', 'checky', 'fielddivisions#chequy', 'chevron', 'ordinaries#chevron', 'chief', 'directions#chief,ordinaries#chief', 'cotised', 'variants#cotised', 'counterermine', 'tinctures#counterermine', 'cross', 'geometrics#cross-couped,ordinaries#cross', 'delf', 'geometrics#delf', 'dexter', 'directions#dexter', 'dovetailed', 'complex#dovetailed', 'embattled', 'complex#embattled', 'emblazon', 'blazon#emblazon_noun,blazon#emblazon_verb', 'endorsed', 'variants#endorsed', 'engrailed', 'complex#engrailed', 'ermines', 'tinctures#ermines', 'ermine', 'tinctures#ermine', 'fess', 'ordinaries#fess', 'field', 'layers1#field', 'fimbriated', 'variants#fimbriated', 'fret', 'geometrics#fret', 'gules', 'tinctures#gules', 'gyron', 'ordinaries#gyron', 'gyronny', 'fielddivisions#gyronny', 'in bend', 'arrangements#in_bend', 'in fess', 'arrangements#in_fess', 'in pale', 'arrangements#in_pale', 'indented', 'complex#indented', 'invected', 'complex#invected', 'inverted', 'orientations#inverted', 'label', 'geometrics#label', 'lozenge', 'geometrics#lozenge', 'lozengy', 'fielddivisions#lozengy', 'mascle', 'geometrics#mascle', 'mullet', 'geometrics#mullet', 'on', 'layers1#on', 'orle', 'ordinaries#orle', 'pale', 'ordinaries#pale', 'pall', 'ordinaries#pall', 'paly', 'fielddivisions#paly', 'pean', 'tinctures#pean', 'per bend', 'fielddivisions#per-bend', 'per chevron', 'fielddivisions#per-chevron', 'per fess', 'fielddivisions#per-fess', 'per pale', 'fielddivisions#per-pale', 'per pall', 'fielddivisions#per-pall', 'per saltire', 'fielddivisions#per-saltire', 'pile', 'ordinaries#pile', 'pily', 'fielddivisions#pily', 'pomme', 'roundels#pomme', 'potent', 'tinctures#potent', 'purpure', 'tinctures#purpure', 'quarterly', 'fielddivisions#quarterly', 'rayonny', 'complex#rayonny', 'reversed', 'orientations#reversed', 'roundel', 'geometrics#roundel', 'sable', 'tinctures#sable', 'saltire', 'ordinaries#saltire', 'saltorel', 'geometrics#saltorel', 'scarpe', 'variants#scarpe', 'sinister', 'directions#sinister', 'tenne', 'tinctures#tenne', 'tierce', 'ordinaries#tierce', 'tincture', 'tinctures#tincture', 'tressure', 'variants#tressure', 'urdy', 'complex#urdy', 'vair', 'tinctures#vair', 'vert', 'tinctures#vert', 'voided', 'variants#voided', 'wavy', 'complex#wavy' ); $def = $definition{$p}; $plink = $plink{$p}; &print_header (); if ($p ne '') { $phrase = &blazon($p); if ($def eq '') { print '

No definition available for "', $phrase, '".

'; } else { print '

"', $phrase, '":

'; $def = &blazon($def); # insert list item tags and italicize parts of speech $def =~ s^\&\#35\;(adj|n|pl\. n|prep|vb)\.^
  • $1.^g; print '
      ', $def, '
    '; if ($plink ne '') { print ''; } } print '
    '; } print '

    Enter the word or phrase you want to look up in the glossary ->;'; print ''; print '

    Actions:

    '; print ''; &print_trailer (); # end of XXGlossaryPathXX XXEOFXX # # config.web slurps up $CopyrightScript. # $CopyrightScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to get the version data on the database and server. # It is to be installed at XXCopyrightPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXCopyrightUrlXX'; # Set title for form. $form_title = 'SCA Database Copyright'; require 'XXCommonClientPathXX'; &print_header (); &connect_to_data_server (); print S 'c'; print S 'EOF'; &get_matches (); print '
    '; &print_messages (); &print_trailer (); # end of XXCopyrightPathXX XXEOFXX # # config.web slurps up $VersionScript. # $VersionScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to get the version data on the database and server. # It is to be installed at XXVersionPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXVersionUrlXX'; # Set title for form. $form_title = 'Identify SCA Database Version'; require 'XXCommonClientPathXX'; &print_header (); &connect_to_data_server (); print S 'v'; print S 'EOF'; &get_matches (); print '
    '; &print_messages (); &print_trailer (); # end of XXVersionPathXX XXEOFXX # # config.web slurps up $NameSearchScript. # $NameSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a name search of the oanda database. # It is to be installed at XXNameSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXNameSearchUrlXX'; # Set title for form. $form_title = 'Name Search Form'; require 'XXCommonClientPathXX'; # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $p = $right if ($left =~ 'p'); } &print_header (); if ($p ne '') { &connect_to_data_server (); print S 'n 1 ', $p; print S 'EOF'; $n = &get_matches (); $scoresort = 0; @matches = sort byname @matches; } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Enter the exact name for which you are searching ->;'; print ''; print '

    Actions:

    '; print ''; print ''; if ($p ne '') { print '
    '; &print_results ('name="'.&escape($p).'"', $n, $scoresort); if ($n == 0) { # No matches. Make suggestions. local ($you, $pp, $without, $in); $you = '

    You'; $pp = $p; if ($p =~ /["]/) { print $you, ' typed something in quotes.'; $pp =~ tr/"//d; $without = ' without the quotes'; $you = 'You also'; } if ($pp !~ /[A-Z]/) { print $you, ' typed the name entirely in lower case.'; $in = 'in'; $you = 'You also'; } elsif ($pp !~ /[a-z]/) { print $you, ' typed the name entirely in UPPER CASE.'; $in = 'in'; $you = 'You also'; } elsif ($pp =~ /^[a-z]/) { print $you, ' typed the name with a lower case initial.'; $in = 'in'; $you = 'You also'; } if ($pp =~ /[*?\\]/) { print $you, ' typed something that looked like a wildcard.'; print 'Perhaps you should try a'; print '', 'case-', $in, 'sensitive pattern search', $without, '.'; } elsif ($pp !~ /\s/) { print $you, ' typed only one word of the name.'; print 'Perhaps you would like to see'; print '', 'all names containing the word "', &escape($pp),'"'; print 'or'; print '', 'all names beginning with "', &escape($pp),'"'; } elsif ($in ne '') { print 'Perhaps you should try a'; print '', 'case-insensitive pattern search', $without, '.'; } elsif ($without ne '') { print 'Perhaps you should'; print '', 'try again', $without, '.'; } elsif (&permute($pp) ne $pp) { $pp = &permute($pp); print 'Perhaps you should try'; print '', &escape($pp), '.'; } elsif ($pp =~ /^([a-z][a-z]).* ([a-z])\S+$/i) { print 'Perhaps you should look at'; print '', 'names of the form "', $1, '... ', $2, '...".'; } } print '

    ', 'Convert to complex search.'; # print '

    ', # 'Request a correction of an item above.'; } &print_trailer (); # end of XXNameSearchPathXX XXEOFXX # # config.web slurps up $DescSearchScript. # $DescSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a desc search of the oanda database. # It is to be installed at XXDescSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXDescSearchUrlXX'; # Set title for form. $form_title = 'Armory Description Search Form'; require 'XXCommonClientPathXX'; # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $p = $right if ($left =~ 'p'); } &print_header (); if ($p ne '') { &connect_to_data_server (); print S 'd0 1 ', $p; print S 'EOF'; $n = &get_matches (); $scoresort = 0; @matches = sort byblazon @matches; } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Enter a description of the armory for which you are searching ->;'; print ''; print '

    Actions:

    '; print ''; print ''; if ($p ne '') { print '
    '; &print_results ("description=\"".&escape($p)."\"", $n, $scoresort); print 'convert to complex search' } &print_trailer (); # end of XXDescSearchPathXX XXEOFXX # # config.web slurps up $NpSearchScript. # $NpSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a name pattern search of the oanda database. # It is to be installed at XXNpSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXNpSearchUrlXX'; # Set title for form. $form_title = 'Name Pattern Search Form'; require 'XXCommonClientPathXX'; # option settings @breadths = ('narrow', 'broad'); $breadth = 'narrow'; @cases = ('case-sensitive', 'case-insensitive'); $case = 'case-insensitive'; @sorts = ('name only', 'last action date', 'blazon'); $sort = 'name only'; # default # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $arm_descs = $right if ($left eq 'a'); $breadth = $right if ($left eq 'b'); $case = $right if ($left eq 'c'); $era = $right if ($left eq 'd'); $gloss_links = $right if ($left eq 'g'); $limit = $right if ($left eq 'l'); $p = $right if ($left eq 'p'); $sort = $right if ($left eq 's'); } $limit = 25 if ($limit !~ /^\d+$/); &print_header (); if ($p ne '') { &connect_to_data_server (); print S "l $limit"; if ($breadth eq 'broad') { $b = 'n'; } else { $b = '1'; } if ($case eq 'case-insensitive') { $i = 'i'; } else { $i = ''; } print S "e$b$i 1 $p"; print S 'EOF'; $n = &get_matches (); if ($sort eq 'name only') { $scoresort = 0; @matches = sort byname @matches; } elsif ($sort eq 'last action date') { $scoresort = 0; @matches = sort bylastdate @matches; } elsif ($sort eq 'blazon') { $scoresort = 0; @matches = sort byblazon @matches; } } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Enter the name pattern for which you are searching ->;'; print ''; print '

    Select type of search ->;'; &select ('b', $breadth, @breadths); &select ('c', $case, @cases); print '

    Maximum number of items to display ->;'; print ''; &display_options (); print '

    Actions:

    '; print ''; print ''; if ($p ne '') { print '
    '; &print_results ("$breadth $case name pattern=\"".&escape($p).'"', $n, $scoresort); print 'convert to complex search' } &print_trailer (); # end of XXNpSearchPathXX XXEOFXX # # config.web slurps up $BpSearchScript. # $BpSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a blazon pattern search of the oanda database. # It is to be installed at XXBpSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXBpSearchUrlXX'; # Set title for form. $form_title = 'Blazon Pattern Search Form'; require 'XXCommonClientPathXX'; # option settings @cases = ('case-sensitive', 'case-insensitive'); $case = 'case-insensitive'; @sorts = ('name only', 'last action date', 'blazon'); $sort = 'name only'; # default # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $arm_descs = $right if ($left eq 'a'); $case = $right if ($left eq 'c'); $era = $right if ($left eq 'd'); $gloss_links = $right if ($left eq 'g'); $limit = $right if ($left eq 'l'); $p = $right if ($left eq 'p'); $sort = $right if ($left eq 's'); } $limit = 25 if ($limit !~ /^\d+$/); &print_header (); if ($p ne '') { &connect_to_data_server (); print S 'l ', $limit; if ($case eq 'case-insensitive') { $i = 'i'; } else { $i = ''; } print S "eb$i 1 $p"; print S 'EOF'; $n = &get_matches (); if ($sort eq 'name only') { $scoresort = 0; @matches = sort byname @matches; } elsif ($sort eq 'last action date') { $scoresort = 0; @matches = sort bylastdate @matches; } elsif ($sort eq 'blazon') { $scoresort = 0; @matches = sort byblazon @matches; } } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Enter the blazon pattern for which you are searching ->;'; print ''; print '

    Select type of search ->;'; &select ('c', $case, @cases); print '

    Maximum number of items to display ->;'; print ''; &display_options (); print '

    Actions:

    '; print ''; print ''; if ($p ne '') { print '
    '; &print_results ($case.' blazon pattern="'.&escape($p).'"', $n, $scoresort); print 'convert to complex search' } &print_trailer (); # end of XXBpSearchPathXX XXEOFXX # # config.web slurps up $DateSearchScript. # $DateSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a date/kingdom search of the oanda database. # It is to be installed at XXDateSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXDateSearchUrlXX'; # Set title for form. $form_title = 'Date/Kingdom Search Form'; require 'XXCommonClientPathXX'; # option settings $this_year = 1900 + (localtime time)[$[+5]; $last_year = $this_year - 1; $month1 = 'January'; # default $year1 = $last_year; # default $month2 = 'December'; # default $year2 = $last_year; # default %kingdom_set = (); # default @sorts = ('name only', 'last action date', 'blazon'); $sort = 'name only'; # default # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $arm_descs = $right if ($left eq 'a'); $era = $right if ($left eq 'd'); $gloss_links = $right if ($left eq 'g'); $kingdom_set{$1} = $right if ($left =~ /^k([A-Za-z])$/); $limit = $right if ($left eq 'l'); $month1 = $right if ($left eq 'm1'); $month2 = $right if ($left eq 'm2'); $sort = $right if ($left eq 's'); $year1 = $right if ($left eq 'y1'); $year2 = $right if ($left eq 'y2'); $p = 1; } $limit = 200 if ($limit !~ /^\d+$/); &print_header (); if ($p ne '') { &connect_to_data_server (); $year1 += 1900 if ($year1 > 66 && $year1 < 100); $year1 = 1970 if ($year1 < 1970); $year1 = $this_year if ($year1 > $this_year); $year2 += 1900 if ($year2 > 66 && $year2 < 100); $year2 = 1970 if ($year2 < 1970); $year2 = $this_year if ($year2 > $this_year); $kstring = ''; while (($k, $v) = each %kingdom_set) { $kstring .= $k if ($v ne ''); } print S "l $limit"; print S 's 1 ', $year1, $mmap{$month1}, ' ', $year2, $mmap{$month2}, ' ', $kstring; print S 'EOF'; $n = &get_matches (); if ($sort eq 'name only') { $scoresort = 0; @matches = sort byname @matches; } elsif ($sort eq 'blazon') { $scoresort = 0; @matches = sort byblazon @matches; } elsif ($sort eq 'last action date') { $scoresort = 0; @matches = sort bylastdate @matches; } } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Starting date ->;'; &select ('m1', $month1, @month_name); print ''; print '

    Ending date ->;'; &select ('m2', $month2, @month_name); print ''; foreach (sort keys %kingdom_name) { print '
    ', $kingdom_name{$_}; } print '

    Maximum number of items to display ->;'; print ''; &display_options (); print '

    Actions:

    '; print ''; print ''; if ($p ne '') { print '
    '; &print_results ("date between $month1/$year1 and $month2/$year2 inclusive, from one of the specified kingdoms", $n, $scoresort); } &print_trailer (); # end of XXDateSearchPathXX XXEOFXX # # config.web slurps up $ComplexSearchScript. # $ComplexSearchScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to do a complex search of the oanda database. # It is to be installed at XXComplexSearchPathXX on XXServerNameXX. # Set URL for this script. $cgi_url = 'XXComplexSearchUrlXX'; require 'XXCommonClientPathXX'; # Set title for form. $form_title = 'Complex Search Form'; $criteria = 5; # option settings @methods = ('', 'armory description', 'name pattern', 'record type', 'blazon pattern', 'broad name'); @sorts = ('score and blazon', 'score and name', 'score only', 'name only', 'last action date', 'blazon'); $sort = 'score and name'; # default foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/=/, $pair, 2); $left = &decode ($left); $right = &decode ($right); if ($left =~ /^w(\d+)$/) { $weight[$1] = $right if ($1 > 0 && $1 <= $criteria); } elsif ($left =~ /^m(\d+)$/) { $method[$1] = $right if ($1 > 0 && $1 <= $criteria); } elsif ($left =~ /^p(\d+)$/) { $p[$1] = $right if ($1 > 0 && $1 <= $criteria); } $arm_descs = $right if ($left eq 'a'); $era = $right if ($left eq 'd'); $gloss_links = $right if ($left eq 'g'); $limit = $right if ($left eq 'l'); $sort = $right if ($left eq 's'); } $limit = 25 if ($limit !~ /^\d+$/); &print_header (); $invalid = 0; $valid = 0; for $i (1 .. $criteria) { if ($weight[$i] !~ /^[+&]?\d+$/) { if ($method[$i] ne '') { print "

    You specified an invalid weight ($weight[$i]) for criterion #$i; a weight must be a positive number.

    "; $invalid++; } } else { if ($method[$i] eq '') { print "

    You specified a weight ($weight[$i]) for criterion #$i without specifying a search method.

    "; $invalid++; } else { $valid++; } } } if ($valid > 0 && $invalid == 0) { &connect_to_data_server (); print S 'l ', $limit; for $i (1 .. $criteria) { if ($method[$i] eq 'name pattern') { print S "e1 $weight[$i] $p[$i]"; } elsif ($method[$i] eq 'record type') { $temp = $p[$i]; s/([^\\])?/$1\\?/g; print S "e3 $weight[$i] ^($p[$i])\$"; } elsif ($method[$i] eq 'armory description') { print S "d0 $weight[$i] $p[$i]"; } elsif ($method[$i] eq 'blazon pattern') { print S "ebi $weight[$i] $p[$i]"; } elsif ($method[$i] eq 'broad name') { print S "n $weight[$i] $p[$i]"; } } print S 'EOF'; $n = &get_matches (); if ($sort eq 'score only') { $scoresort = 1; } elsif ($sort eq 'score and blazon') { $scoresort = 1; @matches = sort byscoreblazon @matches; } elsif ($sort eq 'score and name') { $scoresort = 1; @matches = sort byscorename @matches; } elsif ($sort eq 'name only') { $scoresort = 0; @matches = sort byname @matches; } elsif ($sort eq 'last action date') { $scoresort = 0; @matches = sort bylastdate @matches; } elsif ($sort eq 'blazon') { $scoresort = 0; @matches = sort byblazon @matches; } } print '

    There are other search forms available.'; print 'For help using this form, please refer to the hints page.'; print '

    Scoring criteria:

      '; for $i (1 .. $criteria) { print '
    1. weight='; print ''; # method selector print 'method='; &select ("m$i", $method[$i], @methods); print 'pattern='; print ''; } print '
    '; print '

    Maximum number of items to display ->;'; print ''; &display_options (); print '

    Actions:

    '; print ''; print '[reset the scoring criteria]'; print ''; if ($valid) { print '
    '; &print_results ('the scoring criteria above', $n, $scoresort); } &print_trailer (); # end of XXComplexSearchPathXX XXEOFXX # # config.web slurps up $CorrectionScript. # $CorrectionScript = <<'XXEOFXX'; #!XXPerlPathXX # This is a CGI script to submit a correction to the Ordinary or Armorial. $[ = 1; $, = ''; $\ = "\n"; $form_title = 'Request a Correction to the SCA Ordinary or SCA Armorial'; $outfile = 'XXCorrectionLogPathXX'; # Set encoding type. $enctype = 'application/x-www-form-urlencoded'; # Replace escaped URL characters with text. sub decode { local($in) = @_; local($out); $in =~ s/\+/\ /g; $out = ''; while ($in =~ /\%/) { $in =~ /^([^%]*)\%([0-9A-Fa-f][0-9A-Fa-f])(.*)$/; $out .= $1 . pack ('c', hex $2); $in = $3; } return $out . $in; } # Common client function to translate a text string to HTML. sub escape { local($out) = ''; local(@chars) = split (//, $_[1]); foreach (@chars) { if (/^[ A-Za-z0-9]$/) { $out .= $_; } else { $out .= sprintf ('&#%u;', ord ($_)); } } return $out; } # Process arguments. foreach $pair (split (/\&/, $ENV{'QUERY_STRING'})) { ($left, $right) = split (/[=]/, $pair, 2); $left = &decode ($left); $right = &decode ($right); $p = $right if ($left eq 'p'); $own = $right if ($left eq 'own'); $misname = $right if ($left eq 'misname'); $missing = $right if ($left eq 'missing'); $misindex = $right if ($left eq 'misindex'); $checked = $right if ($left eq 'checked'); $date = $right if ($left eq 'date'); $text = $right if ($left eq 'text'); $email = $right if ($left eq 'email'); $rights{$left} = $right; } # Print bogus MIME type. print "Content-Type: text/html\n"; # Print HTML header. print '', $form_title, ''; # Print first part of HTML body. print ''; $valid = 0; if ($own ne '' || $misname ne '' || $missing ne '' || $misindex ne '' || $checked ne '' || $date ne '' || $text ne '' || $email ne '') { # A request was submitted; check to see whether it might be valid. $valid = 1; @err = (); if ($p eq '') { push (@err, '
  • You didn\'t provide the SCA name in step 1.'); $valid = 0; } if ($missing ne '' && $date eq '') { push (@err, '
  • You didn\'t provide the date of registration in step 3.'); $valid = 0; } if ($text eq '') { push (@err, '
  • You didn\'t provide an explanation in step 4.'); $valid = 0; } if ($email eq '') { push (@err, '
  • You didn\'t provide an email address in step 5.'); $valid = 0; } if ($valid && !open (LOG, ">>$outfile")) { push (@err, '
  • Our computer is misconfigured.'); $valid = 0; } if ($valid) { $number = $$; print LOG "----begin $number"; while (($l, $r) = each (%rights)) { $r =~ s"\r?\n" / "g; print LOG "$l($number)=[$r]"; } print LOG "----end $number"; close (LOG); print '

    Your correction request has been recorded as follows:


    '; print '

    Subject:'; $name = &escape ($p); if ($own ne '') { print "my registration ($name)"; } else { print "a registation by $name"; } $xdate = &escape ($date); if ($date ne '') { print "dated $xdate"; } print '

    '; $xtext = &escape ($text); print "

    $xtext
    "; if ($checked ne '') { print '

    I have checked this information against the'; print "$xdate Laurel letter."; } $xemail = &escape ($email); print "

    Please send e-mail to me at $xemail when my request"; print 'has been looked at by a human being.

    '; } else { print '

    Your correction request was not processed because:

    Try again.
    '; } } if ($valid == 0) { print '
    '; print '

    ', $form_title, '

    '; print <<'EOF';

    NOTE! This service is primarily for correcting errors that occurred between the Laurel letters and the SCA Armorial. Errors that reflect errors in the Laurel letters will take several months to correct. This service is specifically not for changes and appeals. Changes to properly-registered items and appeals of questionable Laurel decisions should be submitted through the heralds in your kingdom.

    1. Type the full SCA name of the person or branch that registered the item (as it currently appears in the Armorial). If the name is missing from the Armorial, type the name as it should appear. (required) EOF print ''; print '

      '; print '
    2. Click on any applicable boxes (optional):'; print '
      '; print 'The item in question is registered to you.'; print '
      '; print 'The name is misspelled in the Armorial'; print '-- be sure to provide the correct spelling.'; print '
      '; print 'The item is missing from the Armorial'; print '-- be sure to provide the month and year of registration.'; print '
      '; print 'The armory appears under an inappropriate heading'; print 'in the Ordinary'; print '-- be sure to specify the heading in question.'; print '
      '; print 'You have checked the item against the Laurel Letter.'; print '

      '; print '
    3. Type the month and year in which the item was registered'; print '(if known).'; print ''; print '

      '; print '
    4. Briefly explain the correction you are requesting,'; print 'including all pertinent information (required).
      '; print ''; print '

      '; print '
    5. For e-mail confirmation of your request,'; print 'type your full e-mail address below (required).
      '; print ''; print '
    '; print '

    Actions:

    '; print ''; print ''; print '
    '; } print <<'EOF';
    XXTrailer2XX XXCloseHtmlXX EOF # end of XXCorrectionScriptXX XXEOFXX # # config.web slurps up $CommonClientCode. # $CommonClientCode = <<'XXEOFXX'; # This file contains Perl routines shared between XXNameSearchPathXX, # XXDescSearchPathXX, # XXNpSearchPathXX, # XXBpSearchPathXX, # XXDateSearchPathXX, # and XXComplexSearchPathXX. # This should be installed at XXCommonClientPathXX on XXServerNameXX. require 'ctime.pl'; # name of host running the database server code: $them = 'XXDataHostXX'; # port number for contacting the database server: $port = XXDataPortXX; # display option settings: @eras = ('modern', 'SCA'); @onoff = ('enabled', 'disabled'); # default display options: $era = 'modern'; $gloss_links = 'enabled'; $arm_descs = 'disabled'; # networking constants: $sockaddr = 'S n a4 x8'; # format of socket address $AF_INET = XXAF_INETXX; $SOCK_STREAM = XXSOCK_STREAMXX; $[ = 1; $" = '|'; $\ = "\n"; %gloss = ( 'Or', 'Or', 'd\'or', 'Or', 'abased', 'abased', 'addorsed', 'addorsed', 'affronty', 'affronty', 'affronte', 'affronty', 'alaunt', 'alaunt', 'annulet', 'annulet', 'annulets', 'annulet', 'antelope', 'antelope', 'appaumy', 'appaumy', 'appaume', 'appaumy', 'argent', 'argent', 'armed', 'armed', 'arrondi', 'arrondi', 'arrondy', 'arrondi', 'azure', 'azure', 'barbed', 'barbed', 'barrulet', 'barrulet', 'barrulets', 'barrulet', 'barry', 'barry', 'barruly', 'barry', 'bar', 'bar', 'bars', 'bar', 'bascinet', 'bascinet', 'bascinets', 'bascinet', 'base', 'base', 'bases', 'base', 'baton sinister', 'baton+sinister', 'batons sinister', 'baton+sinister', 'battle axe', 'battle+axe', 'battleaxe', 'battle+axe', 'beaked', 'beaked', 'bellied', 'bellied', 'bendlet', 'bendlet', 'bendlets', 'bendlet', 'bendwise sinister', 'bendwise+sinister', 'bendwise', 'bendwise', 'bendy', 'bendy', 'bend', 'bend', 'bends', 'bend', 'bezanty', 'bezanty', 'bezant', 'bezant', 'bezants', 'bezant', 'billet', 'billet', 'billets', 'billet', 'blazon', 'blazon', 'bleu celeste', 'bleu+celeste', 'bordure', 'bordure', 'bordures', 'bordure', 'brunatre', 'brunatre', 'canton', 'canton', 'cartouche', 'cartouche', 'celtic cross', 'celtic+cross', 'cendree', 'cendree', 'charged', 'charged', 'charge', 'charge', 'charges', 'charge', 'checky', 'checky', 'chequy', 'checky', 'chevron', 'chevron', 'chevrons', 'chevron', 'chief', 'chief', 'chiefs', 'chief', 'compass rose', 'compass+rose', 'compass roses', 'compass+rose', 'compass star', 'compass+star', 'compass stars', 'compass+star', 'conjoined', 'conjoined', 'contourny', 'contourny', 'contourney', 'contourny', 'cotised', 'cotised', 'counterchanged', 'counterchanged', 'counterermine', 'counterermine', 'couped', 'couped', 'courant', 'courant', 'cross', 'cross', 'crosses', 'cross', 'crux ansata', 'crux+ansata', 'cruces ansatae', 'crux+ansata', 'debruised', 'debruised', 'debruising', 'debruising', 'decrescent', 'decrescent', 'delf', 'delf', 'delfs', 'delf', 'dexter chief', 'dexter+chief', 'dexter', 'dexter', 'displayed', 'displayed', 'dovetailed', 'dovetailed', 'drakkar', 'drakkar', 'drakkars', 'drakkar', 'eclipsed', 'eclipsed', 'embattled', 'embattled', 'emblazon', 'emblazon', 'embowed', 'embowed', 'endorsed', 'endorsed', 'engrailed', 'engrailed', 'erased', 'erased', 'ermine spot', 'ermine+spot', 'ermine spots', 'ermine+spot', 'ermine tail', 'ermine+spot', 'ermine tails', 'ermine+spot', 'ermines', 'ermines', 'ermine', 'ermine', 'erminois', 'erminois', 'estencele', 'estencele', 'estoile', 'estoile', 'estoiles', 'estoile', 'fesswise', 'fesswise', 'fess', 'fess', 'fieldless', 'fieldless', 'field', 'field', 'fields', 'field', 'fimbriated', 'fimbriated', 'flaunches', 'flaunches', 'flank', 'flaunches', 'fret', 'fret', 'fructed', 'fructed', 'golpe', 'golpe', 'golpes', 'golpe', 'goute', 'goute', 'goutty', 'goutty', 'guardant', 'guardant', 'gules', 'gules', 'gunstone', 'gunstone', 'gunstones', 'gunstone', 'gyron', 'gyron', 'gyronny', 'gyronny', 'harpy', 'harpy', 'haurient', 'haurient', 'hurty', 'hurty', 'hurt', 'hurt', 'hurts', 'hurt', 'in annulo', 'in+annulo', 'in base', 'in+base', 'in bend', 'in+bend', 'in canton', 'in+canton', 'in chief', 'in+chief', 'in cross', 'in+cross', 'in fess', 'in+fess', 'in pale', 'in+pale', 'in saltire', 'in+saltire', 'increscent', 'increscent', 'indented', 'indented', 'invected', 'invected', 'inverted', 'inverted', 'issuant', 'issuant', 'label', 'label', 'latin cross', 'latin+cross', 'latin crosses', 'latin+cross', 'leaved', 'leaved', 'lion', 'lion', 'lions', 'lion', 'lozenge', 'lozenge', 'lozengy', 'lozengy', 'martlet', 'martlet', 'mascle', 'mascle', 'maunch', 'maunch', 'mound', 'mound', 'orb', 'mound', 'mount', 'mount', 'mullet', 'mullet', 'mullets', 'mullet', 'naiant', 'naiant', 'ogress', 'ogress', 'ogresses', 'ogress', 'on', 'on', 'ordinary', 'ordinary', 'ordinaries', 'ordinary', 'orle', 'orle', 'palewise', 'palewise', 'pale', 'pale', 'pales', 'pale', 'pall', 'pall', 'paly', 'paly', 'passant', 'passant', 'pean', 'pean', 'pellety', 'pellety', 'pelletty', 'pellety', 'pellet', 'pellet', 'pellets', 'pellet', 'pendant', 'pendant', 'per bend', 'per+bend', 'per chevron', 'per+chevron', 'per fess', 'per+fess', 'per pale', 'per+pale', 'per pall', 'per+pall', 'per saltire', 'per+saltire', 'pheon', 'pheon', 'pheons', 'pheon', 'pheonix', 'pheonix', 'pile', 'pile', 'piles', 'pile', 'pily', 'pily', 'pithon', 'pithon', 'jaculus', 'pithon', 'plate', 'plate', 'plates', 'plate', 'platy', 'platy', 'point', 'point', 'points', 'point', 'pomme', 'pomme', 'pommes', 'pomme', 'potent', 'potent', 'proper', 'proper', 'purpure', 'purpure', 'python', 'python', 'pythons', 'python', 'quarterly', 'quarterly', 'rampant', 'rampant', 'rayonny', 'rayonny', 'rayonne', 'rayonny', 'reguardant', 'reguardant', 'reversed', 'reversed', 'rose', 'rose', 'roses', 'rose', 'roundel', 'roundel', 'sable', 'sable', 'salient', 'salient', 'reguardant', 'reguardant', 'saltire', 'saltire', 'saltires', 'saltire', 'saltorel', 'saltorel', 'saltorels', 'saltorel', 'scarpe', 'scarpe', 'scarpes', 'scarpe', 'sejant', 'sejant', 'semy', 'semy', 'seme', 'semy', 'shield', 'shield', 'shields', 'shield', 'sinister chief', 'sinister+chief', 'sinister', 'sinister', 'slipped', 'slipped', 'sphinx', 'sphinx', 'sphinxes', 'sphinx', 'tenne', 'tenne', 'tergiant', 'tergiant', 'tierce', 'tierce', 'tincture', 'tincture', 'tinctures', 'tincture', 'tinctureless', 'tinctureless', 'torteau', 'torteau', 'torteaux', 'torteau', 'tressure', 'tressure', 'trippant', 'trippant', 'unicorn', 'unicorn', 'urdy', 'urdy', 'vair', 'vair', 'vert', 'vert', 'voided', 'voided', 'volant', 'volant', 'wavy', 'wavy', 'wyvern', 'wyvern', 'wyverns', 'wyvern', ); %kingdom_name = ( 'A', 'Atenveldt', 'C', 'Caid', 'D', 'Drachenwald', 'E', 'the East', 'G', 'Gleann Abhann', 'H', 'AEthelmearc', 'K', 'Calontir', 'L', 'Laurel', 'M', 'the Middle', 'N', 'An Tir', 'O', 'the Outlands', 'Q', 'Atlantia', 'R', 'Artemisia', 'S', 'Meridies', 'T', 'Trimaris', 'W', 'the West', 'm', 'Ealdormere', 'n', 'Northshield', 'w', 'Lochac', 'X', 'Ansteorra'); %mmap = ( 'January', '01', 'February', '02', 'March', '03', 'April', '04', 'May', '05', 'June', '06', 'July', '07', 'August', '08', 'September', '09', 'October', '10', 'November', '11', 'December', '12'); @month_name = ( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); %type_name = ( 'a', 'augmentation', 'b', 'badge', 'D?','armory', 'd', 'device', 'g', 'regalia', 't', 'heraldic title', 's', 'seal', 'N', 'name', 'BN', 'branch name', 'O', 'order name', 'OC', 'order name change', 'AN','alternate name', 'ANC','alternate name change', 'NC','name change', 'Nc','name correction', 'NC','branch-name change', 'Nc','branch-name correction', 'HN','household name', 'HNC','household name change', 'C', 'database comment', 'j', 'joint badge reference', 'u', 'branch designator update', 'v', 'uncorrected variant spelling', 'Bv', 'uncorrected variant branch-name spelling', 'vc', 'corrected variant spelling', 'Bvc', 'corrected variant branch-name spelling', 'R', 'cross-reference'); # Set encoding type. $enctype = 'application/x-www-form-urlencoded'; # Common client function to show display options for a search. sub display_options { #global ($sort, @sorts, $era, @eras, $gloss_links, $arm_descs, @onoff); print '

    Display Options:

      '; print '
    • Sort items by '; &select ('s', $sort, @sorts); print '
    • Display dates in '; &select ('d', $era, @eras); print ' style.'; print '
    • Glossary links '; &select ('g', $gloss_links, @onoff); print '
    • Armory descriptions '; &select ('a', $arm_descs, @onoff); print '
    '; } # Common client function to replace escaped URL characters with text. sub decode { local($in) = @_; local($out); $in =~ s/\+/\ /g; $out = ''; while ($in =~ /\%/) { $in =~ /^([^%]*)\%([0-9A-Fa-f][0-9A-Fa-f])(.*)$/; $out .= $1 . pack ('c', hex $2); $in = $3; } return $out . $in; } # Common client function to generate a pop-up menu in a form. sub select { local($name, $selected, @options) = @_; local($opt, $s); print ''; } # Common client function to read response from database server. sub get_matches { #global (*S, @matches, @messages, @lost, %m); local ($n, $_); $n = 0; while () { chop; if (/^\'(.*)$/) { push (@messages, $1); } elsif (/^\d+\+(\d+)$/) { push (@lost, $_); $n += $1; } elsif (/^(\d+)\|/) { push (@matches, $_); $n++; $m{$1}++; } } close S; return $n; } # Common client function to format an item into HTML. sub print_match { #global ($prev_name, $arm_descs); local ($name, $source, $type, $text, $notes, @descs) = @_; local ($\) = ''; local (@source); local ($disp) = 'altered or released'; if ($notes =~ /^(.*)[(]-([^)]+)[)](.*)/) { $notes = $1.$3; $disp = $2; } @source = split (/-/, $source); print '
  • ', &name ($name), '
      ' if ($name ne $prev_name); print '
    • '; if ($type eq 'Nc') { print 'This name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was corrected to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'BNc') { print 'This branch-name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was corrected to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'u') { print 'This branch name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was updated to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'ANC') { print 'This alternate name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was changed to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'HNC') { print 'This household name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was changed to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'OC') { print 'This order name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was changed to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'BNC') { $text =~ s/^See //; print 'This branch-name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was changed to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'NC') { $text =~ s/^See //; print 'This name'; if ($source =~ /-/) { print ', registered ', &source ($source[1]), ','; $source = $source[2]; } print ' was changed to ', &name ($text); print ' ', &source ($source), '.'; } elsif ($type eq 'j') { print 'This name was referenced ', &source ($source[1]); print ' as joint registrant of a badge'; print ' with ', &name ($text), '.'; } elsif ($type eq 'R') { $text =~ s/^See (also )?//; print 'This name was referenced ', &source ($source[1]); if ($text =~ /^\"(.+)\"$/) { print ' in registrations by '; @targs = split (/\" or \"/, $1); print &name (shift (@targs)); foreach (@targs) { print ' and ', &name ($_); } } else { print ' in a registration by ', &name ($text), '.'; } } elsif ($type eq 'vc' || $type eq 'Bvc') { if ($source !~ /-/) { $source[1] = $source[2]; $source[2] = $source; } print 'This appeared ', &source ($source[1]); print ' as a mis-spelling of ', &name ($text), '. '; print 'The error was corrected ', &source ($source[2]); } elsif ($type eq 'v' || $type eq 'Bv') { print 'This appeared ', &source ($source[1]); print '.
      It appears to have been a mis-spelling of '; print &name ($text), '.'; } elsif ($type eq 'BN') { print 'This branch-name was registered ', &source ($source[1]); print ' and released ', &source ($source[2]) if ($source =~ /-/); print '.'; } elsif ($type eq 'N') { print 'This name was registered ', &source ($source[1]); print ' and released ', &source ($source[2]) if ($source =~ /-/); print '.'; } elsif ($type eq 't' || $type eq 'AN' || $type eq 'HN' || $type eq 'O') { $text =~ s/^For // if ($type eq 'AN'); print 'This ', $type_name{$type}, ' was registered to '; print &name ($text), ' ', &source ($source[1]); print ' and ', $disp, ' ', &source ($source[2]) if ($source =~ /-/); print '.'; } elsif ($type eq 'BD') { print 'Either the branch-name or the following arms'; print ' associated it (or both) were registered ', &source ($source[1]); print ' and ', $disp, ' ', &source ($source[2]) if ($source =~ /-/); print ':
      ', &blazon ($text), ''; } elsif ($type =~ /^[ABDS]$/) { $type =~ tr/ABDS/abds/; print 'Either the name or the following ', $type_name{$type}; print ' associated it (or both) were registered ', &source ($source[1]); print ' and ', $disp, ' ', &source ($source[2]) if ($source =~ /-/); print ':
      ', &blazon ($text), ''; } elsif ($type =~ /^[abdgs]$/ || $type eq 'D?') { print 'The following ', $type_name{$type}; print ' associated with this name was registered ', &source ($source[1]); print ' and ', $disp, ' ', &source ($source[2]) if ($source =~ /-/); print ':
      ', &blazon ($text), ''; } elsif ($type eq 'C') { print 'A database comment:
      ', $text; } else { print "An unknown record (type=`$type') was found in the database."; } if ($notes =~ /^\((.*)\)$/) { foreach (split (/\)\(/, $1)) { if (/^JB: (.+)$/) { print '
      registered jointly with ', &name ($1); } elsif (/^\-?transferred to (the )?(.+)$/) { print '
      transferred to ', $1, &name ($2); } elsif (/^For (the )?(.+)$/) { print '
      for ', $1, &name ($2); } else { print '
      ', &escape ($_); } } } if (@descs > 0 && $arm_descs eq 'enabled') { print '
      Armory descriptions:
        '; foreach (@descs) { print '
      • ', $_, ''; } print '
      '; } $prev_name = $name; } # Common client function to print messages from the server. sub print_messages { #global (@messages); if (@messages > 0) { print '
      ';
          foreach (@messages) {
            print $_;
          }
          print '
      '; } } # Common client function to summarize info about lost items. sub print_lost { local ($score, $count, $lastscore) = @_; local ($other) = ($lastscore eq $score) ? ' other' : ''; print '

    There '; if ($count == 1) { print 'was one', $other, ' item'; } else { print 'were ', $count, $other, ' items'; } printf ' with a score of %s', $score if ($score ne ''); if ($count == 1) { print ' which was omitted '; } else { print ' which were omitted '; } print 'due to the limit feature.

        '; } # Common client function to print messages and matching items. sub print_results { #global (@matches, @lost, $prev_name, $prev_score); local ($criteria, $n, $scoresort) = @_; local ($_, @item, $total_lost, $score); print '

        Results:

        '; &print_messages (); if (!$scoresort) { # Print summary of matches. print '

        '; if ($n == 0) { print 'No items'; } elsif ($n == 1) { print 'One item'; } else { print $n, ' items'; } print 'matched ', $criteria, '.'; if (@matches < $n) { if (@matches == 1) { print "Here's one of them."; } else { print 'Here are ', scalar(@matches), ' of them.'; } } print '

        '; } # Print each matching item. print '
            ' if ($n > 0); $prev_name = ''; $prev_score = 0; foreach (@matches) { ($score, @item) = split (/\|/); if ($score =~ /^\d+$/ && $score > 0) { if ($scoresort && $score != $prev_score) { print '

        Here '; if ($m{$score} != 1) { print 'are ', $m{$score}, ' matching items'; } else { print 'is one matching item'; } print ' with a score of ', $score; print ':

            '; $prev_name = ''; $prev_score = $score; } &print_match (@item); } } if (@lost > 0) { # Summarize items lost due to the limit. $total_lost = 0; foreach (@lost) { if (/^(\d+)\+(\d+)$/ && $1 > 0) { $total_lost += $2; if ($scoresort) { &print_lost ($1, $2, $prev_score); $prev_score = $1; } } } &print_lost ('', $total_lost, '') unless ($scoresort); } print '

        End of Results

        ' if ($n > 0); } # Common client comparison functions (for sorting). sub byblazon { local($sa, $na, $da, $ya, $ba) = split (/\|/, $a); local($sb, $nb, $db, $yb, $bb) = split (/\|/, $b); return $ba cmp $bb; } sub bylastdate { local($sa, $na, $da) = split (/\|/, $a); local($sb, $nb, $db) = split (/\|/, $b); $da =~ s/^.*[-]//; $db =~ s/^.*[-]//; return &idate ($da) <=> &idate ($db); } sub byname { local($sa, $na) = split (/\|/, $a); local($sb, $nb) = split (/\|/, $b); return $na cmp $nb; } sub byscorename { local($sa, $na) = split (/\|/, $a); local($sb, $nb) = split (/\|/, $b); local($c) = ($sb <=> $sa); return $c if ($c); return $na cmp $nb; } sub byscoreblazon { local($sa, $na, $da, $ya, $ba) = split (/\|/, $a); local($sb, $nb, $db, $yb, $bb) = split (/\|/, $b); local($c) = ($sb <=> $sa); return (($sb <=> $sa) || ($ba cmp $bb)); return $na cmp $nb; } # Common client function to translate a Latin-1 string to HTML. # Non-ASCII chars, ampersands, angle-brackets, etc. are escaped. sub escape { local($out) = ''; foreach (split (//, $_[1])) { if (m&^[ !'()*+,./0-9:;?A-Za-z-]$&) { $out .= $_; } else { $out .= sprintf ('&#%u;', ord ($_)); } } return $out; } # Common client function to translate a Latin-1 string into a URL fragment. sub encodeway { local($_) = $_[1]; tr/\300\301\302\303\304\305\307\310\311\312\313\314\315\316\317\321\322\323\324\325\326\330\331\332\333\334\335\340\341\342\343\344\345\347\350\351\352\353\354\355\356\357\361\362\363\364\365\366\370\371\372\373\374\375\377/AAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy/; s/\306/AE/g; s/\320/Dh/g; s/\336/Th/g; s/\337/sz/g; s/\346/ae/g; s/\360/dh/g; s/\376/th/g; return &encode ($_); } sub encode { local($out) = ''; local($_) = $_[1]; local(@chars) = split (//, $_); foreach (@chars) { if (/^[A-Za-z0-9]$/) { $out .= $_; } else { $out .= sprintf ('%%%02x', ord ($_)); } } return $out; } # Common client function to format a date using style indicated # by the global variable $era. sub source { #global ($date_links, $era); local ($source) = @_; if ($source eq '') { # The date is unknown -- be vague. return 'at some point'; } else { local ($year, $out, $have_loar); local ($ce, $month, $kingdom) = unpack ('A2 A2 A1', $source); $ce += 1900; $ce += 100 if ($ce < 1966); # Be prepared! $have_loar = ($ce > 1993); if ($era eq 'SCA') { $year = $ce - 1966; ++$year if ($month > 4); # Convert the numeric SCA year (1 .. 99) to Roman numerals. $year = 'A.S. ' . ('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC')[$[ + int($year/10)] . ('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX')[$[ + ($year%10)]; } else { $year = $ce; } local ($mn) = $month_name[$month]; $out = "in $mn of $year"; $out .= " (via $kingdom_name{$kingdom})" if ($kingdom ne ''); return $out if ($date_links eq 'disabled'); local ($sopt) = "y1=$ce&m1=$mn&y2=$ce&m2=$mn"; if ($kingdom ne '') { $sopt .= "&k$kingdom=checked"; } else { local ($kn); foreach $kn (sort keys %kingdom_name) { $sopt .= "&k$kn=checked"; } } return qq'$out'; } } # sub source # Common client function to convert a blazon into HTML (with # links to the glossary, if those are enabled). sub blazon { #global ($gloss_links, %gloss); local ($_) = @_; local (@words, $i, $phrase); $_ = &escape ($_); return $_ if ($gloss_links eq 'disabled'); # Split into words. @words = split (/([^A-Za-z0-9]+)/); for ($i = $[; $i <= $#words; $i += 2) { if ($i < $#words-1) { # Look up two-word phrase. $phrase = "$words[$i] $words[$i+2]"; $phrase =~ tr/[A-Z]/[a-z]/; if ($gloss{$phrase} ne '') { $words[$i] = qq'$words[$i]'; $i += 2; $words[$i] .= ''; next; } } # Look up one-word phrase. $phrase = $words[$i]; $phrase =~ tr/[A-Z]/[a-z]/ unless ($phrase eq 'Or'); $words[$i] = qq'$words[$i]' if ($gloss{$phrase} ne ''); } return join ('', @words); } # sub blazon # Permute the words of a name so that the first word is significant. sub permute { local ($_) = @_; s/^(the|la|le) +//i; if ( /^(award|bard|barony|borough|braithrean|brotherhood|canton|casa|castle of|castrum|ch[a\342]teau|ch\{a\^\}teau|clann?|college|compagnie|companionate|company|crown principality|domus|dun|fellowship|freehold|guild|honou?r of the|house|household|hous|h[ao]?us|h\{u'\}sa|keep|kingdom|league|l'ordre|maison|office|orde[nr]|ord[eo]|ordre|principality|province|riding|shire) (.*)/i) { $_ = "$2, $1"; $_ = "$2 $1" if (/^(a[fn]|aus|d[eou]|de[ils]|dell[ao]|in|na|of?|van|vo[mn]) (.*)/i); $_ = "$2 $1" if (/^(das|de[mn]?|der|die|el|l[ae]|les|the) (.*)/i); } return $_; } # Common client function to print a name as a link to # the corresponding name search. sub name { local ($text) = @_; local ($link) = &permute ($text); return '' . &escape ($text) . ''; } # Common client function to convert a source string (from # the database) to numerical month. sub idate { local ($source) = @_; return '' if ($source eq ''); local ($ce, $month, $kingdom) = unpack ('A2 A2 A1', $source); $ce += 100 if ($ce < 66); # Be prepared! return $ce*12 + $month; } # Common client function to connect to the database server. sub connect_to_data_server { # global ($AF_INET, $SOCK_STREAM); # Init global $hostname. chop ($hostname = `hostname`); local ($name, $aliases, $proto) = getprotobyname ('tcp'); local ($type, $len, $thisaddr, $thataddr); ($name, $aliases, $type, $len, $thisaddr) = gethostbyname ($hostname); ($name, $aliases, $type, $len, $thataddr) = gethostbyname ($them); local ($this, $that); $this = pack ($sockaddr, $AF_INET, 0, $thisaddr); $that = pack ($sockaddr, $AF_INET, $port, $thataddr); # Open socket connection to port $port on host $them. # Note that S is a global filehandle. socket (S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; bind (S, $this) || die "bind: $!"; if (!connect (S, $that)) { $cast = "connect: $!"; print '

        Sorry, database server ', $them; print ' refused the connection. Try again later.

        '; &print_trailer (); die $cast; } # Put the connection into line-buffered mode. select (S); $| = 1; select (STDOUT); } # Common client function to connect to print an HTML header. sub print_header { # Print bogus MIME type. print "Content-Type: text/html\n"; # Print HTML header. print '', $form_title, ''; # Print first part of HTML body. print ''; print '
        '; print '

        ', $form_title, '

        '; } # Common client function to connect to print an HTML trailer. sub print_trailer { # Print the author's address and other important info. print 'XXTrailerXX'; print 'XXTrailer2XX'; print 'XXCloseHtmlXX'; print "\n"; } 1; # end of XXCommonClientPathXX XXEOFXX # # config.web slurps up $ConfigDbScript. # $ConfigDbScript = <<'XXEOFXX'; exit if ($not_running_Perl); #=========================================================# # Print introductory messages to the config.db installer. # #=========================================================# print <<'EOF'; This Perl script configures and installs the database server used for searching the SCA Armorial. Before proceeding, you must have downloaded + the category file and + the database. You don't need the most up-to-date versions, but it is a good idea to check occasionally to see if there are newer versions available. (Make sure the files are gunziped before proceeding.) EOF $opt = shift; $Y = 'n'; if ($opt eq '-f') { $Y = 'y'; $opt = shift; } $Rcs = 0; if ($opt eq '-r') { $Rcs = 1; } # Here configdb slurps up $DatabaseServerScript. $DatabaseServerScript = <<'XEOFX'; #!XPerlPathX # Database server code, installed at XDatabaseServerPathX on XXDataHostXX. # port number for this service $port = XXDataPortXX; # version of config script $version = 'XXVersionXX'; $db_version = 'unknown'; $show_copyright = 0; $show_version = 0; # path to category and database files $cat_file_name = 'XCatFileNameX'; $db_file_name = 'XDbFileNameX'; $log_file_name = ''; # default limit on result-list size $limit = 500; # max number of waiting connections $listen_queue_length = 5; # a few definitions: # desc -- "BORDURE:argent" and "FAN:2 or more" are _descs_ # heading -- "BORDURE" and "FAN" are _headings_ # feature -- "argent" and "3 or more" are _features_ # set -- "number" and "tincture" are _sets_ $\ = "\n"; # print a newline after every print statment. $[ = 1; # index of first element in a list $; = ':'; # separator for lookup arguments $" = '.'; # separator for octets of IP address $, = ''; # separator for print items # result indicating a failed search $failed = $test{''}; # socket constants $AF_INET = XAF_INETX; $SOCK_STREAM = XSOCK_STREAMX; $sockaddr = 'S n a4 x8'; $SEEK_SET = 0; if ($log_file_name ne '') { open (LOG_FILE, ">>$log_file_name") || die "cannot open $log_file_name"; } else { open (LOG_FILE, '>&STDERR') || die "cannot open STDERR"; } select (LOG_FILE); $| = 1; select (stdout); &log (': started intializing - not ready yet'); # Get a socket address for the appropriate port on this host. ($name, $aliases, $proto) = getprotobyname ('tcp'); $this = pack ($sockaddr, $AF_INET, $port, "\0\0\0\0"); # Force flushes on the new socket. select (NS); $| = 1; select (stdout); # Create a generic socket, bind to it, and start listening. socket (S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; if (!bind (S, $this)) { &log (': A data server process is already running.'); &log (': Please kill the old process and wait two minutes before retrying.'); die "bind: $!"; } listen (S, $listen_queue_length) || die "connect: $!"; # Force flushes on the generic socket. select (S); $| = 1; select (stdout); &read_cat_file ($cat_file_name); &read_db_file ($db_file_name); &log (': ready'); while (1) { # Fork when data is received from the new socket. $addr = accept (NS, S); die "accept: $!" unless $addr; while (waitpid (-1, XWNOHANGX) > 0) {} $child = fork (); if ($child == 0) { # The child process executes the following. # Note the IP address of the client. ($af, $port, $inetaddr) = unpack ($sockaddr, $addr); @inetaddr = unpack ('C4', $inetaddr); # Start with an empty result. %total = (); # Read and execute search commands from the client. while () { chop; # Strip off the newline. &log ("< $_"); if (/^c$/) { $show_copyright = 1; } elsif (/^d(\d?) ([+&]?)(\d+) (.+)$/) { # compatible armory description search w/tolerance local ($tol, $op, $weight, @descs, $desc); $tol = 0+$1; $op = $2; $weight = $3; @descs = split (/\|/, $4); %match = (); foreach $desc (@descs) { &insert_matching_items ($desc, $tol); } &operation ($op, $weight); } elsif (/^e([1-5b])(i?) ([+&]?)(\d+) (.+)$/) { # pattern search on field or blazons, w/flags local ($ind, $flags, $op, $weight, $pat, $cond, $pos); $ind = $1; $flags = $2; $op = $3; $weight = $4; $pat = $5; $pat =~ s#[/]##g; if ($ind eq 'b') { $cond = sprintf ('$f4=~/%s/%s&&$f3=~/^[abds]$/i', $pat, $flags); } else { $cond = sprintf ('$f%s=~/%s/%s', $ind, $pat, $flags); } if ($op eq '+' || $op eq '&') { # promotion or intersection %match = (); eval sprintf (q@ while (($pos, $tot) = each %%total) { ($f1,$f2,$f3,$f4,$f5) = split (/\|/, &get_item ($_)); $match{$pos} = 1 if (%s); }@, $cond); &operation ($op, $weight); } else { # sum -- must scan the file seek (DB_FILE, 0, $SEEK_SET) || die "seek failed: $!"; $pos = tell (DB_FILE); eval sprintf (q@ while () { chop; next if (/^NOTICE[:]$/ .. /^END OF NOTICE[.]$/); ($f1,$f2,$f3,$f4,$f5) = split (/\|/); $total{$pos} += %s if (%s); $pos = tell (DB_FILE); }@, $weight, $cond); } } elsif (/^en(i?) ([+&]?)(\d+) (.+)$/) { # pattern search on cooked names, w/flags local ($flags, $op, $weight, $pat, @pos); $flags = $1; $op = $2; $weight = $3; $pat = $4; $pat =~ s#[/]##g; %match = (); eval sprintf (q^ while (($n,$items) = each %%itemsn) { if ($n =~ /%s/%s) { @pos = unpack ('L*', $items); foreach (@pos) { $match{$_} = 1; } } }^, $pat, $flags); &operation ($op, $weight); } elsif (/^l (\d+)$/) { # change the output limit $limit = $1 if ($limit > 0); } elsif (/^n ([+&]?)(\d+) (.+)$/) { # exact search on cooked names local ($op, $weight, $pat, @pos); $op = $1; $weight = $2; $pat = $3; %match = (); @pos = unpack ('L*', $itemsn{$pat}); foreach (@pos) { $match{$_} = 1; } &operation ($op, $weight); } elsif (/^s ([+&]?)(\d+) ([12][09]\d\d[0-1]\d) ([12][09]\d\d[0-1]\d) ([A-Za-z]+)$/) { # range search on dates local ($op, $weight, $d1, $d2, $kstring); $op = $1; $weight = $2; $date1 = $3; $date2 = $4; $kstring = $5; if ($op eq '+' || $op eq '&') { # promotion or intersection %match = (); while (($pos, $tot) = each %total) { ($f1,$f2,$f3,$f4,$f5) = split (/\|/, &get_item ($_)); ($d1,$d2) = split (/\-/, $f2); $flag = 0; if ($d1 ne '') { $k1 = substr($d1, 5); if ($k1 eq '' || index($kstring, $k1) != $[-1) { $d1 = substr($d1, 1, 4) + 190000; $d1 += 10000 if ($d1 < 196600); $flag = 1 if ($d1 >= $date1 && $d1 <= $date2); } } if ($d2 ne '' && $flag eq 0) { $k2 = substr($d2, 5); if ($k2 eq '' || index($kstring, $k2) != $[-1) { $d2 = substr($d2, 1, 4) + 190000; $d2 += 10000 if ($d2 < 196600); $flag = 1 if ($d2 >= $date1 && $d2 <= $date2); } } $match{$pos} = 1 if ($flag); } &operation ($op, $weight); } else { # sum -- must scan the file seek (DB_FILE, 0, $SEEK_SET) || die "seek failed: $!"; $pos = tell (DB_FILE); while () { chop; next if (/^NOTICE[:]$/ .. /^END OF NOTICE[.]$/); ($f1,$f2,$f3,$f4,$f5) = split (/\|/); ($d1,$d2) = split (/\-/, $f2); $flag = 0; if ($d1 ne '') { $k1 = substr($d1, 5); if ($k1 eq '' || index($kstring, $k1) != $[-1) { $d1 = substr($d1, 1, 4) + 190000; $d1 += 10000 if ($d1 < 196600); $flag = 1 if ($d1 >= $date1 && $d1 <= $date2); } } if ($d2 ne '' && $flag eq 0) { $k2 = substr($d2, 5); if ($k2 eq '' || index($kstring, $k2) != $[-1) {