Home | News | Projects | Releases
Bugs | RFE | Repositories | Help
Forked Xestia Scanner Server! master
authorKiri <Kiri@8169f44b-d627-0410-8eff-b053711aadfe>
Tue, 20 Sep 2011 14:20:59 +0000 (14:20 +0000)
committerKiri <Kiri@8169f44b-d627-0410-8eff-b053711aadfe>
Tue, 20 Sep 2011 14:20:59 +0000 (14:20 +0000)
167 files changed:
CHANGELOG [new file with mode: 0644]
COPYING [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-auth-authenticate.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-auth-logout.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-critical.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-error.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-fileexists.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-filepermissions.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-initialise.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-language.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-output-config.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-output-header.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-output-page.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-processconfig.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-processfilename.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-final.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-getexportmodules.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-getoutputmodules.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-getpreviewimage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-getscannerlist.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-getscannervalue.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-preview.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-scan-setscannervalue.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-edit.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-getauthmodules.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-getlanguages.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-getpresmodules.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-load.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-settings-view.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-users-add.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-users-delete.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-users-edit.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-users-flush.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-users-list.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-utf8convert.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1-variablecheck.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter1.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addboldtext.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addbutton.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addcell.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addcheckbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addheader.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addhiddendata.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addhorizontalline.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addimage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addinputbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-additalictext.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-additem.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addlinebreak.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addlink.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addoption.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addradiobox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addreset.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addselectbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addsubmit.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addtext.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-addtextbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-clear.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-convert.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endcell.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endform.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endheader.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endlist.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endrow.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endselectbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-endtable.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-enterdata.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-grab.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-guidance.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-new.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-startbox.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-startform.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-startheader.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-startlist.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-startrow.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2-starttable.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter2.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-adduser.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-capabilities.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-connect.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-convert.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-dateconvert.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-deleteuser.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-disconnect.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-edituser.htm [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-flushusers.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-geterror.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-getpermissions.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-getuserlist.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-guidance.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-loadsettings.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-new.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-populatetables.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3-userauth.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter3.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-clearflag.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-errorflag.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-errormessage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-getoptions.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-guidance.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-initialise.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-languagestrings.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-loadsettings.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-new.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4-processimage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter4.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-clearflag.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-errorflag.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-errormessage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-exportimage.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-getoptions.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-guidance.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-initialise.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-languagestrings.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-loadsettings.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5-new.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter5.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter6.html [new file with mode: 0644]
Documentation/English (British)/developer-chapter7.html [new file with mode: 0644]
Documentation/English (British)/developer.html [new file with mode: 0644]
Documentation/English (British)/guide.html [new file with mode: 0644]
Documentation/English (British)/index.html [new file with mode: 0644]
Documentation/English (British)/style.css [new file with mode: 0644]
Documentation/English (British)/tutorial-scan.html [new file with mode: 0644]
Documentation/English (British)/tutorial.html [new file with mode: 0644]
Documentation/English (British)/user-chapter1-install.html [new file with mode: 0644]
Documentation/English (British)/user-chapter1-installscript.html [new file with mode: 0644]
Documentation/English (British)/user-chapter1-multiuserinstallscript.html [new file with mode: 0644]
Documentation/English (British)/user-chapter1-obtaining.html [new file with mode: 0644]
Documentation/English (British)/user-chapter1.html [new file with mode: 0644]
Documentation/English (British)/user-chapter2-scanning.html [new file with mode: 0644]
Documentation/English (British)/user-chapter2-users.html [new file with mode: 0644]
Documentation/English (British)/user-chapter2.html [new file with mode: 0644]
Documentation/English (British)/user-chapter3-edit.html [new file with mode: 0644]
Documentation/English (British)/user-chapter3.html [new file with mode: 0644]
Documentation/English (British)/user-chapter4.html [new file with mode: 0644]
Documentation/English (British)/user-chapter5.html [new file with mode: 0644]
Documentation/English (British)/user-introduction.html [new file with mode: 0644]
Documentation/English (British)/user-preface.html [new file with mode: 0644]
Documentation/English (British)/user.html [new file with mode: 0644]
INSTALL [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
cgi-files/Modules/Auth/PostgreSQL.pm [new file with mode: 0644]
cgi-files/Modules/Export/Download.pm [new file with mode: 0644]
cgi-files/Modules/Export/Email.pm [new file with mode: 0644]
cgi-files/Modules/Output/JPEG.pm [new file with mode: 0644]
cgi-files/Modules/Output/PNG.pm [new file with mode: 0644]
cgi-files/Modules/Presentation/HTML4S.pm [new file with mode: 0644]
cgi-files/Modules/System/Auth.pm [new file with mode: 0644]
cgi-files/Modules/System/Common.pm [new file with mode: 0644]
cgi-files/Modules/System/Scan.pm [new file with mode: 0644]
cgi-files/Modules/System/Settings.pm [new file with mode: 0644]
cgi-files/Modules/System/Users.pm [new file with mode: 0644]
cgi-files/install-multiuser.cgi [new file with mode: 0755]
cgi-files/install.cgi [new file with mode: 0755]
cgi-files/lang/en-GB.lang [new file with mode: 0644]
cgi-files/page.html [new file with mode: 0644]
cgi-files/xsdss.cgi [new file with mode: 0644]
misc/dbspec.txt [new file with mode: 0644]
non-cgi-files/images/menutop.png [new file with mode: 0755]
non-cgi-files/images/pagebackground.png [new file with mode: 0755]
non-cgi-files/images/scannertop.png [new file with mode: 0755]
non-cgi-files/images/sectiontop.png [new file with mode: 0755]
non-cgi-files/images/tabletop.png [new file with mode: 0755]

diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644 (file)
index 0000000..6621a2e
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,3 @@
+As this is the first version, there is currently no changelog.
+
+(This is more or less a placeholder).
\ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..20d40b6
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
\ No newline at end of file
diff --git a/Documentation/English (British)/developer-chapter1-auth-authenticate.html b/Documentation/English (British)/developer-chapter1-auth-authenticate.html
new file mode 100644 (file)
index 0000000..023a061
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.14 xestiascan_auth_authenticate</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.14 xestiascan_auth_authenticate</span>\r
+<br><br>\r
+xestiascan_auth_authenticate prints out a form for authenticating and logging into the scanner server.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_auth_authenticate(authfailure);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_auth_authenticate();\r
+</div>\r
+<br><br>\r
+<i>authfailure</i><br>\r
+A failure occurred whilst authenticating. A value of 1 would print an error message.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-auth-logout.html b/Documentation/English (British)/developer-chapter1-auth-logout.html
new file mode 100644 (file)
index 0000000..1725f9d
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.15 xestiascan_auth_logout</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.15 xestiascan_auth_logout</span>\r
+<br><br>\r
+xestiascan_auth_logout prints out a message saying the user has been logged out with a link to return to the login screen.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_auth_logout;\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_auth_logout();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-critical.html b/Documentation/English (British)/developer-chapter1-critical.html
new file mode 100644 (file)
index 0000000..3885ee7
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.5 xestiascan_critical</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.5 xestiascan_critical</span>\r
+<br><br>\r
+xestiascan_critical processes critical errors when using Xestia Scanner Server.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_critical(errortype);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_critical(“generic”);\r
+</div>\r
+<br><br>\r
+<i>errortype</i><br>\r
+Specifies the critical error message to use.\r
+<br><br>\r
+For more information on the error messages used look at the xestiascan_critical subroutine in the Xestia Scanner Server source code.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-error.html b/Documentation/English (British)/developer-chapter1-error.html
new file mode 100644 (file)
index 0000000..3526cc5
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.4 xestiascan_error</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.4 xestiascan_error</span>\r
+<br><br>\r
+xestiascan_error processes errors that occur within Xestia Scanner Server.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_error(errortype, errorext);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_error(“generic”);<br>\r
+xestiascan_error(“databaseerror”, “Extended Error Information”);\r
+</div>\r
+<br><br>\r
+<i>errortype</i><br>\r
+Specifies the error message to return. If the errortype returned is blank then the generic error type is used. This is required each time when the subroutine is called.\r
+<br><br>\r
+For more information about the error message used, look at the xestiascan_error subroutine in the Xestia Scanner Server source code and the language file where each error type should match with the error type given in the language file.\r
+<br><br>\r
+<i>errorext</i><br>\r
+Specifies the extended error information.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-fileexists.html b/Documentation/English (British)/developer-chapter1-fileexists.html
new file mode 100644 (file)
index 0000000..2b65396
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.6 xestiascan_fileexists</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.6 xestiascan_fileexists</span>\r
+<br><br>\r
+xestiascan_fileexists checks if the filename given exists. xestiascan_fileexists will return a value if the filename given does not exist.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_fileexists(filename);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$file_exists = xestiascan_fileexists(“filename”);\r
+</div>\r
+<br><br>\r
+<i>filename</i><br>\r
+Specifies the filename to check to see if it exists.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-filepermissions.html b/Documentation/English (British)/developer-chapter1-filepermissions.html
new file mode 100644 (file)
index 0000000..86eea39
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.7 xestiascan_filepermissions</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.7 xestiascan_filepermissions</span>\r
+<br><br>\r
+xestiascan_filepermissions checks if the file permissions of a file to see if they are valid and returns a value if the file permissions are invalid.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_filepermissions(filename, read, write, filemissingskip);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$file_permissions = xestiascan_filepermissions(“test.html”, 1);<br>\r
+$file_permissions = xestiascan_filepermissions(“test.html”, 1,1);<br>\r
+$file_permissions = xestiascan_filepermissions(“test.html”, 1, 0, 1);\r
+</div>\r
+<br><br>\r
+<i>filename</i><br>\r
+Specifies the filename to check for valid file permissions. This is required each time the subroutine is called.\r
+<br><br>\r
+<i>read</i><br>\r
+Check if the file with the filename given has valid read permissions.\r
+<br><br>\r
+<i>write</i><br>\r
+Check if the file with the filename given has valid write permissions.\r
+<br><br>\r
+<i>filemissingskip</i><br>\r
+If the file is missing then skip the permissions check (normally used if a file doesn’t exist and then has to be created).\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-initialise.html b/Documentation/English (British)/developer-chapter1-initialise.html
new file mode 100644 (file)
index 0000000..7b43114
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.1 xestiascan_initialise</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.1 xestiascan_initialise</span>\r
+<br><br>\r
+xestiascan_initialise loads some variables before they are used throughout Xestia Scanner Server (such as the script filename). This subroutines does not need to be called anywhere else.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_initialise();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_initialise();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-language.html b/Documentation/English (British)/developer-chapter1-language.html
new file mode 100644 (file)
index 0000000..e80a000
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.3 xestiascan_language</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.3 xestiascan_language</span>\r
+<br><br>\r
+xestiascan_language processes language strings that need to have certain pieces of text inserted. This subroutine should be used only if the language string needs to have text inserted (such as values).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_language(string, text1, (text2, text3));\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_language(“%s, %s, %s %s and %s”, “one”, “two”, “three”, “four”, “five”);\r
+</div>\r
+<br><br>\r
+<i>string</i><br>\r
+Specifies the string to insert text into.\r
+<br><br>\r
+<i>text1, text2, text3</i><br>\r
+Specifies the text to insert into the string and the amount of parameters to pass depends on how may %s’es there are in the language string.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-output-config.html b/Documentation/English (British)/developer-chapter1-output-config.html
new file mode 100644 (file)
index 0000000..80c91ed
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.34 xestiascan_output_config</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.34 xestiascan_output_config</span>\r
+<br><br>\r
+xestiascan_output_config outputs a new configuration file using the settings passed to it as a hash.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_output_config(options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_output_config(%options);\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the new settings as a hash. The settings accepted are:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ImagesURIPath</td>\r
+  <td class="tabledata">Specifies the URI path of the images directory (used for graphics to make the page look more pleasing).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScansURIPath</td>\r
+  <td class="tabledata">Specifies the URI path of the scans directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScansFSPath</td>\r
+  <td class="tabledata">Specifies the filesystem path of the scans directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DateTimeFormat</td>\r
+  <td class="tabledata">Specifies the date and time format to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">SystemLanguage</td>\r
+  <td class="tabledata">Specifies the language to use for Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">PresentationModule</td>\r
+  <td class="tabledata">Specifies the presentation module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">AuthModule</td>\r
+  <td class="tabledata">Specifies the authentication module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">OutputModule</td>\r
+  <td class="tabledata">Specifies the output module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseServer</td>\r
+  <td class="tabledata">Specifies the address of the database server to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePort</td>\r
+  <td class="tabledata">Specifies the port to use to connect to the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseProtocol</td>\r
+  <td class="tabledata">Specifies the protocol to use to connect to the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseSQLDatabase</td>\r
+  <td class="tabledata">Specifies the name of the database to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseUsername</td>\r
+  <td class="tabledata">Specifies the username to use for authenticating on the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePassword</td>\r
+  <td class="tabledata">Specifies the password to use for authenticating on the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePasswordKeep</td>\r
+  <td class="tabledata">Specifies if the existing password for authenticating on the database server should be kept.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseTablePrefix</td>\r
+  <td class="tabledata">Specifies the table prefix to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-output-header.html b/Documentation/English (British)/developer-chapter1-output-header.html
new file mode 100644 (file)
index 0000000..924a715
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.10 xestiascan_output_header</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.10 xestiascan_output_header</span>\r
+<br><br>\r
+xestiascan_output_header outputs the header that is part of the HTTP specification.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_output_header();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_output_header();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-output-page.html b/Documentation/English (British)/developer-chapter1-output-page.html
new file mode 100644 (file)
index 0000000..028ac65
--- /dev/null
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.13 xestiascan_output_page</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.13 xestiascan_output_page</span>\r
+<br><br>\r
+xestiascan_output_page outputs the page to a browser, standard output or a console. First two parameters for this subroutine are required.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+kiriwrite_output_page(pagetitle, pagedata, menutype);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+kiriwrite_output_page(“Page Title”, “This is the page data”, “none”);\r
+</div>\r
+<br><br>\r
+<i>pagetitle</i><br>\r
+Specifies the page title of the page.\r
+<br><br>\r
+<i>pagedata</i><br>\r
+Specifies the page data.\r
+<br><br>\r
+<i>menutype</i><br>\r
+Specifies the menu type to use. A value of none specifies that nomenu should be used.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-processconfig.html b/Documentation/English (British)/developer-chapter1-processconfig.html
new file mode 100644 (file)
index 0000000..367ae26
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.12 xestiascan_processconfig</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.12 xestiascan_processconfig</span>\r
+<br><br>\r
+xestiascan_processconfig processes a configuration file (such the Xestia Scanner Server configuration file or a Xestia Scanner Server).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+kiriwrite_processconfig(data);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%config = kiriwrite_processconfig(@config);\r
+</div>\r
+<br><br>\r
+<i>data</i><br>\r
+Processes a configuration file that is formatted as an array and returns the configuration as a hash. This is much easier to use as specific configuration data does not need to be on a specific line.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-processfilename.html b/Documentation/English (British)/developer-chapter1-processfilename.html
new file mode 100644 (file)
index 0000000..df5949c
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.11 xestiascan_processfilename</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.11 xestiascan_processfilename</span>\r
+<br><br>\r
+xestiascan_processfilename processes a name and turns it into a filename that can be used by Xestia Scanner Server.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_processfilename(text);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$filename = xestiascan_processfilename(“For the 3rd time already”);\r
+</div>\r
+<br><br>\r
+<i>text</i><br>\r
+Specifies the text to create a filename with.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-final.html b/Documentation/English (British)/developer-chapter1-scan-final.html
new file mode 100644 (file)
index 0000000..22b906c
--- /dev/null
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.19 xestiascan_scan_final</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.19 xestiascan_scan_final</span>\r
+<br><br>\r
+xestiascan_scan_final scans a document and presents a list of available output and export modules.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_final(confirm, pageoptions);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$previewoptions{ScannerID} = $form_data->{'scanner'};<br>\r
+$previewoptions{Brightness} = $form_data->{'brightness'};<br>\r
+$previewoptions{Contrast} = $form_data->{'contrast'};<br>\r
+$previewoptions{Rotate} = $form_data->{'rotate'};<br>\r
+$previewoptions{Colour} = $form_data->{'colourtype'};<br>\r
+$previewoptions{Resolution} = $form_data->{'imagedpi'};<br>\r
+$previewoptions{TopLeftX} = $form_data->{'topleftx'};<br>\r
+$previewoptions{TopLeftY} = $form_data->{'toplefty'};<br>\r
+$previewoptions{BottomRightX} = $form_data->{'bottomrightx'};<br>\r
+$previewoptions{BottomRightY} = $form_data->{'bottomrighty'};<br>\r
+<br><br>\r
+$page_data = xestiascan_scan_final(1, %previewoptions);<br>\r
+</div>\r
+<br><br>\r
+<i>confirm</i><br>\r
+Confirms the action to scan a document\r
+<br><br>\r
+<i>pageoptions</i><br>\r
+Specifies the following document options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScannerID</td>\r
+  <td class="tabledata">Specifies the SANE Scanner ID to preview a document with.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Brightness</td>\r
+  <td class="tabledata">Specifies how bright the document should have.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Contrast</td>\r
+  <td class="tabledata">Specifies how much contrast the document have.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Rotate</td>\r
+  <td class="tabledata">Specifies the rotation of the document (0, 90, 180, or 270 degrees).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Colour</td>\r
+  <td class="tabledata">Specifies if the document should be grey or RGB.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Resolution</td>\r
+  <td class="tabledata">Specifies the resolution of the document.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">TopLeftX</td>\r
+  <td class="tabledata">Specifies the top left X position of the document to scan from.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">TopLeftY</td>\r
+  <td class="tabledata">Specifies the top left Y position of the document to scan from.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">BottomRightX</td>\r
+  <td class="tabledata">Specifies the bottom right X position of the document to scan to.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">BottomRightY</td>\r
+  <td class="tabledata">Specifies the bottom right Y position of the document to scan to.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-getexportmodules.html b/Documentation/English (British)/developer-chapter1-scan-getexportmodules.html
new file mode 100644 (file)
index 0000000..f046453
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.17 xestiascan_scan_getexportmodules</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="code">1.17 xestiascan_scan_getexportmodules</span>\r
+<br><br>\r
+xestiascan_scan_getexportmodules gets the list of available export modules in the Modules/Export directory and returns the list as an array.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getoutputmodules();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+@outputmodules = xestiascan_scan_getoutputmodules();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-getoutputmodules.html b/Documentation/English (British)/developer-chapter1-scan-getoutputmodules.html
new file mode 100644 (file)
index 0000000..de9468a
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.16 xestiascan_scan_getoutputmodules</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.16 xestiascan_scan_getoutputmodules</span>\r
+<br><br>\r
+xestiascan_scan_getoutputmodules gets the list of available output modules in the Modules/Output directory and returns the list as an array.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getoutputmodules();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+@outputmodules = xestiascan_scan_getoutputmodules();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-getpreviewimage.html b/Documentation/English (British)/developer-chapter1-scan-getpreviewimage.html
new file mode 100644 (file)
index 0000000..d4aed0f
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.20 xestiascan_scan_getpreviewimage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.20 xestiascan_scan_getpreviewimage</span>\r
+<br><br>\r
+xestiascan_scan_getpreviewimage gets a preview of the image in the PNG format. It also deletes the preview image once it has been read and outputted.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getpreviewimage(previewid);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getpreviewimage(“322E5FC”);\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-getscannerlist.html b/Documentation/English (British)/developer-chapter1-scan-getscannerlist.html
new file mode 100644 (file)
index 0000000..30c3309
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.21 xestiascan_scan_getscannerlist</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.21 xestiascan_scan_getscannerlist</span>\r
+<br><br>\r
+xestiascan_scan_getscannerlist gets a list of available scanners and returns them as a hash.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getscannerlist();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%scannerlist = xestiascan_scan_getscannerlist();\r
+</div>\r
+<br><br>\r
+Each scanner has three values: \r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">name</td>\r
+  <td class="tabledata">The SANE ID of the scanner.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">model</td>\r
+  <td class="tabledata">The model of the scanner.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">vendor</td>\r
+  <td class="tabledata">The vendor of the scanner.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-getscannervalue.html b/Documentation/English (British)/developer-chapter1-scan-getscannervalue.html
new file mode 100644 (file)
index 0000000..76eaaa3
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.22 xestiascan_scan_getscannervalue</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.22 xestiascan_scan_getscannervalue</span>\r
+<br><br>\r
+xestiascan_scan_getscannervalue gets a value based on a specific name from the selected scanner.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_getscannervalue(name);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$scannervalue = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);\r
+</div>\r
+<br><br>\r
+<i>name</i><br>\r
+Gets the value associated with the name. The names used are macros as used by the SANE API.\r
+<br><br>\r
+Any errors that did occur whilst getting the value can be checked using $Sane::STATUS. A null/empty value indicates that the operation completed successfully while a value indicates that the operation was not completed successfully.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-preview.html b/Documentation/English (British)/developer-chapter1-scan-preview.html
new file mode 100644 (file)
index 0000000..b278326
--- /dev/null
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.18 xestiascan_scan_preview</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.18 xestiascan_scan_preview</span>\r
+<br><br>\r
+xestiascan_scan_preview previews a document for scanning. It also prints out a form for changing the scanner settings.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_preview(previewdocument, previewoptions);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$previewoptions{ScannerID} = $form_data->{'scanner'};<br>\r
+$previewoptions{Brightness} = $form_data->{'brightness'};<br>\r
+$previewoptions{Contrast} = $form_data->{'contrast'};<br>\r
+$previewoptions{Rotate} = $form_data->{'rotate'};<br>\r
+$previewoptions{Colour} = $form_data->{'colourtype'};<br>\r
+$previewoptions{Resolution} = $form_data->{'imagedpi'};<br>\r
+$previewoptions{TopLeftX} = $form_data->{'topleftx'};<br>\r
+$previewoptions{TopLeftY} = $form_data->{'toplefty'};<br>\r
+$previewoptions{BottomRightX} = $form_data->{'bottomrightx'};<br>\r
+$previewoptions{BottomRightY} = $form_data->{'bottomrighty'};<br>\r
+<br><br>\r
+$page_data = xestiascan_scan_preview(“off”, %previewoptions);<br>\r
+$page_data = xestiascan_scan_preview(“on”, %previewoptions);\r
+</div>\r
+<br><br>\r
+<i>previewdocument</i><br>\r
+Specifies if a preview of the document that is in the scanner should be scanned and displayed as a preview.\r
+<br><br>\r
+<i>previewoptions</i><br>\r
+Specifies the following preview options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScannerID</td>\r
+  <td class="tabledata">Specifies the SANE Scanner ID to preview a document with.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Brightness</td>\r
+  <td class="tabledata">Specifies how bright the document should have.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Contrast</td>\r
+  <td class="tabledata">Specifies how much contrast the document have.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Rotate</td>\r
+  <td class="tabledata">Specifies the rotation of the document (0, 90, 180, or 270 degrees).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Colour</td>\r
+  <td class="tabledata">Specifies if the document should be grey or RGB.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Resolution</td>\r
+  <td class="tabledata">Specifies the resolution of the document.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">TopLeftX</td>\r
+  <td class="tabledata">Specifies the top left X position of the document to scan from.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">TopLeftY</td>\r
+  <td class="tabledata">Specifies the top left Y position of the document to scan from.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">BottomRightX</td>\r
+  <td class="tabledata">Specifies the bottom right X position of the document to scan to.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">BottomRightY</td>\r
+  <td class="tabledata">Specifies the bottom right Y position of the document to scan to.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-scan-setscannervalue.html b/Documentation/English (British)/developer-chapter1-scan-setscannervalue.html
new file mode 100644 (file)
index 0000000..022c7c1
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.23 xestiascan_scan_setscannervalue</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.23 xestiascan_scan_setscannervalue</span>\r
+<br><br>\r
+xestiascan_scan_setscannervalue gets a value based on a specific name from the selected scanner.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_setscannervalue(name, value);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_scan_setscannervalue(SANE_NAME_SCAN_RESOLUTION, “50”);\r
+</div>\r
+<br><br>\r
+<i>name</i><br>\r
+Gets the value associated with the name. The names used are macros as used by the SANE API.\r
+<br><br>\r
+<i>value</i><br>\r
+Sets the selected name with the given value.\r
+<br><br>\r
+Any errors that did occur whilst setting the value can be checked using $Sane::STATUS. A null/empty value indicates that the operation completed successfully while a value indicates that the operation was not completed successfully.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-edit.html b/Documentation/English (British)/developer-chapter1-settings-edit.html
new file mode 100644 (file)
index 0000000..383d189
--- /dev/null
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.33 xestiascan_settings_edit</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.33 xestiascan_settings_edit</span>\r
+<br><br>\r
+xestiascan_settings_edit edits the settings for the Xestia Scanner Server installation. The settings can only be edited if the user has administrative privileges.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_edit(options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_settings_edit(%options);\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the new settings as a hash. The settings accepted are:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ImagesURIPath</td>\r
+  <td class="tabledata">Specifies the URI path of the images directory (used for graphics to make the page look more pleasing).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScansURIPath</td>\r
+  <td class="tabledata">Specifies the URI path of the scans directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScansFSPath</td>\r
+  <td class="tabledata">Specifies the filesystem path of the scans directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DateTimeFormat</td>\r
+  <td class="tabledata">Specifies the date and time format to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">SystemLanguage</td>\r
+  <td class="tabledata">Specifies the language to use for Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">PresentationModule</td>\r
+  <td class="tabledata">Specifies the presentation module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">AuthModule</td>\r
+  <td class="tabledata">Specifies the authentication module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">OutputModule</td>\r
+  <td class="tabledata">Specifies the output module to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseServer</td>\r
+  <td class="tabledata">Specifies the address of the database server to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePort</td>\r
+  <td class="tabledata">Specifies the port to use to connect to the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseProtocol</td>\r
+  <td class="tabledata">Specifies the protocol to use to connect to the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseSQLDatabase</td>\r
+  <td class="tabledata">Specifies the name of the database to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseUsername</td>\r
+  <td class="tabledata">Specifies the username to use for authenticating on the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePassword</td>\r
+  <td class="tabledata">Specifies the password to use for authenticating on the database server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabasePasswordKeep</td>\r
+  <td class="tabledata">Specifies if the existing password for authenticating on the database server should be kept.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DatabaseTablePrefix</td>\r
+  <td class="tabledata">Specifies the table prefix to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Confirm</td>\r
+  <td class="tabledata">Confirms the action to edit the settings.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-getauthmodules.html b/Documentation/English (British)/developer-chapter1-settings-getauthmodules.html
new file mode 100644 (file)
index 0000000..77fd1c4
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.29 xestiascan_settings_getauthmodules</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.29 xestiascan_settings_getauthmodules</span>\r
+<br><br>\r
+xestiascan_settings_getauthmodules gets a list of authentication modules from the Modules/Auth directory and returns them as an array.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_getauthmodules();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+@authmodules = xestiascan_settings_getauthmodules();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-getlanguages.html b/Documentation/English (British)/developer-chapter1-settings-getlanguages.html
new file mode 100644 (file)
index 0000000..a0514a0
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.31 xestiascan_settings_getlanguages</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.31 xestiascan_settings_getlanguages</span>\r
+<br><br>\r
+xestiascan_settings_getlanguages gets a list of language files from the lang directory and returns them as an array.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_getpresmodules();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+@languages = xestiascan_settings_getlanguages();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-getpresmodules.html b/Documentation/English (British)/developer-chapter1-settings-getpresmodules.html
new file mode 100644 (file)
index 0000000..6e714a9
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.30 xestiascan_settings_getpresmodules</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.30 xestiascan_settings_getpresmodules</span>\r
+<br><br>\r
+xestiascan_settings_getpresmodules gets a list of presentation modules from the Modules/Presentation directory and returns them as an array.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_getpresmodules();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+@presmodules = xestiascan_settings_getpresmodules();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-load.html b/Documentation/English (British)/developer-chapter1-settings-load.html
new file mode 100644 (file)
index 0000000..aa9b037
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.2 xestiascan_settings_load</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.2 xestiascan_settings_load</span>\r
+<br><br>\r
+xestiascan_settings_load loads the settings, presentation module, authentication module and the language file. Any errors that occur during this subroutine will be critical errors.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_load();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_load();\f\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-settings-view.html b/Documentation/English (British)/developer-chapter1-settings-view.html
new file mode 100644 (file)
index 0000000..232ac54
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.32 xestiascan_settings_view</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.32 xestiascan_settings_view</span>\r
+<br><br>\r
+xestiascan_settings_view displays the current settings of the Xestia Scanner Server installation. The current settings will only be displayed if the logged in user has administrative privileges.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_settings_view();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_settings_view();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-users-add.html b/Documentation/English (British)/developer-chapter1-users-add.html
new file mode 100644 (file)
index 0000000..95c81c2
--- /dev/null
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.25 xestiascan_users_add</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.25 xestiascan_users_add</span>\r
+<br><br>\r
+xestiascan_users_add adds a user to the user list or prints out a form for adding a user if the action to add an user has not been confirmed.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_users_add(username, userinfo, scannerinfo, outputmoduleinfo, exportmoduleinfo, confirm);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_users_add();<br>\r
+$pagedata = xestiascan_users_add(“New User”, \%userinfo, \%scannerinfo, \%outputmoduleinfo, \%exportmoduleinfo, 1);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the username to add to the user list.\r
+<br><br>\r
+<i>userinfo</i><br>\r
+Specifies the user information as a hashref.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Username</td>\r
+   <td class="tabledata">Specifies the username.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Name</td>\r
+   <td class="tabledata">Specifies the name of the user.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Password</td>\r
+   <td class="tabledata">Specifies the password of the user.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">ConfirmPassword</td>\r
+   <td class="tabledata">Specifies the confirmed password (should be same as Password).</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Admin</td>\r
+   <td class="tabledata">Specifies if the user has administrative privledges.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Enabled</td>\r
+   <td class="tabledata">Specifies if the account is enabled.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+<i>scannerinfo</i><br>\r
+Specifies the scanner permissions as a hashref.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">scanner_(ScannerID)</td>\r
+   <td class="tabledata">Specifies if the user has permission to use this scanner (A value of ‘on’ would allow the user to use that scanner).</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+<i>outputmoduleinfo</i><br>\r
+Specifies the output module permissions as a hashref. Each setting uses outputmodule_(OutputModuleName) and this specifies if the user has permission to use this output module (A value of ‘on’ would allow the user to use the module).\r
+<br><br>\r
+<i>exportmoduleinfo</i><br>\r
+Specifies the export module permissions as a hashref. Each settings uses exportmodule_(ExportModuleName) and this specifies if the user has permission to use this export module (A value of ‘on’ would allow the user to use the module).\r
+<br><br>\r
+<i>confirm</i><br>\r
+Confirms the action to add the user.\f\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-users-delete.html b/Documentation/English (British)/developer-chapter1-users-delete.html
new file mode 100644 (file)
index 0000000..c10e128
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.27 xestiascan_users_delete</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.27 xestiascan_users_delete</span>\r
+<br><br>\r
+xestiascan_users_delete deletes a user from the users list.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_users_delete(username, confirm);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_users_delete(“Kiri” , 1);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the user with the username given to delete.\r
+<br><br>\r
+<i>confirm</i><br>\r
+Confirms the action to delete the user from the user list.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-users-edit.html b/Documentation/English (British)/developer-chapter1-users-edit.html
new file mode 100644 (file)
index 0000000..f690515
--- /dev/null
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.26 xestiascan_users_edit</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.26 xestiascan_users_edit</span>\r
+<br><br>\r
+xestiascan_users_add edits a user from the user list or prints out a form for adding a user if the action to edit a user has not been confirmed.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_users_edit(username, userinfo, scannerinfo, outputmoduleinfo, exportmoduleinfo, confirm);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_users_add();\r
+$pagedata = xestiascan_users_add(“New User”, \%userinfo, \%scannerinfo, \%outputmoduleinfo, \%exportmoduleinfo, 1);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the username to edit from the user list. This is required in all cases.\r
+<br><br>\r
+<i>userinfo</i><br>\r
+Specifies the user information as a hashref.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">OriginalUsername</td>\r
+  <td class="tabledata">Specifies the original username.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">NewUsername</td>\r
+  <td class="tabledata">Specifies the new username.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Name</td>\r
+  <td class="tabledata">Specifies the name of the user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password of the user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ConfirmPassword</td>\r
+  <td class="tabledata">Specifies the confirmed password (should be same as Password).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Admin</td>\r
+  <td class="tabledata">Specifies if the user has administrative privledges.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Enabled</td>\r
+  <td class="tabledata">Specifies if the account is enabled.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+<i>scannerinfo</i><br>\r
+Specifies the scanner permissions as a hashref. Each permission is named scanner_(ScannerID) and specifies if the user has permission to use this scanner (A value of ‘on’ would allow the user to use that scanner).\r
+<br><br>\r
+<i>outputmoduleinfo</i><br>\r
+Specifies the output module permissions as a hashref. Each permission is named outputmodule_(OutputModuleName) and specifies if the user has permission to use this output module (A value of 'on' would allow the user to use that module).\r
+<br><br>\r
+<i>exportmoduleinfo</i><br>\r
+Specifies the export module permissions as a hashref. Each permission is named exportmodule_(ExportModuleName) and specifies if the user has permission to use this export module (A value of 'on' would allow the user to use that module).\r
+<br><br>\r
+<i>confirm</i><br>\r
+Confirms the action to add the user.\f\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-users-flush.html b/Documentation/English (British)/developer-chapter1-users-flush.html
new file mode 100644 (file)
index 0000000..88cf7f3
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.28 xestiascan_users_flush</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.28 xestiascan_users_flush</span>\r
+<br><br>\r
+xestiascan_users_flush logs everyone out of the Xestia Scanner Server installation.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_users_flush(confirm);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_users_flush(confirm);\r
+</div>\r
+<br><br>\r
+<i>confirm</i><br>\r
+Confirms the action to log everyone out.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-users-list.html b/Documentation/English (British)/developer-chapter1-users-list.html
new file mode 100644 (file)
index 0000000..627e804
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.24 xestiascan_users_list</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.24 xestiascan_users_list</span>\r
+<br><br>\r
+xestiascan_users_list prints a list of users. This will print a list of users only if the logged in user has administrative permissions.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_users_list(options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = xestiascan_users_list({ HideDeactivatedUsers => 1 });\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Value</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">HideDeactivatedUsers</td>\r
+  <td class="tabledata">Hides deactivated users from the user list. The default setting is enabled (1). Setting the value to 0 will display the disabled users in the user list.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-utf8convert.html b/Documentation/English (British)/developer-chapter1-utf8convert.html
new file mode 100644 (file)
index 0000000..621a838
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.8 xestiascan_utf8convert</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.8 xestiascan_utf8convert</span>\r
+<br><br>\r
+xestiascan_utf8convert converts the values into properly formatted UTF-8 values.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_utf8convert(string);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$utf8_string = xestiascan_utf8convert(“This string should now be a UTF-8 formatted string”);\r
+</div>\r
+<br><br>\r
+<i>string</i><br>\r
+Specifies the string to convert into UTF-8.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1-variablecheck.html b/Documentation/English (British)/developer-chapter1-variablecheck.html
new file mode 100644 (file)
index 0000000..4321755
--- /dev/null
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 1.9 xestiascan_variablecheck</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.9 xestiascan_variablecheck</span>\r
+<br><br>\r
+xestiascan_variablecheck checks variables that are passed to it to see if the content of that variable is valid and returns an error if it isn’t. All the parameters are needed each time the subroutine is called and if the noerror parameters is set to 1 then a value is returned when an error occurs. Otherwise, a standard error will be given.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_variablecheck(variable, type, option, noerror);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+xestiascan_variablecheck(“Test 123”, “lettersnumbers”, “”, 0);<br>\r
+$letters_letnum_check = xestiascan_variablecheck(“Test 123”, “lettersnumbers”, “”, 1);\r
+</div>\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Value</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">numbers</td>\r
+  <td class="tabledata">Check if the variable given only contains characters.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">decimal</td>\r
+  <td class="tabledata">Check if the variable given is a valid decimal number.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">lettersnumbers</td>\r
+  <td class="tabledata">Check if the variable given only contains letters and numbers.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">maxlength</td>\r
+  <td class="tabledata">Check if the variable given does not exceed the specific length given.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">blank</td>\r
+  <td class="tabledata">Check if the variable given is blank.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">filename</td>\r
+  <td class="tabledata">Check if the variable given is a valid filename.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">filenameindir</td>\r
+  <td class="tabledata">Check if the variable given is a valid filename in a directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">datetime</td>\r
+  <td class="tabledata">Check if the variable given is a valid date and time format.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">directory</td>\r
+  <td class="tabledata">Check if the variable given is a valid directory name.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">language_filename</td>\r
+  <td class="tabledata">Check if the variable given is a valid language filename.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">module</td>\r
+  <td class="tabledata">Check if the variable given is a valid module name.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">utf8</td>\r
+  <td class="tabledata">Check if the variable given is a correctly formatted UTF8 string.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">serverprotocol</td>\r
+  <td class="tabledata">Checks to see if the variable given contains a valid server protocol (TCP or UDP).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">port</td>\r
+  <td class="tabledata">Check to see if the port number given is a valid port number (0-65535)</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+<i>option</i><br>\r
+Specifies the setting to be used with the test.\r
+<br><br>\r
+<i>noerror</i><br>\r
+Specifies if no error message should be returned but a value should be returned instead so that a more specific error message can be used.\r
+<br><br>\r
+For more information on what values are returned, please look at the xestiascan_error subroutine in the Kiriwrite source code.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter1.html b/Documentation/English (British)/developer-chapter1.html
new file mode 100644 (file)
index 0000000..f136e05
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 1: Internal Xestia Scanner Server Subroutines</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 1: Internal Xestia Scanner Server Subroutines</span>\r
+<br><br>\r
+The subroutines listed here are used internally by Xestia Scanner Server. Typically most of the subroutines here shouldn't be used anywhere else other than the xestiascan_filepermissions and xestiascan_fileexists subroutines which can be used for checking if files exist and have valid permissions set.\r
+\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addboldtext.html b/Documentation/English (British)/developer-chapter2-addboldtext.html
new file mode 100644 (file)
index 0000000..bca175a
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.34 addboldtext</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.34 addboldtext</span>\r
+<br><br>\r
+The addboldtext subroutine adds bolded text.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtext(text, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtext("Here's some text.", { Style => "textformat" });\r
+</div>\r
+<br><br>\r
+<i>text</i><br>\r
+Specifies the text to be added.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addbutton.html b/Documentation/English (British)/developer-chapter2-addbutton.html
new file mode 100644 (file)
index 0000000..beae396
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.29 addbutton</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.29 addbutton</span>\r
+<br><br>\r
+The addbutton subroutine adds a button.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addbutton(buttonname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addbutton("button", { Value => "clicked", Description => "Click this button", Style => "buttonstyle" });\r
+</div>\r
+<br><br>\r
+<i>buttonname</i><br>\r
+Specifies the button name to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Value</td>\r
+  <td class="tabledata">Specifies a value for the button when clicked on.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Description</td>\r
+  <td class="tabledata">Specifies a description (label) for the button.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addcell.html b/Documentation/English (British)/developer-chapter2-addcell.html
new file mode 100644 (file)
index 0000000..200f35b
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.11 addcell</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.11 addcell</span>\r
+<br><br>\r
+The addcell subroutine adds a table cell.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addcell(style);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addcell("tablecellstyle");\r
+</div>\r
+<br><br>\r
+<i>style</i><br>\r
+Specifies the CSS style to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addcheckbox.html b/Documentation/English (British)/developer-chapter2-addcheckbox.html
new file mode 100644 (file)
index 0000000..7c95561
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.19 addcheckbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.19 addcheckbox</span>\r
+<br><br>\r
+The addcheckbox subroutine adds a checkbox.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addcheckbox(checkboxname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addcheckbox("checkbox", { OptionDescription => "Check box", Style => "checkboxstyle", LineBreak => 1 } );\r
+</div>\r
+<br><br>\r
+<i>checkboxname</i><br>\r
+Specifies the name of the checkbox.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">OptionDescription</td>\r
+   <td class="tabledata">Specifies a description for the checkbox value.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Style</td>\r
+   <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Checked</td>\r
+   <td class="tabledata">Specifies if the checkbox is checked.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">LineBreak</td>\r
+   <td class="tabledata">Specifies if a line break should be added.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addheader.html b/Documentation/English (British)/developer-chapter2-addheader.html
new file mode 100644 (file)
index 0000000..6464d53
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.8 addheader</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.8 addheader</span>\r
+<br><br>\r
+The addheader subroutine adds a table header to the table.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addheader(headername, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addheader("Header Name", { Style => "tableheader" });\r
+</div>\r
+<br><br>\r
+<i>headername</i><br>\r
+Specifies the header name to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table>\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addhiddendata.html b/Documentation/English (British)/developer-chapter2-addhiddendata.html
new file mode 100644 (file)
index 0000000..d2d950d
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.28 addhiddendata</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.28 addhiddendata</span>\r
+<br><br>\r
+The addhiddendata subroutine adds a hidden field.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addhiddendata(name, value);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addhiddendata("hidden", "data");\r
+</div>\r
+<br><br>\r
+<i>name</i><br>\r
+Specifies the name of the hidden data field.\r
+<br><br>\r
+<i>value</i><br>\r
+Specifies the value of the hidden data field.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addhorizontalline.html b/Documentation/English (British)/developer-chapter2-addhorizontalline.html
new file mode 100644 (file)
index 0000000..db3b859
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.37 addhorizontalline</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.37 addhorizontalline</span>\r
+<br><br>\r
+The addhorizontalline subroutine adds an horizontal line.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addhorizontalline();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addhorizontalline();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addimage.html b/Documentation/English (British)/developer-chapter2-addimage.html
new file mode 100644 (file)
index 0000000..b1437b9
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.32 addimage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.32 addimage</span>\r
+<br><br>\r
+The addimage subroutine adds an image.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addimage(image, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addimage("image.png", { Width => "100", Height => "100", Description => "This is an image." });\r
+</div>\r
+<br><br>\r
+<i>image</i><br>\r
+Specifies the filename of the image to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use for the image.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Description</td>\r
+  <td class="tabledata">Specifies the description of the image.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Width</td>\r
+  <td class="tabledata">Specifies the width of the image.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Height</td>\r
+  <td class="tabledata">Specifies the height of the image.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addinputbox.html b/Documentation/English (British)/developer-chapter2-addinputbox.html
new file mode 100644 (file)
index 0000000..2a33cf3
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.24 addinputbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.24 addinputbox</span>\r
+<br><br>\r
+The addinputbox subroutine adds an input box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addinputbox(inputboxname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addinputbox("inputbox", { Size => "64", MaxLength => "128", Style => "inputbox", Value => "Default", Password => 0 });\r
+</div>\r
+<br><br>\r
+<i>inputboxname</i><br>\r
+Specifies the input box name to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Size</td>\r
+  <td class="tabledata">Specifies the size of the input box.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">MaxLength</td>\r
+  <td class="tabledata">Specifies the maximum length of the input box.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style of the input box.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Value</td>\r
+  <td class="tabledata">Specifies the value of the input box.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies if this input box is for a password.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ReadOnly</td>\r
+  <td class="tabledata">Specifies if the value should be read only.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-additalictext.html b/Documentation/English (British)/developer-chapter2-additalictext.html
new file mode 100644 (file)
index 0000000..46443f8
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.35 additalictext</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.35 additalictext</span>\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->additalictext(text, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->additalictext("This is italic formatted text.", { Style => "italictext" });\r
+</div>\r
+<br><br>\r
+<i>text</i><br>\r
+Specifies the italic text to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-additem.html b/Documentation/English (British)/developer-chapter2-additem.html
new file mode 100644 (file)
index 0000000..997aa65
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.39 additem</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.39 additem</span>\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->additem(text, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->additem("This is an item", { Style => "itemstyle" });\r
+</div>\r
+<br><br>\r
+<i>text</i><br>\r
+Specifies the text to use for the item.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addlinebreak.html b/Documentation/English (British)/developer-chapter2-addlinebreak.html
new file mode 100644 (file)
index 0000000..8631782
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.36 addlinebreak</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.36 addlinebreak</span>\r
+<br><br>\r
+The addlinebreak subroutine adds a line break.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addlinebreak();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addlinebreak();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addlink.html b/Documentation/English (British)/developer-chapter2-addlink.html
new file mode 100644 (file)
index 0000000..9248871
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.31 addlink</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.31 addlink</span>\r
+<br><br>\r
+The addlink subroutine adds a link.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addlink(link, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addlink("kiriwrite.cgi?mode=db", { Text => "View the database list." });\r
+</div>\r
+<br><br>\r
+<i>link</i><br>\r
+Specifies the location the link should go to when it is clicked on.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Target</td>\r
+  <td class="tabledata">Specifies the target window for the link.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Text</td>\r
+  <td class="tabledata">Specifies the text to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addoption.html b/Documentation/English (British)/developer-chapter2-addoption.html
new file mode 100644 (file)
index 0000000..9cf7d4c
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.22 addoption</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.22 addoption</span>\r
+<br><br>\r
+The addoption subroutine adds an option to a select box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addoption(optionname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addoption("Option Name", { Style => "option", Value => "optionvalue" });\r
+</div>\r
+<br><br>\r
+<i>optionname</i><br>\r
+Specifies the option name.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Value</td>\r
+  <td class="tabledata">Specifies the value for the option when selected.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Selected</td>\r
+  <td class="tabledata">Specifies if the option should be selected by default.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addradiobox.html b/Documentation/English (British)/developer-chapter2-addradiobox.html
new file mode 100644 (file)
index 0000000..3b5c219
--- /dev/null
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.20 addradiobox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.20 addradiobox</span>\r
+<br><br>\r
+The addradiobox subroutine adds a radio box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addradiobox(radioboxname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addradiobox("radiobox", { Description => "Radio box", Selected => 1, Value => "radioboxselected" } );\r
+</div>\r
+<br><br>\r
+<i>radioboxname</i><br>\r
+Specifies the radio box name to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Description</td>\r
+   <td class="tabledata">Specifies a description for the radio box name.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Style</td>\r
+   <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Selected</td>\r
+   <td class="tabledata">Specifies if the radio box should be selected.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">LineBreak</td>\r
+   <td class="tabledata">Specifies if a line break should be added.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Value</td>\r
+   <td class="tabledata">Specifies the value of the radio box.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addreset.html b/Documentation/English (British)/developer-chapter2-addreset.html
new file mode 100644 (file)
index 0000000..c149699
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.27 addreset</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.27 addreset</span>\r
+<br><br>\r
+The addreset subroutine adds a reset button.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addreset(resetname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addreset("Reset this", { Style => "resetbutton" });\r
+</div>\r
+<br><br>\r
+<i>resetname</i><br>\r
+Specifies the label of the reset button.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addselectbox.html b/Documentation/English (British)/developer-chapter2-addselectbox.html
new file mode 100644 (file)
index 0000000..e119e62
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.21 addselectbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.21 addselectbox</span>\r
+<br><br>\r
+The addselectbox subroutine adds a select box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addselectbox(selectboxname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addselectbox("selectbox", { Style => "selectbox" });\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ReadOnly</td>\r
+  <td class="tabledata">Specifies the select box is read only.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addsubmit.html b/Documentation/English (British)/developer-chapter2-addsubmit.html
new file mode 100644 (file)
index 0000000..3e68a2c
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.26 addsubmit</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.26 addsubmit</span>\r
+<br><br>\r
+The addsubmit subroutine adds a submit button.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addsubmit(submitname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addsubmit("Submit This", { Style => "submitbutton" });\r
+</div>\r
+<br><br>\r
+<i>submitname</i><br>\r
+Specifies the label of the submit button.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addtext.html b/Documentation/English (British)/developer-chapter2-addtext.html
new file mode 100644 (file)
index 0000000..dbc0fae
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.33 addtext</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.33 addtext</span>\r
+<br><br>\r
+The addtext subroutine adds text.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtext(text, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtext("Here's some text.", { Style => "textformat" });\r
+</div>\r
+<br><br>\r
+<i>text</i><br>\r
+Specifies the text to be added.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Style</td>\r
+  <td class="tabledata">Specifies the CSS style to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-addtextbox.html b/Documentation/English (British)/developer-chapter2-addtextbox.html
new file mode 100644 (file)
index 0000000..1e66220
--- /dev/null
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.25 addtextbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.25 addtextbox</span>\r
+<br><br>\r
+The addtextbox subroutine adds multiple line text box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtextbox(textboxname, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->addtextbox("textbox", { Columns => 25, Rows => 5, Style => "textbox", Value => "This is a text box." });\r
+</div>\r
+<br><br>\r
+<i>textboxname</i><br>\r
+Specifies the name of the multiple line text box.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Columns</td>\r
+   <td class="tabledata">Specifies the width of the multiple line text box.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Rows</td>\r
+   <td class="tabledata">Specifies the height of the multiple line text box.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Style</td>\r
+   <td class="tabledata">Specifies the CSS style of the multiple line text box.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Value</td>\r
+   <td class="tabledata">Specifies the value of the multiple line text box.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">ReadOnly</td>\r
+   <td class="tabledata">Specifies if the text box is read only.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-clear.html b/Documentation/English (British)/developer-chapter2-clear.html
new file mode 100644 (file)
index 0000000..a96bd93
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.3 clear</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.3 clear</span>\r
+<br><br>\r
+The clear subroutine removes the current layout used by this module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->clear();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->clear();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-convert.html b/Documentation/English (British)/developer-chapter2-convert.html
new file mode 100644 (file)
index 0000000..c39df66
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.5 convert</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.5 convert</span>\r
+<br><br>\r
+The convert subroutine converts the data passed to it into a format that is that would be valid using the output format given.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->convert(data, type);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+
$data = $xestiascan_presmodule->convert(“Moo?”, “link”);\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endbox.html b/Documentation/English (British)/developer-chapter2-endbox.html
new file mode 100644 (file)
index 0000000..5818823
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.17 endbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.17 endbox</span>\r
+<br><br>\r
+The endbox subroutine ends an information box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endbox();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endbox();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endcell.html b/Documentation/English (British)/developer-chapter2-endcell.html
new file mode 100644 (file)
index 0000000..33c8d4a
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.12 endcell</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.12 endcell</span>\r
+<br><br>\r
+The endcell subroutine ends a table cell.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endcell();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endcell();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endform.html b/Documentation/English (British)/developer-chapter2-endform.html
new file mode 100644 (file)
index 0000000..cb3e754
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.30 endform</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.30 endform</span>\r
+<br><br>\r
+The endform subroutine ends a form.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endform();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endform();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endheader.html b/Documentation/English (British)/developer-chapter2-endheader.html
new file mode 100644 (file)
index 0000000..7a350b8
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.9 endheader</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.9 endheader</span>\r
+<br><br>\r
+The endheader subroutine ends a table header.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endheader();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endheader();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endlist.html b/Documentation/English (British)/developer-chapter2-endlist.html
new file mode 100644 (file)
index 0000000..da35d2f
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.40 endlist</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.40 endlist</span>\r
+<br><br>\r
+The endlist subroutine ends a list.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endlist();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endlist();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endrow.html b/Documentation/English (British)/developer-chapter2-endrow.html
new file mode 100644 (file)
index 0000000..fa40f15
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.13 endrow</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.13 endrow</span>\r
+<br><br>\r
+The endrow subroutine ends a table row.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endrow();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endrow();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endselectbox.html b/Documentation/English (British)/developer-chapter2-endselectbox.html
new file mode 100644 (file)
index 0000000..1dceff6
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.23 endselectbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.23 endselectbox</span>\r
+<br><br>\r
+The endselectbox subroutine ends a select box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endselectbox();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endselectbox();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-endtable.html b/Documentation/English (British)/developer-chapter2-endtable.html
new file mode 100644 (file)
index 0000000..b934d6a
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.14 endtable</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.14 endtable</span>\r
+<br><br>\r
+The endtable subroutine ends a table.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endtable();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->endtable();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-enterdata.html b/Documentation/English (British)/developer-chapter2-enterdata.html
new file mode 100644 (file)
index 0000000..8a1f3d2
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.16 enterdata</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.16 enterdata</span>\r
+<br><br>\r
+The enterdata subroutine enters data into an information box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->enterdata(data);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->enterdata("Data for the information box.");\r
+</div>\r
+<br><br>\r
+<i>data</i><br>\r
+Specifies the data to enter into the information box.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-grab.html b/Documentation/English (British)/developer-chapter2-grab.html
new file mode 100644 (file)
index 0000000..801007d
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.4 grab</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.4 grab</span>\r
+<br><br>\r
+The grab subroutine allows the current layout to be printed or passed to a variable.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->grab();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$pagedata = $xestiascan_presmodule->grab();<br>\r
+print $xestiascan_presmodule->grab();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-guidance.html b/Documentation/English (British)/developer-chapter2-guidance.html
new file mode 100644 (file)
index 0000000..e7a274d
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.1 Guidance</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.1 Guidance</span>\r
+<br><br>\r
+When creating a new presentation module to be used in Xestia Scanner Server, the following is required.\r
+<br><br>\r
+When creating a new presentation module, at the top of the script the following should be inserted:\r
+<br><br>\r
+<div class="code">\r
+package Module::Presentation::(modulename);<br>\r
+<br>\r
+use strict;<br>\r
+use warnings;<br>\r
+<br>\r
+our $VERSION = “(version)”;<br>\r
+my $pagedata = “”;\r
+</div>\r
+<br><br>\r
+Replace (modulename) with the name of the module like HTML4S which means HTML 4.01 Strict. When specifying the module name it should be the name of the format (HTML) and version (4S as in 4.01 Strict).\r
+<br><br>\r
+‘use strict’ and ‘use warnings’ isn’t required but it is generally accepted that Perl scripts and modules should at least have ‘use strict’ and ‘use warnings’ lines written.\r
+<br><br>\r
+Replace (version) with the internal version number of the module.\r
+<br><br>\r
+‘my $pagedata’ doesn’t need to be $pagedata and can be something else like $data but it’s somewhere where the page data can be stored until it is needed by the grab subroutine. Presentation modules are stored in the Modules/Presentation directory. For an example of a written presentation module look at the HTML4S.pm file.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-new.html b/Documentation/English (British)/developer-chapter2-new.html
new file mode 100644 (file)
index 0000000..8299867
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.2 new</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.2 new</span>\r
+<br><br>\r
+Creates a new instance of the Presentation Module\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+Modules::Presentation::OutPage->new();\r
+</div>\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule = Modules::Presentation::OutPage->new();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-startbox.html b/Documentation/English (British)/developer-chapter2-startbox.html
new file mode 100644 (file)
index 0000000..d458a24
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.15 startbox</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.15 startbox</span>\r
+<br><br>\r
+The startbox subroutine starts an information box.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$kiriwrite_presmodule->startbox(style);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$kiriwrite_presmodule->startbox("boxstyle");\r
+</div>\r
+<i>style</i><br>\r
+Specifies the CSS style to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-startform.html b/Documentation/English (British)/developer-chapter2-startform.html
new file mode 100644 (file)
index 0000000..d62ac16
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.18 startform</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.18 startform</span>\r
+<br><br>\r
+The startform subroutine starts a form.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startform(action, method);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startform("xsdss.cgi", "POST");\r
+</div>\r
+<br><br>\r
+<i>action</i><br>\r
+Specifies where the form data should be sent to.\r
+<br><br>\r
+<i>method</i><br>\r
+Specifies the method of posting the data.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">POST</td>\r
+   <td class="tabledata">Posts the form data. The data does not appear in the address bar.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">GET</td>\r
+   <td class="tabledata">Gets the form data. The data appears in the address bar.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-startheader.html b/Documentation/English (British)/developer-chapter2-startheader.html
new file mode 100644 (file)
index 0000000..96b6ff4
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.7 startheader</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.7 startheader</span>\r
+<br><br>\r
+The startheader subroutine starts a table header.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startheader();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startheader();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-startlist.html b/Documentation/English (British)/developer-chapter2-startlist.html
new file mode 100644 (file)
index 0000000..ab3e63b
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.38 startlist</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.38 startlist</span>\r
+<br><br>\r
+The startlist subroutine starts a list.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startlist();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startlist();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-startrow.html b/Documentation/English (British)/developer-chapter2-startrow.html
new file mode 100644 (file)
index 0000000..f9a33dc
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.10 startrow</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.10 startrow</span>\r
+<br><br>\r
+The startrow subroutine starts a table row.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startrow();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->startrow();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2-starttable.html b/Documentation/English (British)/developer-chapter2-starttable.html
new file mode 100644 (file)
index 0000000..4d217bf
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 2.6 starttable</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.6 starttable</span>\r
+<br><br>\r
+The starttable subroutine starts a table.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->starttable(cssstyle, options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_presmodule->starttable("tablestyle");<br>\r
+$xestiascan_presmodule->starttable("tablestyle", { CellSpacing => 1, CellPadding => 1});\r
+</div>\r
+<br><br>\r
+<i>cssstyle</i><br>\r
+Specifies the cascading style sheet (CSS) style to use.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash in any order.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">CellSpacing</td>\r
+  <td class="tabledata">Specifies the cell spacing to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">CellPadding</td>\r
+  <td class="tabledata">Specifies the cell padding to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter2.html b/Documentation/English (British)/developer-chapter2.html
new file mode 100644 (file)
index 0000000..75dba63
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 2: Presentation Module</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 2: Presentation Module</span>\r
+<br><br>\r
+The subroutine listed here in this chapter are used by the presentation module. The presentation module outputs the page data in Xestia Scanner Server as the specified format. An example of this is the HTML4S module which writes the page in the HTML 4.0 Strict Format.\r
+<br><br>\r
+When the presentation module is loaded the subroutines for it can be called from the $xestiascan_presmodule scalar.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-adduser.html b/Documentation/English (British)/developer-chapter3-adduser.html
new file mode 100644 (file)
index 0000000..f5bbb4d
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.12 adduser</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.12 adduser</span>\r
+<br><br>\r
+Adds a user to the user list.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->adduser(username, userinfo);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->adduser(“User”, %userinfo);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the name of the new user.\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Username</td>\r
+  <td class="tabledata">Specifies the username to use for the new user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Name</td>\r
+  <td class="tabledata">Specifies the name of the new user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ConfirmPassword</td>\r
+  <td class="tabledata">Specifies the confirmed password to use (should be same as Password).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Admin</td>\r
+  <td class="tabledata">Specifies if the account has administrative privileges.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Enabled</td>\r
+  <td class="tabledata">Specifies if the account is enabled or not.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-capabilities.html b/Documentation/English (British)/developer-chapter3-capabilities.html
new file mode 100644 (file)
index 0000000..ddb7b15
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.4 capabilities</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.4 capabilities</span>\r
+<br><br>\r
+Gets the capabilities of the authentication module (if it supports multiuser or not) and returns as a hash.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->capabilities();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%capabilities = $xestiascan_authmodule->capabilities();\r
+</div>\r
+<br><br>\r
+The following is returned within the hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">multiuser</td>\r
+  <td class="tabledata">Specifies if the authentication module is a multiuser module.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-connect.html b/Documentation/English (British)/developer-chapter3-connect.html
new file mode 100644 (file)
index 0000000..e7d9550
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.8 connect</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.8 connect</span>\r
+<br><br>\r
+Connects to the server containing the authentication information.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->connect();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->connect();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-convert.html b/Documentation/English (British)/developer-chapter3-convert.html
new file mode 100644 (file)
index 0000000..b14ecbb
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.5 convert</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.5 convert</span>\r
+<br><br>\r
+Converts the data into SQL formatted data.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->convert(data);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$converted = $xestiascan_authmodle->convert(‘Moo’);\r
+</div>\r
+<br><br>\r
+<i>data</i><br>\r
+Specifies the data to convert.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-dateconvert.html b/Documentation/English (British)/developer-chapter3-dateconvert.html
new file mode 100644 (file)
index 0000000..4664082
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.6 dateconvert</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.6 dateconvert</span>\r
+<br><br>\r
+Converts a SQL date into a proper date.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->dateconvert(date);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$converted = $xestiascan_authmodule->dateconvert(“2011-04-11”);\r
+</div>\r
+<br><br>\r
+<i>date</i><br>\r
+Specifies the date to convert.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-deleteuser.html b/Documentation/English (British)/developer-chapter3-deleteuser.html
new file mode 100644 (file)
index 0000000..831f0ec
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.14 deleteuser</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.14 deleteuser</span>\r
+<br><br>\r
+Deletes a user from the user list.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->deleteuser(username);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->deleteuser(“User”);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the user to delete.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-disconnect.html b/Documentation/English (British)/developer-chapter3-disconnect.html
new file mode 100644 (file)
index 0000000..ae44700
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.9 disconnect</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.9 disconnect</span>\r
+<br><br>\r
+Disconnects from the server containing the authentication information.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->disconnect();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->disconnect();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-edituser.htm b/Documentation/English (British)/developer-chapter3-edituser.htm
new file mode 100644 (file)
index 0000000..4316a15
--- /dev/null
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.13 edituser</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.13 edituser</span>\r
+<br><br>\r
+Edits a user’s details.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->edituser(username, type, data);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->edituser(“User”, “User”, %userdata);\r
+</div>\r
+<br><br>\r
+<i>username</i><br>\r
+Specifies the username to use.\r
+<br><br>\r
+<i>type</i><br>\r
+Specifies the type of data. This is either User, Scanner, OutputModule or ExportModule.\r
+<br><br>\r
+<i>data</i><br>\r
+Specifies the data as a hash.\r
+<br><br>\r
+User Data Type Hash:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Username</td>\r
+  <td class="tabledata">Specifies the username to use for the new user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Name</td>\r
+  <td class="tabledata">Specifies the name of the new user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ConfirmPassword</td>\r
+  <td class="tabledata">Specifies the confirmed password to use (should be same as Password).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Admin</td>\r
+  <td class="tabledata">Specifies if the account has administrative privileges.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Enabled</td>\r
+  <td class="tabledata">Specifies if the account is enabled or not.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+Scanner Data Type Hash:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ScannerID</td>\r
+  <td class="tabledata">Specifies the scanner ID. A setting of “on” means the user should have permission to use this scanner.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+OutputModule Data Type Hash:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">OutputModule</td>\r
+  <td class="tabledata">Specifies the name of the module. A setting of “on” means the user should have permission to use the output module.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+ExportModule Data Type Hash:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ExportModule</td>\r
+  <td class="tabledata">Specifies the name of the module. A setting of “on” means the user should have permission to use the export module.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-flushusers.html b/Documentation/English (British)/developer-chapter3-flushusers.html
new file mode 100644 (file)
index 0000000..92cd22d
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.16 flushusers</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.16 flushusers</span>\r
+<br><br>\r
+Flush all users from the sessions table.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->flushusers();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->flushusers();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-geterror.html b/Documentation/English (British)/developer-chapter3-geterror.html
new file mode 100644 (file)
index 0000000..b139e7a
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.7 geterror</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.7 geterror</span>\r
+<br><br>\r
+Gets the error message (or extended error message).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->geterror();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$exterror = $xestiascan_authmodule->geterror();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-getpermissions.html b/Documentation/English (British)/developer-chapter3-getpermissions.html
new file mode 100644 (file)
index 0000000..3b988ba
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.11 getpermissions</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.11 getpermissions</span>\r
+<br><br>\r
+Gets the permissions for specific scanner or module. Not specifying a permission name will get the complete list of permissions for that type as a hash. \r
+<br><br>\r
+Specifying a permission name will return a string saying 1 (the user has permission for that) or 0 (the user does not have permission to do that).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->getpermissions(options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->getpermissions({Username => “User”, PermissionType => “OutputModule”, PermissionName => “Test”});<br>\r
+%userinfo = $xestiascan_authmodule->getpermissions({ Username => “User”, PermissionType => “UserInfo”);\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Username</td>\r
+  <td class="tabledata">Specifies the username to get permissions for.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">PermissionType</td>\r
+  <td class="tabledata">Specifies the permission type.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">PermissionName</td>\r
+  <td class="tabledata">Get a specific permission name.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-getuserlist.html b/Documentation/English (British)/developer-chapter3-getuserlist.html
new file mode 100644 (file)
index 0000000..182ab1f
--- /dev/null
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.10 getuserlist</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.10 getuserlist</span>\r
+<br><br>\r
+Gets the user list. Returns as a hash.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->getuserlist();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%userlist = $xestiascan_authmodule->getuserlist(options);\r
+</div>\r
+<br><br>\r
+<i>options</i><br>\r
+Specifies the following options as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Reduced</td>\r
+  <td class="tabledata">Gets a reduced version of the user list.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">ShowDeactivated</td>\r
+  <td class="tabledata">Show users that are deactivated from the list.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+The hash returns the following data for each user.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">username</td>\r
+  <td class="tabledata">Specifies the username of the user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">name</td>\r
+  <td class="tabledata">Specifies the name of the user.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">deactivated</td>\r
+  <td class="tabledata">Specifies if the user account is enabled or disabled.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-guidance.html b/Documentation/English (British)/developer-chapter3-guidance.html
new file mode 100644 (file)
index 0000000..c957158
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.1 Guidance</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.1 Guidance</span>\r
+<br><br>\r
+When creating a new authentication module to be used in Xestia Scanner Server, the following is required:\r
+<br><br>\r
+When creating a new authentication module, at the top of the page the following should be inserted:\r
+<br><br>\r
+<div class="code">\r
+package Modules::Auth::(modulename);<br>\r
+<br>\r
+use strict;<br>\r
+use warnings;<br>\r
+<br>\r
+our $VERSION = "(version)";<br>\r
+my ($options, %options);<br>\r
+my $database_handle;<br>\r
+my $statement_handle;<br>\r
+my $error;<br>\r
+my $errorext;<br>\r
+</div>\r
+<br><br>\r
+Replace (modulename) with the name of the module like PostgreSQL (which means PostgreSQL database server version 5.x). When specifying the module name it should be the name of the format (PostgreSQL).\r
+<br><br>\r
+'use strict' and 'use warnings' isn't required but it is generally accepted that Perl scripts and modules should have 'use strict' and 'use warnings' lines written.\r
+<br><br>\r
+Replace (version) with the internal version number of the module.\r
+<br><br>\r
+Authentication modules are stored in the Modules/Auth directory. For an example of a written authentication module look at the PostgreSQL.pm file.\r
+<br><br>\r
+If an authentication error occurs while preforming a authentication operation then the error string from the database handle scalar ($database_handle) should be placed in the $errorext scalar.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-loadsettings.html b/Documentation/English (British)/developer-chapter3-loadsettings.html
new file mode 100644 (file)
index 0000000..f902260
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.3 loadsettings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="code">3.3 loadsettings</span>\r
+<br><br>\r
+Loads the current Xestia Scanner Server settings into the authentication module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->loadsettings(options);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->loadsettings(%options);\r
+</div>\r
+<br><br>\r
+<i>options
</i><br>\r
+Specifies the settings to use as a hash.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">DateTime</td>\r
+  <td class="tabledata">Specifies the date and time format to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Server</td>\r
+  <td class="tabledata">Specifies the server to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database</td>\r
+  <td class="tabledata">Specifies the database to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Username</td>\r
+  <td class="tabledata">Specifies the username to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Port</td>\r
+  <td class="tabledata">Specifies the server port to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Protocol</td>\r
+  <td class="tabledata">Specifies the protocol to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">TablePrefix</td>\r
+  <td class="tabledata">Specifies the table prefix to use.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-new.html b/Documentation/English (British)/developer-chapter3-new.html
new file mode 100644 (file)
index 0000000..7d1b25f
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.2 new</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.2 new</span>\r
+<br><br>\r
+Creates a new instance of the Output Module.\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+Modules::Auth::AuthModule->new();\r
+</div>\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule = Modules::Presentation::AuthModule->new();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-populatetables.html b/Documentation/English (British)/developer-chapter3-populatetables.html
new file mode 100644 (file)
index 0000000..4ff0256
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.17 populatetables</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.17 populatetables</span>\r
+<br><br>\r
+Populates the database with tables.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->populatetables(type, forcerecreate);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->populatetables(“modules”, 1);\r
+</div>\r
+<br><br>\r
+<i>type</i><br>\r
+Specifies the type of table to populate. Available types are modules, scanners, sessions and users.\r
+<br><br>\r
+<i>forcerecreate</i><br>\r
+Forces the recreation of the table by deleting it and then creating it.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3-userauth.html b/Documentation/English (British)/developer-chapter3-userauth.html
new file mode 100644 (file)
index 0000000..8639c1f
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 3.15 userauth</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.15 userauth</span>\r
+<br><br>\r
+Authenticates a user. Return a value of 1 and the seed value if the user has been authenticated correctly. If a valid seed has been passed along with the user then it will return a value of 1. Invalid authentications will return a value of 0.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_authmodule->userauth(type, user, password, keeploggedin);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$login = $xestiascan_authmodule->userauth(“password”, “User”, “moo”, 1);\r
+$login = $xestiascan_authmodule->userauth(“seed”, “User”, “seed”);\r
+</div>\r
+<br><br>\r
+<i>type</i><br>\r
+Specifies the type of authentication. Either Password (passes a password to the userauth module) or Seed (passes a seed for a user who is already logged in).\r
+<br><br>\r
+<i>user</i><br>\r
+Specifies the username to authenticate.\r
+<br><br>\r
+<i>password</i><br>\r
+Specifies the password or seed to use.\r
+<br><br>\r
+<i>keeploggedin</i><br>\r
+Specifies if the user is to keep logged in. By default the user is logged in for three hours but this option will keep the user logged in for one year.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter3.html b/Documentation/English (British)/developer-chapter3.html
new file mode 100644 (file)
index 0000000..37aa515
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 3: Authentication Module</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 3: Authentication Module</span>\r
+<br><br>\r
+The subroutines listed here in this chapter are used by the authentication module. The authentication module allows users to be authenticated to use the scanner server.\r
+<br><br>\r
+An example of a server-based authentication module is the PostgreSQL module (which is a database module for the PostgreSQL database servers).\r
+<br><br>\r
+When the authentication module is loaded the subroutines for it can be called from the $xestiascan_authmodule scalar.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-clearflag.html b/Documentation/English (British)/developer-chapter4-clearflag.html
new file mode 100644 (file)
index 0000000..a8d0433
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.8 clearflag</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.8 clearflag</span>\r
+<br><br>\r
+Clears the error message flag and the error message itself.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->clearflag();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->clearflag();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-errorflag.html b/Documentation/English (British)/developer-chapter4-errorflag.html
new file mode 100644 (file)
index 0000000..e5ba908
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.6 errorflag</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.6 errorflag</span>\r
+<br><br>\r
+Returns an error flag (if any).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->errorflag();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$errorflag = $xestiascan_outputmodule->errorflag();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-errormessage.html b/Documentation/English (British)/developer-chapter4-errormessage.html
new file mode 100644 (file)
index 0000000..1a39dcc
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.7 errormessage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.7 errormessage</span>\r
+<br><br>\r
+Returns an error message (if any).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->errormessage();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$errorflag = $xestiascan_outputmodule->errormessage();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-getoptions.html b/Documentation/English (British)/developer-chapter4-getoptions.html
new file mode 100644 (file)
index 0000000..5d77018
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.5 getoptions</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.5 getoptions</span>\r
+<br><br>\r
+Gets the options available for the output module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->getoptions();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%options = $xestiascan_outputmodule->getoptions();\r
+</div>\r
+<br><br>\r
+Places the following settings as a hash. Each setting has the following values with the short name for the value.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">type</td>\r
+  <td class="tabledata">Specifies the type of setting. Either checkbox, textbox, combobox or radio.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">string</td>\r
+  <td class="tabledata">Specifies the description of the setting.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">checked</td>\r
+  <td class="tabledata">Specifies if the option is checked for a checkbox type setting.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">size</td>\r
+  <td class="tabledata">Specifies the size of the textbox.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">maxlength</td>\r
+  <td class="tabledata">Specifies the maximum length of the textbox.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">value</td>\r
+  <td class="tabledata">Specifies the default value of the textbox or the values of the combo box.<br>Each value for the combobox should be seperated with a pipe (‘|’) symbol.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">password</td>\r
+  <td class="tabledata">Specifies if the textbox is a password field.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">selected</td>\r
+  <td class="tabledata">Specifies if the radio option is selected.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-guidance.html b/Documentation/English (British)/developer-chapter4-guidance.html
new file mode 100644 (file)
index 0000000..2da82c2
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.1 Guidance</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.1 Guidance</span>\r
+<br><br>\r
+When creating a new output module to be used in Xestia Scanner Server, the following is required:\r
+<br><br>\r
+When creating a new output module, at the top of the page the following should be inserted:\r
+<br><br>\r
+<div class="code">\r
+package Modules::Output::(modulename);<br>\r
+<br>\r
+use strict;<br>\r
+use warnings;<br>\r
+<br>\r
+our $VERSION = "(version)";<br>\r
+my ($pages, %pages);<br>\r
+my $error_flag;<br>\r
+my $error_message;<br>\r
+my $language_name = "";<br>\r
+my %optionshash = ();<br>\r
+</div>\r
+<br><br>\r
+Replace (modulename) with the name of the module like PNG (which means PNG format). When specifying the module name it should be the name of the format (PNG).\r
+<br><br>\r
+'use strict' and 'use warnings' isn't required but it is generally accepted that Perl scripts and modules should have 'use strict' and 'use warnings' lines written.\r
+<br><br>\r
+Replace (version) with the internal version number of the module.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-initialise.html b/Documentation/English (British)/developer-chapter4-initialise.html
new file mode 100644 (file)
index 0000000..2b31d61
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.3 initialise</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.3 initialise</span>\r
+<br><br>\r
+Initialises the output module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->initialise();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->initialise();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-languagestrings.html b/Documentation/English (British)/developer-chapter4-languagestrings.html
new file mode 100644 (file)
index 0000000..9d82141
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.10 languagestrings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.10 languagestrings</span>\r
+<br><br>\r
+Language strings that are used in this module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->languagestrings(langstring);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$string = $xestiascan_outputmodule->languagestrings(“examplestring”);\r
+</div>\r
+<br><br>\r
+<i>langstring</i><br>\r
+Specifies the language string to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-loadsettings.html b/Documentation/English (British)/developer-chapter4-loadsettings.html
new file mode 100644 (file)
index 0000000..e1efa9d
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.4 loadsettings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.4 loadsettings</span>\r
+<br><br>\r
+Loads the settings into the output module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->loadsettings(language);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->loadsettings(“en-GB”);\r
+</div>\r
+<br><br>\r
+<i>language</i><br>\r
+Specifies the language to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-new.html b/Documentation/English (British)/developer-chapter4-new.html
new file mode 100644 (file)
index 0000000..c1ada85
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.2 new</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.2 new</span>\r
+<br><br>\r
+Creates a new instance of the Output Module.\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+Modules::Output::OutputModule->new();\r
+</div>\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule = Modules::Presentation::OutputModule->new();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4-processimage.html b/Documentation/English (British)/developer-chapter4-processimage.html
new file mode 100644 (file)
index 0000000..6de4aed
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 4.9 processimage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">4.9 processimage</span>\r
+<br><br>\r
+Processes the image. This subroutine returns the filename of the processed image.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->processimage(hexnumber, outputmoduleoptions);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_outputmodule->processimage(“31F”, { Option => 2 });\r
+</div>\r
+<br><br>\r
+<i>hexnumber</i><br>\r
+Specifies the hexadecimal number of the filename to process the image.\r
+<br><br>\r
+<i>outputmoduleoptions</i><br>\r
+Specifies the output module settings as a hash which were selected on the settings screen.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter4.html b/Documentation/English (British)/developer-chapter4.html
new file mode 100644 (file)
index 0000000..4933a3e
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 4: Output Format Module</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 4: Output Format Module</span>\r
+<br><br>\r
+The subroutines listed here in this chapter are used by the output module. The output module allows a scanned document to be processed into the desired format (such as PNG).\r
+<br><br>\r
+An example of a output module is the PNG module (which processes the document into the PNG format).\r
+<br><br>\r
+When the output module is loaded when the processing or the available settings are being obtained, they are available from the $xestiascan_outputmodule.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-clearflag.html b/Documentation/English (British)/developer-chapter5-clearflag.html
new file mode 100644 (file)
index 0000000..bd931da
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.9 clearflag</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.9 clearflag</span>\r
+<br><br>\r
+Clears the error message flag and the error message itself.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->clearflag();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->clearflag();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-errorflag.html b/Documentation/English (British)/developer-chapter5-errorflag.html
new file mode 100644 (file)
index 0000000..708e4a3
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.7 errorflag</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.7 errorflag</span>\r
+<br><br>\r
+Returns an error flag (if any).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->errorflag();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$errorflag = $xestiascan_exportmodule->errorflag();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-errormessage.html b/Documentation/English (British)/developer-chapter5-errormessage.html
new file mode 100644 (file)
index 0000000..247e239
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.8 errormessage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.8 errormessage</span>\r
+<br><br>\r
+Returns an error message (if any).\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->errormessage();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$errormessage = $xestiascan_exportmodule->errormessage();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-exportimage.html b/Documentation/English (British)/developer-chapter5-exportimage.html
new file mode 100644 (file)
index 0000000..5a37c57
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.6 exportimage</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.6 exportimage</span>\r
+<br><br>\r
+Exports the image.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->exportimage(processedfilename, scansuridirectory, scansfsdirectory, exportoptions);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->exportimage(“filename”, “/images/scans”, “/var/scans”, %exportoptions);\r
+</div>\r
+<br><br>\r
+<i>processedfilename</i><br>\r
+Specified the name of the processed filename which has gone through an output module.\r
+<br><br>\r
+<i>scansuridirectory</i><br>\r
+Specifies the URI location of the scans directory.\r
+<br><br>\r
+<i>scansfsdirectory</i><br>\r
+Specifies the filesystem location of the scans directory.\r
+<br><br>\r
+<i>exportoptions</i><br>\r
+Specifies the export options which were specified in the getoptions subroutine when the form for specifying the export module settings was specified.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-getoptions.html b/Documentation/English (British)/developer-chapter5-getoptions.html
new file mode 100644 (file)
index 0000000..9b12d7e
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.5 getoptions</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.5 getoptions</span>\r
+<br><br>\r
+Gets the options available for the export module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->getoptions();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+%options = $xestiascan_exportmodule->getoptions();\r
+</div>\r
+<br><br>\r
+Places the following settings as a hash. Each setting has the following values with the short name for the value.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">type</td>\r
+  <td class="tabledata">Specifies the type of setting. Either checkbox, textbox, combobox or radio.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">string</td>\r
+  <td class="tabledata">Specifies the description of the setting.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">checked</td>\r
+  <td class="tabledata">Specifies if the option is checked for a checkbox type setting.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">size</td>\r
+  <td class="tabledata">Specifies the size of the textbox.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">maxlength</td>\r
+  <td class="tabledata">Specifies the maximum length of the textbox.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">value</td>\r
+  <td class="tabledata">Specifies the default value of the textbox or the values of the combo box. Each value for the combobox should be seperated with a pipe (‘|’) symbol.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">password</td>\r
+  <td class="tabledata">Specifies if the textbox is a password field.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">selected</td>\r
+  <td class="tabledata">Specifies if the radio option is selected.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-guidance.html b/Documentation/English (British)/developer-chapter5-guidance.html
new file mode 100644 (file)
index 0000000..2f64851
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.1 Guidance</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.1 Guidance</span>\r
+<br><br>\r
+When creating a new export module to be used in Xestia Scanner Server, the following is required:\r
+<br><br>\r
+When creating a new export module, at the top of the page the following should be inserted:\r
+<br><br>\r
+<div class="code">\r
+package Modules::Export::(modulename);<br>\r
+<br>\r
+use strict;<br>\r
+use warnings;<br>\r
+<br>\r
+our $VERSION = "(version)";<br>\r
+my ($pages, %pages);<br>\r
+my $error_flag;<br>\r
+my $error_message;<br>\r
+my $language_name = "";<br>\r
+my %optionshash = ();\r
+</div>\r
+<br><br>\r
+Replace (modulename) with the name of the module like Download (which means Download export module).\r
+<br><br>\r
+'use strict' and 'use warnings' isn't required but it is generally accepted that Perl scripts and modules should have 'use strict' and 'use warnings' lines written.\r
+<br><br>\r
+Replace (version) with the internal version number of the module.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-initialise.html b/Documentation/English (British)/developer-chapter5-initialise.html
new file mode 100644 (file)
index 0000000..50bb9ca
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.3 initialise</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.3 initialise</span>\r
+<br><br>\r
+Initialises the export module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->initialise();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->initialise();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-languagestrings.html b/Documentation/English (British)/developer-chapter5-languagestrings.html
new file mode 100644 (file)
index 0000000..03dff03
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.10 languagestrings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.10 languagestrings</span>\r
+<br><br>\r
+Language strings that are used in this module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->languagestrings(langstring);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$string = $xestiascan_exportmodule->languagestrings(“examplestring”);\r
+</div>\r
+<br><br>\r
+<i>langstring</i><br>\r
+Specifies the language string to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-loadsettings.html b/Documentation/English (British)/developer-chapter5-loadsettings.html
new file mode 100644 (file)
index 0000000..c05faec
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.4 loadsettings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.4 loadsettings</span>\r
+<br><br>\r
+Loads the settings into the export module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->loadsettings(language);\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule->loadsettings(“en-GB”);\r
+</div>\r
+<br><br>\r
+<i>language</i><br>\r
+Specifies the language to use.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5-new.html b/Documentation/English (British)/developer-chapter5-new.html
new file mode 100644 (file)
index 0000000..e9a6b77
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - 5.2 new</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">5.2 new</span>\r
+<br><br>\r
+Creates a new instance of the Export Module.\r
+<br><br>\r
+<b>Parameters:</b>\r
+<br><br>\r
+<div class="code">\r
+Modules::Export::ExportModule->new();\r
+</div>\r
+<br><br>\r
+<b>Usage:</b>\r
+<br><br>\r
+<div class="code">\r
+$xestiascan_exportmodule = Modules::Presentation::ExportModule->new();\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter5.html b/Documentation/English (British)/developer-chapter5.html
new file mode 100644 (file)
index 0000000..07f8cc4
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 5: Export Format Module</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 5: Export Format Module</span>\r
+<br><br>\r
+The subroutines listed here in this chapter are used by the export module. The export module allows a scanned document to be transferred to the desired medium or sent through the internet. (such as Download and Email).\r
+<br><br>\r
+An example of an export module is the Download module (which makes the scanned document downloadable through a web browser after processing).\r
+<br><br>\r
+When the export module is loaded when the processing or the available settings are being obtained, they are available from the $xestiascan_exportmodule.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter6.html b/Documentation/English (British)/developer-chapter6.html
new file mode 100644 (file)
index 0000000..c4b5d4d
--- /dev/null
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 6: Xestia Scanner Server Page Format</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 6: Xestia Scanner Server Page Format</span>\r
+<br><br>\r
+The Xestia Scanner Server page format is the page format that is used internally for displaying the generated content from the presentation module.\r
+<br><br>\r
+It is stored in the page.html file and can be changed to show the generated content from the presentation module in a different way. Typically the page format would be formatted as the style the presentation module would output.\r
+<br><br>\r
+The content generated from the presentation module and other information (such as page title) can be inserted into the page.html file by using the tags below:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Tag</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">&lt;xestiascan:menu&gt;</td>\r
+  <td class="tabledata">Writes the menu where this tag is specified.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">&lt;xestiascan:imagespath&gt;</td>\r
+  <td class="tabledata">Writes the URI path the images directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">&lt;xestiascan:title&gt;</td>\r
+  <td class="tabledata">Writes the title of the page.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">&lt;xestiascan:pagedata&gt;</td>\r
+  <td class="tabledata">Writes the page data generated by the presentation module.</td>\r
+ </tr>\r
+</table>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer-chapter7.html b/Documentation/English (British)/developer-chapter7.html
new file mode 100644 (file)
index 0000000..db53449
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation - Chapter 7: Languages</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 7: Languages</span>\r
+<br><br>\r
+The language files that are used by Xestia Scanner Server are stored in the 'lang' directory. The language filenames used are typically formatted as ISO 639-1 codes with the “local” dialect appened to it.\r
+<br><br>\r
+An example of this is English (British), as it is the English language it begins with the ISO 639-1 code of en and is then appended with -GB for the “local” dialect making it en-GB. Typically if it's a language specific for a country the local dialect is in capitals, while variations of the language are typically in small letters.\r
+<br><br>\r
+When translating Xestia Scanner Server to another language, the default language of Xestia Scanner Server is English (British). This is the en-GB.lang file in the 'lang' directory and will always contain the most recent language strings. However, if there are already completed and translated files in other languages, you can base the translation from that language if it is easier that way.\r
+<br><br>\r
+The settings in the 'about' tag provide information about the language file. 'name' specifies the name of the language, 'creator' specifies who created the language file while 'mailaddress' specifies an e-mail address (if desired).\r
+<br><br>\r
+The remaining tags contain all of the strings that are used within Xestia Scanner Server.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/developer.html b/Documentation/English (British)/developer.html
new file mode 100644 (file)
index 0000000..6f530a1
--- /dev/null
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Developer Documentation</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Developer Documentation</span>\r
+<br><br>\r
+The Developer Documentation contains information about the internal Xestia Scanner Server subroutines, presentation module, authentication module, export module, output modules, language support and page configuration.\r
+\r
+<br><br>\r
+<a href="developer-chapter1.html">Chapter 1: Internal Xestia Scanner Server Subroutines</a><br>\r
+&nbsp;<a href="developer-chapter1-initialise.html">1.1 xestiascan_initialise</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-load.html">1.2 xestiascan_settings_load</a><br>\r
+&nbsp;<a href="developer-chapter1-language.html">1.3 xestiascan_language</a><br>\r
+&nbsp;<a href="developer-chapter1-error.html">1.4 xestiascan_error</a><br>\r
+&nbsp;<a href="developer-chapter1-critical.html">1.5 xestiascan_critical</a><br>\r
+&nbsp;<a href="developer-chapter1-fileexists.html">1.6 xestiascan_fileexists</a><br>\r
+&nbsp;<a href="developer-chapter1-filepermissions.html">1.7 xestiascan_filepermissions</a><br>\r
+&nbsp;<a href="developer-chapter1-utf8convert.html">1.8 xestiascan_utf8convert</a><br>\r
+&nbsp;<a href="developer-chapter1-variablecheck.html">1.9 xestiascan_variablecheck</a><br>\r
+&nbsp;<a href="developer-chapter1-output-header.html">1.10 xestiascan_output_header</a><br>\r
+&nbsp;<a href="developer-chapter1-processfilename.html">1.11 xestiascan_processfilename</a><br>\r
+&nbsp;<a href="developer-chapter1-processconfig.html">1.12 xestiascan_processconfig</a><br>\r
+&nbsp;<a href="developer-chapter1-output-page.html">1.13 xestiascan_output_page</a><br>\r
+&nbsp;<a href="developer-chapter1-auth-authenticate.html">1.14 xestiascan_auth_authenticate</a><br>\r
+&nbsp;<a href="developer-chapter1-auth-logout.html">1.15 xestiascan_auth_logout</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-getoutputmodules.html">1.16 xestiascan_scan_getoutputmodules</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-getexportmodules.html">1.17 xestiascan_scan_getexportmodules</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-preview.html">1.18 xestiascan_scan_preview</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-final.html">1.19 xestiascan_scan_final</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-getpreviewimage.html">1.20 xestiascan_scan_getpreviewimage</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-getscannerlist.html">1.21 xestiascan_scan_getscannerlist</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-getscannervalue.html">1.22 xestiascan_scan_getscannervalue</a><br>\r
+&nbsp;<a href="developer-chapter1-scan-setscannervalue.html">1.23 xestiascan_scan_setscannervalue</a><br>\r
+&nbsp;<a href="developer-chapter1-users-list.html">1.24 xestiascan_users_list</a><br>\r
+&nbsp;<a href="developer-chapter1-users-add.html">1.25 xestiascan_users_add</a><br>\r
+&nbsp;<a href="developer-chapter1-users-edit.html">1.26 xestiascan_users_edit</a><br>\r
+&nbsp;<a href="developer-chapter1-users-delete.html">1.27 xestiascan_users_delete</a><br>\r
+&nbsp;<a href="developer-chapter1-users-flush.html">1.28 xestiascan_users_flush</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-getauthmodules.html">1.29 xestiascan_settings_getauthmodules</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-getpresmodules.html">1.30 xestiascan_settings_getpresmodules</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-getlanguages.html">1.31 xestiascan_settings_getlanguages</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-view.html">1.32 xestiascan_settings_view</a><br>\r
+&nbsp;<a href="developer-chapter1-settings-edit.html">1.33 xestiascan_settings_edit</a><br>\r
+&nbsp;<a href="developer-chapter1-output-config.html">1.34 xestiascan_output_config</a><br>\r
+<a href="developer-chapter2.html">Chapter 2: Presentation Module</a><br>\r
+&nbsp;<a href="developer-chapter2-guidance.html">2.1 Guidance</a><br>\r
+&nbsp;<a href="developer-chapter2-new.html">2.2 new</a><br>\r
+&nbsp;<a href="developer-chapter2-clear.html">2.3 clear</a><br>\r
+&nbsp;<a href="developer-chapter2-grab.html">2.4 grab</a><br>\r
+&nbsp;<a href="developer-chapter2-convert.html">2.5 convert</a><br>\r
+&nbsp;<a href="developer-chapter2-starttable.html">2.6 starttable</a><br>\r
+&nbsp;<a href="developer-chapter2-startheader.html">2.7 startheader</a><br>\r
+&nbsp;<a href="developer-chapter2-addheader.html">2.8 addheader</a><br>\r
+&nbsp;<a href="developer-chapter2-endheader.html">2.9 endheader</a><br>\r
+&nbsp;<a href="developer-chapter2-startrow.html">2.10 startrow</a><br>\r
+&nbsp;<a href="developer-chapter2-addcell.html">2.11 addcell</a><br>\r
+&nbsp;<a href="developer-chapter2-endcell.html">2.12 endcell</a><br>\r
+&nbsp;<a href="developer-chapter2-endrow.html">2.13 endrow</a><br>\r
+&nbsp;<a href="developer-chapter2-endtable.html">2.14 endtable</a><br>\r
+&nbsp;<a href="developer-chapter2-startbox.html">2.15 startbox</a><br>\r
+&nbsp;<a href="developer-chapter2-enterdata.html">2.16 enterdata</a><br>\r
+&nbsp;<a href="developer-chapter2-endbox.html">2.17 endbox</a><br>\r
+&nbsp;<a href="developer-chapter2-startform.html">2.18 startform</a><br>\r
+&nbsp;<a href="developer-chapter2-addcheckbox.html">2.19 addcheckbox</a><br>\r
+&nbsp;<a href="developer-chapter2-addradiobox.html">2.20 addradiobox</a><br>\r
+&nbsp;<a href="developer-chapter2-addselectbox.html">2.21 addselectbox</a><br>\r
+&nbsp;<a href="developer-chapter2-addoption.html">2.22 addoption</a><br>\r
+&nbsp;<a href="developer-chapter2-endselectbox.html">2.23 endselectbox</a><br>\r
+&nbsp;<a href="developer-chapter2-addinputbox.html">2.24 addinputbox</a><br>\r
+&nbsp;<a href="developer-chapter2-addtextbox.html">2.25 addtextbox</a><br>\r
+&nbsp;<a href="developer-chapter2-addsubmit.html">2.26 addsubmit</a><br>\r
+&nbsp;<a href="developer-chapter2-addreset.html">2.27 addreset</a><br>\r
+&nbsp;<a href="developer-chapter2-addhiddendata.html">2.28 addhiddendata</a><br>\r
+&nbsp;<a href="developer-chapter2-addbutton.html">2.29 addbutton</a><br>\r
+&nbsp;<a href="developer-chapter2-endform.html">2.30 endform</a><br>\r
+&nbsp;<a href="developer-chapter2-addlink.html">2.31 addlink</a><br>\r
+&nbsp;<a href="developer-chapter2-addimage.html">2.32 addimage</a><br>\r
+&nbsp;<a href="developer-chapter2-addtext.html">2.33 addtext</a><br>\r
+&nbsp;<a href="developer-chapter2-addboldtext.html">2.34 addboldtext</a><br>\r
+&nbsp;<a href="developer-chapter2-additalictext.html">2.35 additalictext</a><br>\r
+&nbsp;<a href="developer-chapter2-addlinebreak.html">2.36 addlinebreak</a><br>\r
+&nbsp;<a href="developer-chapter2-addhorizontalline">2.37 addhorizontalline</a><br>\r
+&nbsp;<a href="developer-chapter2-startlist.html">2.38 startlist</a><br>\r
+&nbsp;<a href="developer-chapter2-additem.html">2.39 additem</a><br>\r
+&nbsp;<a href="developer-chapter2-endlist.html">2.40 endlist</a><br>\r
+<a href="developer-chapter3.html">Chapter 3: Authentication Module</a><br>\r
+&nbsp;<a href="developer-chapter3-guidance.html">3.1 Guidance</a><br>\r
+&nbsp;<a href="developer-chapter3-new.html">3.2 new</a><br>\r
+&nbsp;<a href="developer-chapter3-loadsettings.html">3.3 loadsettings</a><br>\r
+&nbsp;<a href="developer-chapter3-capabilities.html">3.4 capabilities</a><br>\r
+&nbsp;<a href="developer-chapter3-convert.html">3.5 convert</a><br>\r
+&nbsp;<a href="developer-chapter3-dateconvert.html">3.6 dateconvert</a><br>\r
+&nbsp;<a href="developer-chapter3-geterror.html">3.7 geterror</a><br>\r
+&nbsp;<a href="developer-chapter3-connect.html">3.8 connect</a><br>\r
+&nbsp;<a href="developer-chapter3-disconnect.html">3.9 disconnect</a><br>\r
+&nbsp;<a href="developer-chapter3-getuserlist.html">3.10 getuserlist</a><br>\r
+&nbsp;<a href="developer-chapter3-getpermissions.html">3.11 getpermissions</a><br>\r
+&nbsp;<a href="developer-chapter3-adduser.html">3.12 adduser</a><br>\r
+&nbsp;<a href="developer-chapter3-edituser.html">3.13 edituser</a><br>\r
+&nbsp;<a href="developer-chapter3-deleteuser.html">3.14 deleteuser</a><br>\r
+&nbsp;<a href="developer-chapter3-userauth.html">3.15 userauth</a><br>\r
+&nbsp;<a href="developer-chapter3-flushusers.html">3.16 flushusers</a><br>\r
+&nbsp;<a href="developer-chapter3-populatetables.html">3.17 populatetables</a><br>\r
+<a href="developer-chapter4.html">Chapter 4: Output Format Module</a><br>\r
+&nbsp;<a href="developer-chapter4-guidance.html">4.1 Guidance</a><br>\r
+&nbsp;<a href="developer-chapter4-new.html">4.2 new</a><br>\r
+&nbsp;<a href="developer-chapter4-initialise.html">4.3 initialise</a><br>\r
+&nbsp;<a href="developer-chapter4-loadsettings.html">4.4 loadsettings</a><br>\r
+&nbsp;<a href="developer-chapter4-getoptions.html">4.5 getoptions</a><br>\r
+&nbsp;<a href="developer-chapter4-errorflag.html">4.6 errorflag</a><br>\r
+&nbsp;<a href="developer-chapter4-errormessage.html">4.7 errormessage</a><br>\r
+&nbsp;<a href="developer-chapter4-clearflag.html">4.8 clearflag</a><br>\r
+&nbsp;<a href="developer-chapter4-processimage.html">4.9 processimage</a><br>\r
+&nbsp;<a href="developer-chapter4-languagestrings.html">4.10 languagestrings</a><br>\r
+<a href="developer-chapter5.html">Chapter 5: Export Format Module</a><br>\r
+&nbsp;<a href="developer-chapter5-guidance.html">5.1 Guidance</a><br>\r
+&nbsp;<a href="developer-chapter5-new.html">5.2 new</a><br>\r
+&nbsp;<a href="developer-chapter5-initialise.html">5.3 initialise</a><br>\r
+&nbsp;<a href="developer-chapter5-loadsettings.html">5.4 loadsettings</a><br>\r
+&nbsp;<a href="developer-chapter5-getoptions.html">5.5 getoptions</a><br>\r
+&nbsp;<a href="developer-chapter5-exportimage.html">5.6 exportimage</a><br>\r
+&nbsp;<a href="developer-chapter5-errorflag.html">5.7 errorflag</a><br>\r
+&nbsp;<a href="developer-chapter5-errormessage.html">5.8 errormessage</a><br>\r
+&nbsp;<a href="developer-chapter5-clearflag.html">5.9 clearflag</a><br>\r
+&nbsp;<a href="developer-chapter5-languagestrings.html">5.10 languagestrings</a><br>\r
+<a href="developer-chapter6.html">Chapter 6: Xestia Scanner Server Page Format</a><br>\r
+<a href="developer-chapter7.html">Chapter 7: Languages</a>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/guide.html b/Documentation/English (British)/guide.html
new file mode 100644 (file)
index 0000000..b81a750
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Documentation Guide</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Documentation Guide</span><br>\r
+\r
+Throughout the documentation in Xestia Scanner Server, certain icons will appear which will mean the following:<br><br>\r
+\r
+<div class="warningbox">\r
+    <div class="message warning">\r
+        <span class="warningtext">\r
+            <b>Warning</b><br>\r
+            This is a warning message meaning that a certain action you take may cause consequences to your Xestia Scanner Server installation.\r
+        </span>\r
+    </div>\r
+</div>\r
+\r
+<br>\r
+\r
+<div class="messagebox">\r
+    <div class="message note">\r
+        <b>Note</b><br>\r
+        This is a note which gives some information.\r
+    </div>\r
+</div>\r
+\r
+<br>\r
+\r
+<div class="messagebox">\r
+    <div class="message hint">\r
+        <b>Hint</b><br>\r
+        This is a hint to give you some helpful advice.\r
+    </div>\r
+</div>\r
+\r
+<br>\r
+\r
+<div class="code">\r
+    This is where the code will be displayed using a fixed font.\r
+</div>\r
+\r
+<br>\r
+\r
+<div class="specific apache132x">\r
+   This is a section of the documentation which contains instructions for Apache HTTP Web Server versions 1.3 and 2.x.\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/index.html b/Documentation/English (British)/index.html
new file mode 100644 (file)
index 0000000..059a748
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Index Page</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Welcome</span><br>\r
+This is the documentation for Xestia Scanner Server and it is split into three parts:\r
+<ul><li><span class="heading"><a href="user.html">User Documentation</a></span><br>The User Documentation provides information on how to install and use your Xestia Scanner Server installation.</li><li><span class="heading"><a href="tutorial.html">Tutorial Documentation</a></span><br>The Tutorial Documentation provides some tutorials on how to use certain featurs of Xestia Scanner Server.</li><li><span class="heading"><a href="developer.html">Developer Documentation</a></span><br>The Developer Documentation provides information on how to create additional presentation modules, authentication modules, export modules, output modules and information on translating Xestia Scanner Server into another language.</li></ul>\r
+The <a href="guide.html">Xestia Scanner Server Documentation Guide</a> provides information about the symbols that appear while reading the documentation.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/style.css b/Documentation/English (British)/style.css
new file mode 100644 (file)
index 0000000..e569755
--- /dev/null
@@ -0,0 +1,162 @@
+a {
+       color: #FFFFFF;
+}
+
+a:hover {
+       color: #EEEEEE;
+}
+
+body {
+       background-repeat: repeat-x;
+       background-image: url('images/background.png');
+       background-color: #402040;
+       color: #FFFFFF;
+       margin: 0px;
+       padding: 0px;
+       font-family: sans-serif;
+       font-size: 13px;
+}
+
+.footnote {
+       height: 1px;
+       background-color: #FFFFFF;
+       width: 25%;
+}
+
+.apptitle {
+       position: absolute;
+       font-weight: bold;
+       text-align: left;
+       z-index: 1;
+       left: 0;
+       padding-left: 6px;
+       font-size: 16px;
+}
+
+.menubarback {
+       background-image: url('images/menutop.png');
+       background-repeat: repeat-x;
+       background-position: top;
+}
+
+.menubar {
+       border-bottom-width: 1px;
+       border-bottom-color: #EE70EE;
+       border-bottom-style: solid;
+       text-align: right;
+       padding: 4px;
+       padding-right: 6px;
+}
+                       
+.pageinformation {
+       padding: 8px;
+}
+
+.message {
+       background-color: #transparent;
+       padding: 5px;
+       border-color: #D070D0;
+       border-width: 1px;
+       border-style: solid;
+}
+
+.warning {
+       background-image: url('images/warning.png');
+       background-repeat: no-repeat;
+       border-color: #FF1010;
+       background-color: transparent;
+       padding-left: 50px;
+       background-position: 9 7;
+}
+
+.messagebox {
+       background-image: url('images/messageback.png');
+       background-repeat: repeat-x;
+       background-color: #704670;
+       width: 60%;
+       margin-left: auto;
+       margin-right: auto;                             
+}
+
+.warningbox {
+       background-image: url('images/warningback.png');
+       background-repeat: repeat-x;
+       background-color: #701010;
+       width: 60%;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+.note {
+       background-image: url('images/note.png');
+       background-repeat: no-repeat;
+       padding-left: 50px;
+       background-position: 9 7;
+}
+
+.hint {
+       background-image: url('images/hint.png');
+       background-repeat: no-repeat;
+       padding-left: 50px;
+       background-position: 8 7;
+}
+
+.specific {
+       min-height:64px;                                
+}
+
+.apache132x {
+       background-image: url('images/apache132x.png');
+       background-repeat: no-repeat;
+       padding-left: 70px;
+}
+
+.code {
+       background-image: url('images/messageback.png');
+       background-repeat: repeat-x;
+       background-position: top;
+       background-color: #704670;
+       border-color: #D070D0;
+       border-style: solid;
+       border-width: 1px;
+       font-family: fixed;
+       padding: 5px;
+       width: 80%;
+       margin-left: auto;
+       margin-right: auto;
+}
+
+.pagetitle {
+       font-weight: bold;
+       font-size: 16px;
+}
+
+.heading {
+       font-weight: bold;
+       font-size: 14px;
+} 
+
+.infotable {
+       margin-left: auto;
+       margin-right: auto;
+       cell-padding: 0px;
+       border-collapse: collapse;
+       border-width: 1px;
+       border-style: solid;
+       border-color: #D070D0;
+}
+
+.tableheading {
+       background-image: url('images/messageback.png');
+       padding: 5px;
+       border-bottom-width: 1px;
+       border-bottom-style: solid;
+       border-color: #B060B0;
+        font-size: 13px;
+}
+
+.tabledata {
+       padding: 5px;
+       background-color: #402040;
+        font-size: 13px;
+}
\ No newline at end of file
diff --git a/Documentation/English (British)/tutorial-scan.html b/Documentation/English (British)/tutorial-scan.html
new file mode 100644 (file)
index 0000000..b7db954
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Tutorial Documentation - Scan and download document</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Tutorial: Scan a document and download it</span>\r
+<br><br>\r
+After logging in, select the scanner you want to use from the drop down list and click on the ‘Switch Scanner’ button. This will load the default settings for that scanner.\r
+<br><br>\r
+After this, review the document settings in the Document Settings box, check the ‘Preview Document’ box at the top and click on the ‘Start Scanning’ button. The scanner will then begin to scan the document and after scanning it, a preview of document will appear.\r
+<br><br>\r
+After reviewing the document and making the required changes to the document settings, uncheck the ‘Preview Document’ box at the top and click on the ‘Start Scanning’ button again. \r
+<br><br>\r
+After the scanning is complete, a new screen will appear, for the output format module select PNG and click on the ‘Switch Module’ button. This will ensure that the PNG output format module is being used.\r
+<br><br>\r
+For the export format, check the Download export format module box and set the filename to use to “xestiascannerserver-tutorial.png” (without the quotes).\r
+<br><br>\r
+Go to the bottom of the screen and click on the ‘Process’ button. This will then covert the file into the PNG format and make it available for download under the “xestiascannerserver-tutorial.png” filename.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/tutorial.html b/Documentation/English (British)/tutorial.html
new file mode 100644 (file)
index 0000000..5367c39
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Tutorial Documentation</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Tutorial Documentation</span>\r
+<br><br>\r
+The Tutorial Documentation provides a tutorial on how to use some of the most common functions in Xestia Scanner Server.\r
+\r
+<br><br>\r
+<a href="tutorial-scan.html">Scan and download document</a><br>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter1-install.html b/Documentation/English (British)/user-chapter1-install.html
new file mode 100644 (file)
index 0000000..02b69b7
--- /dev/null
@@ -0,0 +1,174 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 1.2: Installing Xestia Scanner Server</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.2: Installing Xestia Scanner Server</span>\r
+<br><br><b>1.2.1: Copying files</b>\r
+<br><br>Before Xestia Scanner Server can be used, the files need to be copied to the correct place. After extracting the archive, the structure of the extracted archive should be like this:\r
+<br><br>\r
+<b>Documentation</b> – Documentation that is available in several languages.<br>\r
+<b>cgi-files</b> – The main Xestia Scanner Server script, associated modules, installer scripts and language files. <br>\r
+&nbsp;<b>Modules</b> – Modules for Xestia Scanner Server are stored here.<br>\r
+&nbsp;&nbsp;<b>Auth</b> – Authentication modules are stored here.<br>\r
+&nbsp;&nbsp;<b>Export</b> – Export modules are stored here.<br>\r
+&nbsp;&nbsp;<b>Presentation</b> – Presentation modules are stored here.<br>\r
+&nbsp;&nbsp;<b>Output</b> – Output modules are stored here.<br>\r
+&nbsp;&nbsp;<b>System</b> – System modules are stored here.<br>\r
+&nbsp;<b>lang</b> – The directory for language files in Xestia Scanner Server.<br>\r
+&nbsp;<b>scans</b> – The directory for scanned documents in Xestia Scanner Server.<br>\r
+<b>misc</b> – Miscellaneous files (mainly for developers).<br>\r
+<b>non-cgi-files</b> – Non CGI files that need to be placed outside of the cgi-bin directory (such as the images for the default layout).\r
+&nbsp;<b>images</b> – Images for the default layout.\r
+<br><br>\r
+The files in the cgi-files directory should be copied to the cgi-bin<sup>1</sup> directory<sup>2</sup> and the files in the non-cgi-files directory should be copied to a directory which can be accessed from the web server (so that it can be read). This must be copied to outside the cgi-files. \r
+<br><br>\r
+<b>1.2.2 Setting Permissions</b>\r
+<br><br>\r
+The following permissions should be set for the files that have been copied to the cgi-files directory based on the user/web server daemon set as owner of the files and the web server daemon set as the group (the following file list should apply to those running *nix/BSD systems): \r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Filename</td>\r
+  <td class="tableheading">Owner</td>\r
+  <td class="tableheading">Group</td>\r
+  <td class="tableheading">Others</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><i>(Top Directory)</i><br>After installation it is advised to make this directory readonly to prevent settings changed.</td>\r
+   <td class="tabledata">RWX</td>\r
+   <td class="tabledata">RWX</td>\r
+   <td class="tabledata">None</td>\r
+</tr>\r
+ <tr>\r
+   <td class="tabledata"><b>Modules</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>Modules/Auth</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Modules/Auth/*.pm</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>   \r
+   <td class="tabledata"><b>Modules/Export</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Modules/Export/*.pm</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>Modules/Presentation</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Modules/Presentation/*.pm</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>Modules/Output</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Modules/Output/*.pm</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>Modules/System</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Modules/System/*.pm</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>lang</b></td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">lang/*.lang</td>\r
+   <td class="tabledata">R</td>\r
+   <td class="tabledata">R</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata"><b>scans</b></td>\r
+   <td class="tabledata">RWX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">xsdss.cgi</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">install.cgi</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">install-multiuser.cgi</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">RX</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">page.html</td>\r
+   <td class="tabledata">R</td>\r
+   <td class="tabledata">R</td>\r
+   <td class="tabledata">None</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+\r
+R = Read, W = Write, X = Execute/Allow directory listing\r
+\r
+<br><br>\r
+For the non-cgi files directory, read only permissions should be set on all files (and read and allow directory listings for directories) as no writing should be needed. Once this is done, the installer script can be run by browsing to URI location of where the files in the cgi-files directory were in place and adding install.cgi to the end of it.\r
+<br><br>\r
+<div class="footnote"><sup>1</sup> The cgi-bin directory is used for storing scripts that use the Common Gateway Interface (CGI). CGI scripts are typically associated with Perl scripts but can also be C++, C, Python, shell script and many others.<br><br><sup>2</sup> Some servers are configured so that CGI scripts can run from any directory so in this case Xestia Scanner Server doesn't have to be placed in the cgi-bin directory. \r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter1-installscript.html b/Documentation/English (British)/user-chapter1-installscript.html
new file mode 100644 (file)
index 0000000..6d39573
--- /dev/null
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 1.3 Installer Script</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.3 Installer Script</span>\r
+<br><br>\r
+After pointing your browser to the installer script, a page appears which guides you through configuring the settings for Xestia Scanner Server.\r
+<br><br>\r
+At the top of the page a drop down box is available to change the language of the installer script to another language which is more easier to understand, simply select the language from the drop down box and click on the Switch button, the script will then switch to the selected language.\r
+<br><br>\r
+The installer script will preform three tests, the first being to check if all the needed modules are there, the second test is to check if the modules needed for the authentication modules are there and finally a test to check if the directories have their correct permissions set.\r
+<br><br>\r
+Before the settings can be configured, checks are made to make sure that all of the needed modules are installed properly. If any of the needed modules are missing an error message will appear saying that one or more of the required Perl modules is missing and will need to be installed which can be done from the CPAN interface.\r
+<br><br>\r
+The installer script then checks to see if at least of the Perl modules for the database modules are installed. If none of the Perl modules needed for the authentication modules are found then an error message will appear saying that none of the Perl modules needed for the authentication modules are installed and will need to be installed which can be done from the CPAN interface.\r
+<br><br>\r
+Finally, the installer script then checks to see if the directories have the minimum correct permissions set. If one or more of the directories has an error, then a message appears saying to make sure that the correct permissions are set.\r
+<br><br>\r
+<div class="messagebox">\r
+<div class="message hint"><b>Hint</b><br><br>\r
+More information on solving problems that occur while installing Xestia Scanner Server can be found in Chapter 5: Troubleshooting.\r
+</div>\r
+</div>\r
+<br><br>\r
+When the installer finds that everything is fine in regards to Perl modules and file permissions, a form appears allowing to configure the Xestia Scanner Server installation to specific needs. Some default values are given which will work with the file-based authentication modules.\r
+<br><br>\r
+The configuration settings in detail:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Images (URI path)</td>\r
+  <td class="tabledata">Specifies the URI path for the images used in the page layout.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Scans (URI path)</td>\r
+  <td class="tabledata">Specifies the URI path for the scanned images.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Scans (Filesystem path)</td>\r
+  <td class="tabledata">Specifies the Filesystem path to store the scanned images when processed by an output module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Date Format</td>\r
+  <td class="tabledata">Specifies the date format to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">System Language</td>\r
+  <td class="tabledata">Specifies the language to use for Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Presentation Module</td>\r
+  <td class="tabledata">Specifies the presentation module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Output Module</td>\r
+  <td class="tabledata">Specifies the default output module to use after a scan is made.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Authentication Module</td>\r
+  <td class="tabledata">Specifies the authentication module to use for the user management.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Server</td>\r
+  <td class="tabledata">Specifies the database server to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Port</td>\r
+  <td class="tabledata">Specifies the database server port to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Protocol</td>\r
+  <td class="tabledata">Specifies the database protocol to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Name</td>\r
+  <td class="tabledata">Specifies the database name to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Username</td>\r
+  <td class="tabledata">Specifies the database username to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Password</td>\r
+  <td class="tabledata">Specifies the database password to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Table Prefix</td>\r
+  <td class="tabledata">Specifies the database table prefix to use for the authentication module.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+There are two options also available to delete the installer script when finished and also the multiuser script if it is not needed. \r
+<br><br>\r
+Click on the Save Settings button to write the configuration file or the Reset Settings button to restore the settings to their default values.\r
+<br><br>\r
+After clicking on the Save Settings button, some checks are made to make sure that data passed is correct, the configuration file is written (and the installer and multiuser installer scripts are deleted if requested) and a message appears saying that Xestia Scanner Server can now be used by clicking on the link at the bottom of the page.\r
+<br><br>\r
+If the authentication module selected is a module which needs to be setup for the user management (which is also known as a multiuser authentication module) then you'll be prompted to run the Multiuser Installer script.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter1-multiuserinstallscript.html b/Documentation/English (British)/user-chapter1-multiuserinstallscript.html
new file mode 100644 (file)
index 0000000..3e1d400
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 1.4 Multiuser Installer Script</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.4 Multiuser Installer Script</span>\r
+<br><br>\r
+After pointing or being directed to this script, a page appears which guides you through setting up the multiuser tables.\r
+<br><br>\r
+At the top of the page a drop down box is available to change the language of the installer script to another language which is more easier to understand, simply select the language from the drop down box and click on the Switch button, the script will then switch to the selected language.\r
+<br><br>\r
+The installer will attempt to load the configuration file created from the installer script if that script was run previously to save time filling in those details again otherwise you will need to use the correct authentication module and the correct database server authentication details in order to setup the multiuser tables.\r
+<br><br>\r
+The configuration settings in detail:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Authentication Module</td>\r
+  <td class="tabledata">Specifies the authentication module to use. Only modules which have multiuser support are listed here.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Server</td>\r
+  <td class="tabledata">Specifies the database server to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Port</td>\r
+  <td class="tabledata">Specifies the database server port to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Protocol</td>\r
+  <td class="tabledata">Specifies the database protocol to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Name</td>\r
+  <td class="tabledata">Specifies the database name to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Username</td>\r
+  <td class="tabledata">Specifies the database username to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Password</td>\r
+  <td class="tabledata">Specifies the database password to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Database Table Prefix</td>\r
+  <td class="tabledata">Specifies the database table prefix to use for the authentication module.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Username</td>\r
+  <td class="tabledata">Specifies the username with administrative access to the scanner server software.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password to set the for administrative access account to the scanner server software.</td>\r
+ </tr>\r
+</table>\r
+<br><br>\r
+There are also options available to specify if certain tables (modules permissions, scanners permissions, sessions and users) should be created. If you are installing Xestia Scanner Server for the first time then make sure all of the checkboxes for creating the tables are checked.\r
+<br><br>\r
+The tables can be forcibly recreated if there are problems with the existing tables by simply checking the 'Force recreation of the selected tables' box.This will delete and recreate the tables as if it was being installed.\r
+<br><br>\r
+As with the original install script, there are two options also available to delete the installer script when finished and also the multiuser script if it is not needed (otherwise, leave this option unchecked if you need to create more tables).\r
+<br><br>\r
+After clicking on the Create tables button, the tables are then created and if any errors have occurred whilst creating the tables then they will be displayed on the next screen. If no errors have occurred, the installation is now complete and you can click on the 'Start using Xestia Scanner Server' link.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter1-obtaining.html b/Documentation/English (British)/user-chapter1-obtaining.html
new file mode 100644 (file)
index 0000000..523a7d4
--- /dev/null
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 1.1 Obtaining Xestia Scanner Server</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">1.1: Obtaining Xestia Scanner Server</span>\r
+<br><br>\r
+Xestia Scanner Server can be obtained either through the Subversion repository or extracted from a source archive that is available on Xestia Scanner Server homepage.\r
+<br><br>\r
+<b>1.1.1: Archive Extraction</b>\r
+<br><br>\r
+The contents of the Xestia Scanner Server archive can be extracted using gzip if it's a Gzip archive, bzip2 if it's a Bzip2'ed archive, 7za if it's a 7-Zip archive and unzip if it's a ZIP archive.\r
+<br><br>\r
+Bear in mind the following is done from a command console. GUI interfaces can also do the same as preformed here and mainly involves opening the archive and clicking on the Extract/Extract All button or simply dragging the folder containing from out of the archive (usually making a copy of the contents in the archive).\r
+<br><br>\r
+<div class="messagebox"><div class="message note"><b>Note</b>\r
+<br><br>\r
+The naming convention of the Xestia Scanner Server archives go as the following:\r
+<br><br>\r
+xestiascannerserver-x.y.z(-e).arc\r
+<br><br>\r
+Where x is the major version, y is the minor version and z is the revision with (-e) meaning a very tiny modification that had to be done that did not merit an increment to the revision number.\r
+    </div>\r
+</div>\r
+<br><br>\r
+When downloading an archive, the archive can be checked (by downloading the file with the same name but with .sha256 added to the end of it) using shasum(1) by doing the following to ensure it is downloaded correctly:\r
+<br><br>\r
+<div class="code">\r
+shasum -a 256 xestiascannerserver-x.y.z(-e).arc\r
+</div>\r
+<br><br>\r
+shasum should then generate the SHA-256 or MD5 checksum that should match the one that appears in the file with .sha256 or .md5 appended to it. If it does not match (and the file containing the sha256 or md5sum hash is the correct version) then the archive should be downloaded again and repeat the same process.\r
+<br><br>\r
+To extract the gzip archive, the following command should be preformed when switched to the correct directory to extract from.\r
+<br><br>\r
+<div class="code">\r
+gzip -d -c (path)/xestiascannerserver-0.1.0.tar.gz | tar -xv\r
+</div>\r
+<br><br>\r
+A list of files that have been extracted will then appear with the contents of the archive appearing in the directory that the archive was extracted to.\r
+<br><br>\r
+To extract the bzip2 archive, the following command should be preformed when switched to the correct directory to extract from.\r
+<br><br>\r
+<div class="code">\r
+bzip2 -d -c (path)/xestiascannerserver-0.1.0.tar.bz2 | tar -xv\r
+</div>\r
+<br><br>\r
+A list of files that have been extracted will then appear with the contents of the archive appearing in the directory that the archive was extracted to.\r
+<br><br>\r
+To extract the ZIP archive, the following command should be preformed when switched to the correct directory to extract from.\r
+<br><br>\r
+<div class="code">\r
+unzip (path)/xestiascannerserver-0.1.0.zip\r
+</div>\r
+<br><br>\r
+A list of files that have been extracted will then appear with the contents of the archive appearing in the directory that the archive was extracted to.\r
+<br><br>\r
+To extract the 7Zip archive, the following command should be preformed when switched to the correct directory to extract from.\r
+<br><br>\r
+<div class="code">\r
+7za e (path)/xestiascannerserver-0.1.0.7z\r
+</div>\r
+<br><br>\r
+A list of files that have been extracted will then appear with the contents of the archive appearing in the directory that the archive was extracted to.\r
+<br><br>\r
+<b>1.1.2: Subversion Access</b>\r
+<br><br>\r
+Xestia Scanner Server can also be obtained through checking out the code from the Subversion repository.\r
+<br><br>\r
+<div class="messagebox"><div class="message note"><b>Note</b><br><br>\r
+Bear in mind that the code that is in the Xestia Scanner Server Subversion repository is normally unstable and could very well cause unexpected problems (such as warnings that appear in the web server error log that can be easily fixed and alterations to the database structure which requires an upgrade script which hasn't been written yet for that particular version yet).\r
+</div></div>\r
+<br><br>\r
+Xestia Scanner Server can be obtained from the Subversion repository by doing the following in a command console after selecting the correct directory to put it in:\r
+<br><br>\r
+<div class="code">\r
+svn checkout svn://svn.berlios.de/xestiascansrv/trunk\r
+</div>\r
+<br><br>\r
+A list of files then appear as they are received from the Subversion repository and placed in the directory the command console is currently in. To update the code stored locally with code that is in the Xestia Scanner Server Subversion repository this command should be done after changing to the directory where the local copy of the Xestia Scanner Server Subversion code is:\r
+<br><br>\r
+<div class="code">\r
+svn update\r
+</div>\r
+<br><br>\r
+A list of files will then appear showing which files has been updated.1 The version of shasum talked about here is the shasum script that is used by the Digest::SHA::PurePerl Perl module which can produce checksums in SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 which can be installed via CPAN.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter1.html b/Documentation/English (British)/user-chapter1.html
new file mode 100644 (file)
index 0000000..173acc6
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Chapter 1: Installation</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 1: Installation</span>\r
+Before Xestia Scanner Server can be used, Xestia Scanner Server needs to be installed properly and this involves obtaining the code from a source package or from a Subversion<sup>1</sup> repository, copying the needed files into the correct place, setting the correct permissions on the files and running the installation script.\r
+<br><br>\r
+This chapter is split into two parts with the first part explaining on how to obtain Xestia Scanner Server and the second part explaining on how to install Xestia Scanner Server.\r
+<div class="footnote"><sup>1</sup> Subversion is a version control system which tracks changes to data stored in the repositories and allows easy updating of source code after the source code is checked out.\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter2-scanning.html b/Documentation/English (British)/user-chapter2-scanning.html
new file mode 100644 (file)
index 0000000..2a15089
--- /dev/null
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 2.1 Scanning</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.1 Scanning</span>\r
+<br><br>\r
+Before scanning, in most cases you will need to login using the username and password either given by the multiuser installer script or by the administrator who is running the scanner server software.\r
+<br><br>\r
+After logging in, you will presented with a screen with the first scanner selected and the scanner's default settings loaded.\r
+<br><br>\r
+<b>2.1.1 Document Settings</b>\r
+<br><br>\r
+This box contains the settings for adjusting the scanned document.\r
+<br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Top Left X</td>\r
+  <td class="tabledata">This specifies where the scanner should start from (in millimetres, from the left hand side of the document).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Top Left Y</td>\r
+  <td class="tabledata">This specifies where the scanner should start from (in millimetres, from the top of the document).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Bottom Right X</td>\r
+  <td class="tabledata">This specifies where the scanner should stop (in millimetres, from the left hand side of the document).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Bottom Right Y</td>\r
+  <td class="tabledata">This specifies where the scanner should stop (in millimetres, from the top of the document).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Picture Resolution</td>\r
+  <td class="tabledata">Specifies the picture resolution of the scanned document.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Rotate</td>\r
+  <td class="tabledata">Rotates the document (either 0, 90, 180 or 270 degrees).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Brightness</td>\r
+  <td class="tabledata">Specifies how bright the document should be.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Colour</td>\r
+  <td class="tabledata">Specifies if the document should be coloured (RGB) or greyscale.</td>\r
+ </tr>\r
+</table>\r
+<br>           \r
+<b>2.1.2 Switching Scanners</b>\r
+<br><br>\r
+To switch scanners, select the scanner from the drop down box at the top of the page, select the scanner and then click on the Switch Scanner button. This will switch to the scanner selected and use the default settings for that scanner in the document settings.\r
+<br><br>\r
+<b>2.1.3 Preview Document</b>\r
+<br><br>\r
+To preview a document on the selected scanner, check the document settings are correct and then click on the Preview Document checkbox. Click on the Start Scanning button and then a preview of the scanned image will appear which can then be adjusted in the document settings box.\r
+<br><br>\r
+<b>2.1.4 Scan Document</b>\r
+<br><br>\r
+To scan a document on the selected scanner, check the document settings are correct, ensure that the Preview Document checkbox is unchecked and click on the Start Scanning button. This will start the scanning the document that is in the scanner. The next screen will then be the output and export format modules settings screen along with a preview of the document that has been scanned in.\r
+<br><br>\r
+<b>2.1.5 Export & Output Format Modules</b>\r
+<br><br>\r
+On this screen, you are shown a preview of the image (which has been scaled down), output format module and export format module settings. An output format module allows the scanned image to be exported into a common image format (such as PNG and JPEG) while an export format module allows the processed document to be exported for downloading or sent to someone through email.\r
+<br><br>\r
+To select the output module you want to use click on the drop down box and select the output module you want and click on switch module. The screen than loads again to reflect that the output module has been changed and if there are any options available for that output module then they will appear. After configuring the output module settings, an export format needs to be configured.\r
+<br><br>\r
+To use an export format module, check the checkbox next to the name of the export format module you want to use, specify the settings for the export format module. After selecting the required export format module, click on the Process button to process the document with the selected output format module and export format modules.\r
+<br><br>\r
+The next screen will display the results of the output format module and export format modules and if any errors occurred while using these modules.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter2-users.html b/Documentation/English (British)/user-chapter2-users.html
new file mode 100644 (file)
index 0000000..a12344c
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 2.2 User Management</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">2.2 User Management</span>\r
+<br><br>\r
+To ensure users do not use or use only certain scanners, output format modules and export format modules, user management is required.\r
+<br><br>\r
+User management can be done (as a user with administrative privileges) by clicking on the User Management link on the top menu.\r
+<br><br>\r
+<b>2.1.1 Add a User</b>\r
+<br><br>\r
+To add a user to the user management list, click on the Add Users button on the user list. This will then display the following settings to enter for the user under the User Details section:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">User name</td>\r
+  <td class="tabledata">Specifies the username of the account.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Name</td>\r
+  <td class="tabledata">Specifies the name of the person associated with this account.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Administrator Privileges</td>\r
+  <td class="tabledata">Specifies if the account has administrator privileges. An account with administrator privileges is able to manage the users who can access scanners and can the settings for the scanner server software itself.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Account Enabled</td>\r
+  <td class="tabledata">Specifies if the account should be enabled or disabled. If the account enabled button is not checked then this account will not be able to login.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Password</td>\r
+  <td class="tabledata">Specifies the password to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Confirm Password</td>\r
+  <td class="tabledata">Confirms the password to use by entering it a second time.</td>\r
+ </tr>\r
+</table>\r
+<br>\r
+The next section is the Scanner List which lists the permissions for the scanners. To allow access to a scanner, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+The third section is the Output Format Module List which lists the permissions for the output format modules. To allow access to an output format module, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+The final section is the Export Format Module List which lists the permissions for the export format modules. To allow access to an export format module, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+To confirm the settings given, click on the Add User button at the bottom of the screen. To clear the values and start again click on the Clear values also at the bottom of the screen.\r
+<br><br>\r
+<b>2.1.2 Edit a User</b>\r
+<br><br>\r
+To edit a user’s settings, select a user on the user management list and click on the Edit link in the List Users screen. This will display the following settings to enter for the user under the User Details section:\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Setting</td>\r
+  <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">User name</td>\r
+  <td class="tabledata">Specifies the username of the account.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Name</td>\r
+  <td class="tabledata">Specifies the name of the person associated with this account.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Administrator Privileges</td>\r
+  <td class="tabledata">Specifies if the account has administrator privileges. An account with administrator privileges is able to manage the users who can access scanners and can the settings for the scanner server software itself.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Account Enabled</td>\r
+  <td class="tabledata">Specifies if the account should be enabled or disabled. If the account enabled button is not checked then this account will not be able to login.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">New Password</td>\r
+  <td class="tabledata">Specifies the new password to use.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">Confirm New Password</td>\r
+  <td class="tabledata">Confirms the new password to use by entering it a second time.</td>\r
+ </tr>\r
+</table>\r
+<br>\r
+The next section is the Scanner List which lists the permissions for the scanners. It will also display the permissions for any scanners which aren’t plugged in but the user can access when they are plugged in again. To allow access to a scanner, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+The third section is the Output Format Module List which lists the permissions for the output format modules. To allow access to an output format module, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+The final section is the Export Format Module List which lists the permissions for the export format modules. To allow access to an export format module, simply check the Allow Access checkbox next to the name of the scanner.\r
+<br><br>\r
+To save the changed settings for the user, click on the Edit User button. To revert the settings back to their original settings click on the Clear values button.\r
+<br><br>\r
+<div class="messagebox">\r
+<div class="message note">\r
+<b>Note</b>\r
+<br><br>If the username is changed, the user under the previous username will be logged out and will have to login using the new username.\r
+</div>\r
+</div>\r
+<br><br>\r
+<b>2.1.3 Delete a User</b>\r
+<br><br>\r
+To delete a user, click on the Delete link next to the user you want to delete on the user management list and to confirm deletion click on the ‘Yes, delete user’ button. This will remove the user from the list.\r
+<br><br>\r
+Deleting the administrative account used to manage users is not recommended as the only way to recover from this is to rerun the Multiuser Installer script again.\r
+<br><br>\r
+<b>2.1.4 Logout All Users</b>\r
+<br><br>\r
+If you need to logout all users for the purposes of maintenance or in the event of an emergency, you are able to logout all users. To do this, click on the Logout All Users button on the users list and then click on ‘Logout All Users’ to confirm this action. This will log everyone out (including the user requesting this action). You will need to log back in again to continue.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter2.html b/Documentation/English (British)/user-chapter2.html
new file mode 100644 (file)
index 0000000..4d8d148
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Chapter 2: Operation</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 2: Operation</span>\r
+<br><br>\r
+Now that Xestia Scanner Server is installed and setup, this chapter is about operating Xestia Scanner Server. This chapter is split into scanning and user management.\r
+<br>\r
+<ul>\r
+<li>Scanning: Scanning, Outputting and Exporting.</li>\r
+<li>User Management: Adding, Editing, Deleting Users and Setting Permissions.</li>\r
+</ul>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter3-edit.html b/Documentation/English (British)/user-chapter3-edit.html
new file mode 100644 (file)
index 0000000..ce8c51f
--- /dev/null
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - 3.1 Editing the settings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">3.1 Editing the settings</span>\r
+<br><br>\r
+To edit the settings, click on the ‘Edit Settings’ button in the View Settings sub-menu, a form then appears allowing the settings for Xestia Scanner Server to be edited.\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Images (URI path)</td>\r
+   <td class="tabledata">Specifies the Images (URI path) to use for displaying images when using the page template with Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Scans (URI path)</td>\r
+   <td class="tabledata">Specifies the Scanned Images (URI path) to use for downloading images.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Scans (Filesystem path)</td>\r
+   <td class="tabledata">Specifies the filesystem path of where the images for downloading are stored.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Date Format</td>\r
+   <td class="tabledata">Specifies the date format to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">System Language</td>\r
+   <td class="tabledata">Specifies the system language to use in Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Presentation Module</td>\r
+   <td class="tabledata">Specifies the presentation module to use in Xestia Scanner Server.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Output Format Module</td>\r
+   <td class="tabledata">Specifies the default output format module to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Authentication Module</td>\r
+   <td class="tabledata">Specifies the authentication module to use.</td>\r
+ </tr>\r
+</table>\r
+<br><Br>\r
+The following options are used only by the authentication modules:\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+   <td class="tableheading">Setting</td>\r
+   <td class="tableheading">Description</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Server</td>\r
+   <td class="tabledata">Specifies the database server to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Port</td>\r
+   <td class="tabledata">Specifies the database port to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Protocol</td>\r
+   <td class="tabledata">Specifies the database protocol to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Name</td>\r
+   <td class="tabledata">Specifies the database name to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Username</td>\r
+   <td class="tabledata">Specifies the database username to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Password</td>\r
+   <td class="tabledata">Specifies the database password to use.</td>\r
+ </tr>\r
+ <tr>\r
+   <td class="tabledata">Database Table Prefix</td>\r
+   <td class="tabledata">Specifies the table prefix to use. Multiple Xestia Scanner Server installations can use the same server database so long as the table prefix is different.</td>\r
+ </tr>\r
+</table>\r
+<br>\r
+To save the new settings, click on the ‘Change Settings’ button which will display a confirmation message saying that the settings were changed and will take effect on the next page load of Xestia Scanner Server. Clicking on the ‘Restore current settings’ button will undo any changes made and will restore the current settings. Clicking on the 'Return to the list of settings.' link will return to the list of currently used settings.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter3.html b/Documentation/English (British)/user-chapter3.html
new file mode 100644 (file)
index 0000000..db79124
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Chapter 3: Xestia Scanner Server Settings</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 3: Xestia Scanner Server Settings</span>\r
+<br><br>\r
+The settings that are used in Xestia Scanner Server can be viewed by clicking on the ‘Settings Configuration’ link in the menu which will display a list of settings that are currently in use.\r
+\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter4.html b/Documentation/English (British)/user-chapter4.html
new file mode 100644 (file)
index 0000000..2841ee5
--- /dev/null
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Chapter 4: Troubleshooting</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 4: Troubleshooting</span>\r
+<br><br>\r
+<b>4.1 Common Problems</b>\r
+<br><br>\r
+<table class="infotable">\r
+ <tr>\r
+  <td class="tableheading">Problem</td>\r
+  <td class="tableheading">Symptom</td>\r
+  <td class="tableheading">Solution</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When installing, some of the needed Perl modules have the word ‘Error’ next to them.</td>\r
+  <td class="tabledata">The needed Perl modules are more than likely not installed.</td>\r
+  <td class="tabledata">Install the needed Perl modules from the CPAN<sup>1</sup> archive using the CPAN command interface.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When installing, an error message appears saying that none of the needed Perl modules for the authentication modules are installed.</td>\r
+  <td class="tabledata">The needed Perl module(s) (or the Perl module needed specifically for that certain authentication module) are more than likely not installed.</td>\r
+  <td class="tabledata">Install the needed Perl modules from the CPAN archive using the CPAN command interface.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When installing, an error message appears saying that some of the directories and files have invalid permissions set.</td>\r
+  <td class="tabledata">The directories and/or files have invalid permissions set.</td>\r
+  <td class="tabledata">Change the permissions on the directories and/or files so that are the correct permissions needed.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When installing, no authentication or presentation modules appear in the list of available authentication or presentation modules.</td>\r
+  <td class="tabledata">The modules weren't copied or were copied to the wrong directories.</td>\r
+  <td class="tabledata">Copy or move the authentication modules to the correct directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When installing, no languages appears in the languages selection list.</td>\r
+  <td class="tabledata">The language files weren't copied or were copied to the wrong location.</td>\r
+  <td class="tabledata">Copy or move the language files to the correct directory.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the configuration file does not exist.</td>\r
+  <td class="tabledata">The configuration file has been deleted or the installation script wasn't run.</td>\r
+  <td class="tabledata">Run the installer script (again).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the configuration file has invalid permissions set.</td>\r
+  <td class="tabledata">The configuration file has invalid permissions set.</td>\r
+  <td class="tabledata">Change the permissions on the configuration file so that it can be read.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the authentication module does not exist.</td>\r
+  <td class="tabledata">The authentication module has been deleted or renamed.</td>\r
+  <td class="tabledata">Run the installer script (again).<br>Check if the Modules and Modules/Auth directory have the correct permissions set so that they can be read.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the authentication module has invalid permissions set.</td>\r
+  <td class="tabledata">The authentication module has invalid permissions set.</td>\r
+  <td class="tabledata">Change the permissions on the authentication module so that they can be read (execute permissions not usually needed).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the presentation module does not exist.</td>\r
+  <td class="tabledata">The presentation module has been deleted or renamed.</td>\r
+  <td class="tabledata">Run the installer script (again).<br>Check if the Modules and Modules/Presentation directory have the correct permissions set so that they can be read.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the presentation module has invalid permissions set.</td>\r
+  <td class="tabledata">The presentation module has invalid permissions set.</td>\r
+  <td class="tabledata">Change the permissions on the presentation module so that they can be read (execute permissions not usually needed).</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the language file does not exist.</td>\r
+  <td class="tabledata">The language file does not exist.</td>\r
+  <td class="tabledata">Run the installer script (again).<br>Check if the lang directory has the correct permissions set so that they can be read.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When starting Xestia Scanner Server, a critical error message appears saying that the language file has invalid permissions set.</td>\r
+  <td class="tabledata">The language file has invalid permissions set.</td>\r
+  <td class="tabledata">Change the permissions on the language file so that they can be read.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When trying to scan, the scanner does not appear in the scanner list.</td>\r
+  <td class="tabledata">Either the scanner is:<br>\r
+    Unplugged.<br>\r
+    Not turned on.<br>\r
+    Permissions not set correctly.<br>\r
+    Not supported by the SANE subsystem.</td>\r
+  <td class="tabledata">Plug the scanner in.<br>\r
+    Turn the scanner on.<br>\r
+    Permissions should have been set correctly automatically upon plugging in and may be a bug with the operating system.<br>\r
+    Check the scanner manufactuer’s website to see if they support the scanner through SANE.\r
+    </td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When trying to scan, it is not possible due to invalid permissions set on the user account.</td>\r
+  <td class="tabledata">The administrator operating the Xestia Scanner Server installation has set your account to not use this scanner.</td>\r
+  <td class="tabledata">Speak to the administrator operating the Xestia Scanner Server installation.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When trying to scan, it is not possible due to an error message caused by the scanner.</td>\r
+  <td class="tabledata">The scanner may be malfunctioning.</td>\r
+  <td class="tabledata">Read the manual that came with the scanner and follow the troubleshooting procedure (if any) or contact the manufactuer of the scanner.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When trying to output an image, an error occurs.</td>\r
+  <td class="tabledata">The output module was configured incorrectly.</td>\r
+  <td class="tabledata">Either check the settings used for the output module or see the administrator operating the Xestia Scanner Server Installation as the administrator may need to set file permissions or configure the system.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">When trying to export an image, an error occurs.</td>\r
+  <td class="tabledata">The export module was configured incorrectly.</td>\r
+  <td class="tabledata">Either check the settings used for the export module or see the administrator operating the Xestia Scanner Server Installation as the administrator may need to set file permissions or configure the system.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">An error message appears when trying to login despite entering the correct username and password.</td>\r
+  <td class="tabledata">The user account has been disabled or the password has been changed by the administrator.</td>\r
+  <td class="tabledata">Check with the administrator operating the Xestia Scanner Server installation.</td>\r
+ </tr>\r
+ <tr>\r
+  <td class="tabledata">I get logged out whilst using the Xestia Scanner Server.</td>\r
+  <td class="tabledata">Your session has expired or the administrator has used the ‘Logout All Users’ feature.</td>\r
+  <td class="tabledata">Login again.</td>\r
+ </tr>\r
+</table>\r
+\r
+<div class="footnote">\r
+<sup>1</sup> The CPAN (Comprehensive Perl Archive Network) command interface is normally included with Perl installations and will normally require superuser (root) permissions.\r
+</div>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-chapter5.html b/Documentation/English (British)/user-chapter5.html
new file mode 100644 (file)
index 0000000..56b5b19
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Chapter 5: Contributing to Xestia Scanner Server</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Chapter 5: Contributing to Xestia Scanner Server</span>\r
+<br><br>\r
+<b>5.1: Contributing</b>\r
+<br><br>\r
+You can contribute to Xestia Scanner Server in many different ways like the following examples:\r
+<br><br>\r
+<ul>\r
+<li>Translate Xestia Scanner Server (program or documentation) so that it can be used in your own local language.</li>\r
+<li>Add functionality to Xestia Scanner Server.</li>\r
+<li>Write a presentation, authentication, output format or export format module.</li>\r
+<li>Report a bug or fault (either with Xestia Scanner Server itself or the documentation).</li>\r
+<li>When reporting a bug, you should give the version number of Kiriwrite, what operating system you are using, what web server you are using and the version of it, the version of Perl you are using (and if possible the version of the Perl module that is causing the bug), what the error message of the bug is and how to recreate the bug (if possible).</li>\r
+</ul>\r
+<br><br>\r
+For more information on how to contribute to Xestia Scanner Server visit <a href="http://xestia.co.uk/scannerserver">http://xestia.co.uk/scannerserver</a> or visit the BerliOS project site at <a href="http://developer.berlios.de/projects/xestiascansrv">http://developer.berlios.de/projects/xestiascansrv</a>. A list of stuff that needs doing can be found in the TODO file in the Xestia Scanner Server package (remember to check the latest Xestia Scanner Server package's TODO file for the latest on what needs doing).\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-introduction.html b/Documentation/English (British)/user-introduction.html
new file mode 100644 (file)
index 0000000..eba1925
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation - Introduction</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Introduction</span><br><br>Xestia Scanner Server is software which allows you to use your scanner over a network so that it can be shared with several users or several PCs using a web browser based interface which the image is then outputted and then exported. Instead of one scanner per user which may well be hardly ever used, having one scanner per group would save money as fewer scanners would be used and save time (plus stress) in maintenance due to few scanner needing to be looked after.<br><br>\r
+There is a modular system available for outputting the scanner image into several formats and also several options for exporting the image (To download via the web browser and send the image through email). This can be easily extended to support newer (and older) image formats or different exporting methods as needed.<br><br>\r
+For using with a group of users, you can manage what the scanners, output modules and export modules the user can or cannot use.<br><br>\r
+The documentation is split into three parts, the user documentation (which is this part), the developer documentation (for writing new modules or language files) and the tutorial documentation (the basics and how to use Xestia Scanner Server).<br><br>\r
+Xestia Scanner Server uses the SANE (Scanner Access Made Easy) software which allows the scanner server to be used as many operating systems as possible which can run SANE.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user-preface.html b/Documentation/English (British)/user-preface.html
new file mode 100644 (file)
index 0000000..29e1023
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - Preface</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">Preface</span>\r
+<br><br>\r
+To deal with the fact that where I live I have several PCs available to work from, I decided to build a miniature server which would help me manage my files, calendar and (eventually) my contacts.\r
+<br><br>\r
+I also decided that I want to print from any PC at home regardless if my main PC is turned on or not which meant attaching the printer to my miniature server.<br><br>As my printer is an all-in-one printer, I couldn't easily access the scanner part of the printer through the network and each operating system had it's own way of accessing scanners. The simple answer was to write some scanner server software which can be managed through a web browser which resulted in Xestia Scanner Server.\r
+<br><br>\r
+To save time for myself, I had forked Kiriwrite so that the advantages which Kiriwrite had would be the same for Xestia Scanner Server such as the UTF-8 support, modular system and multiple language support.\r
+<br><br>\r
+In memory of my Dad who sadly passed away several weeks before the first version of Xestia Scanner Server was completed.\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/Documentation/English (British)/user.html b/Documentation/English (British)/user.html
new file mode 100644 (file)
index 0000000..e1e80a7
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">\r
+<html>\r
+       <head>\r
+               <link href="style.css" REL="stylesheet" TYPE="text/css" MEDIA="screen">\r
+               <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">\r
+               <title>Xestia Scanner Server Documentation - User Documentation</title>\r
+       </head>\r
+       <body>\r
+               <div class="menubarback">\r
+                       <div class="menubar">\r
+                               <span class="apptitle">Xestia Scanner Server</span>\r
+                               <a href="index.html">Index</a> | <a href="user.html">User \r
+Documentation</a> | <a href="tutorial.html">Tutorial Documentation</a> | \r
+<a href="developer.html">Developer Documentation</a>\r
+                       </div>\r
+               </div>\r
+               <div class="pageinformation">\r
+                       <span class="pagetitle">User Documentation</span><br>\r
+The User Documentation contains information on how to install Xestia Scanner Server, operate Xestia Scanner Server, solutions to common problems that occur while using Xestia Scanner Server.\r
+\r
+<br><br>\r
+<span class="heading">Contents</span><br>\r
+<br><br>\r
+<a href="user-preface.html">Preface</a><br>\r
+<a href="user-introduction.html">Introduction</a><br>\r
+<a href="user-chapter1.html">Chapter 1: Installation</a><br>\r
+&nbsp;<a href="user-chapter1-obtaining.html">1.1 Obtaining Xestia Scanner Server</a><br>\r
+&nbsp;<a href="user-chapter1-install.html">1.2 Installing Xestia Scanner Server</a><br>\r
+&nbsp;<a href="user-chapter1-installscript.html">1.3 Installer Script</a><br>\r
+&nbsp;<a href="user-chapter1-multiuserinstallscript.html">1.4 Multiuser Installer Script</a><br>\r
+<a href="user-chapter2.html">Chapter 2: Operation</a><br>\r
+&nbsp;<a href="user-chapter2-scanning.html">2.1 Scanning</a><br>\r
+&nbsp;<a href="user-chapter2-users.html">2.2 User Management</a><br>\r
+<a href="user-chapter3.html">Chapter 3: Xestia Scanner Server Settings</a><br>\r
+&nbsp;<a href="user-chapter3-edit.html">3.1 Editing the settings</a><br>\r
+<a href="user-chapter4.html">Chapter 4: Troubleshooting</a><br>\r
+<a href="user-chapter5.html">Chapter 5: Contributing to Xestia Scanner Server</a><br>\r
+               </div>\r
+       </body>\r
+</html>\r
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..4245e94
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,2 @@
+For information on installing Xestia Scanner Server, see Chapter 1: Installation 
+in the User Documentation in the Documentation directory. 
\ No newline at end of file
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..6f9e296
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,22 @@
+Xestia Scanner Server uses a regular expression for checking if UTF8 data 
+that is passed to it is valid is from the World Wide Web Consortium (W3C) 
+website. ( http://www.w3.org )
+
+The W3C Software License (the 31st December 2002 version) 
+is compatable with the GNU General Public License which Kiriwrite is 
+licensed under.
+
+----------------------------------------------------------------------
+
+UTF8 validation check regular expression: 
+http://www.w3.org/International/questions/qa-forms-utf-8
+
+Copyright ©2003 World Wide Web Consortium, 
+(Massachusetts Institute of Technology, European Research Consortium for 
+Informatics and Mathematics, Keio University). All Rights Reserved. This 
+work is distributed under the W3C® Software License [1] in thehope 
+that it will be useful, but WITHOUT ANY WARRANTY; without even the 
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+
+[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..8651e9a
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+Xestia Scanner Server is a web-based (browser-based) interface for using your
+scanner over a network. It uses SANE (Scanner Access Now Easy) to processed
+scanned images and documents.
+
+For information on how to install, usage and hints on using Xestia Scanner 
+Server read the Documentation that is in the Documentation directory.
+
+Xestia Scanner Server is licensed under the GPL (version 3). For more 
+information please read the COPYING file that is included with the archive.
\ No newline at end of file
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..830adf6
--- /dev/null
+++ b/TODO
@@ -0,0 +1,9 @@
+TODO
+====
+
+Changes for future releases
+===========================
+
+- Allow multiple documents to be scanned in a session.
+- Add more export and output modules.
+
diff --git a/cgi-files/Modules/Auth/PostgreSQL.pm b/cgi-files/Modules/Auth/PostgreSQL.pm
new file mode 100644 (file)
index 0000000..393ee54
--- /dev/null
@@ -0,0 +1,1851 @@
+#################################################################################
+# Xestia Scanner Server Database Module - PostgreSQL Database Module           #
+# Database module for mainipulating data in a PostgreSQL database.             #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is the GPL version 3.                                                                #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# Define the package (perl module) name.
+
+package Modules::Auth::PostgreSQL;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+use Encode;
+use Digest;
+use utf8;
+
+# Load the following Perl modules.
+
+use DBI qw(:sql_types);
+
+# Set the following values.
+
+our $VERSION   = "0.1.0";
+my ($options, %options);
+my $database_handle;
+my $statement_handle;
+my $error;
+my $errorext;
+my $database_filename;
+my $second_database_filename;
+
+#################################################################################
+# Generic Subroutines.                                                         #
+#################################################################################
+
+sub new{
+#################################################################################
+# new: Create an instance of the PostgreSQL module.                            #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule = PostgreSQL->new();                                               #
+#################################################################################
+       
+       # Get the perl module name.
+
+       my $class = shift;
+       my $self = {};
+
+       return bless($self, $class);
+
+}
+
+sub capabilities{
+#################################################################################
+# capabilities: Get the capabilities for this module as a hash.                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->capabilities();                                                   #
+#################################################################################
+       
+       my $class = shift;
+       
+       my %capabilities = (
+               "multiuser"     => 1,
+       );
+       
+       return %capabilities; 
+       
+}
+
+sub loadsettings{
+#################################################################################
+# loadsettings: Loads settings into the PostgreSQL authentication module       #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->loadsettings(options);                                            #
+#                                                                              #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# DateTime     Specifies the date and time format to use.                      #
+# Server       Specifies the server to use.                                    #
+# Database     Specifies the database to use.                                  #
+# Username     Specifies the username to use.                                  #
+# Password     Specifies the password to use.                                  #
+# Port         Specifies the server port to use.                               #
+# Protocol     Specifies the protocol to use.                                  #
+# TablePrefix  Specifies the table prefix to use.                              #
+#################################################################################
+
+       # Get the data passed to the subroutine.
+
+       my $class = shift;
+       my ($passedoptions)     = @_;
+
+       # Add the directory setting to the list of options (as it's the only
+       # one needed for this database module).
+
+       %options = (
+               "Directory"     => $passedoptions->{"Directory"},
+               "DateTime"      => $passedoptions->{"DateTime"},
+               "Server"        => $passedoptions->{"Server"},
+               "Database"      => $passedoptions->{"Database"},
+               "Username"      => $passedoptions->{"Username"},
+               "Password"      => $passedoptions->{"Password"},
+               "Port"          => $passedoptions->{"Port"},
+               "Protocol"      => $passedoptions->{"Protocol"},
+               "TablePrefix"   => $passedoptions->{"TablePrefix"}
+       );
+
+}
+
+sub convert{
+#################################################################################
+# convert: Converts data into SQL formatted data.                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->convert(data);                                                    #
+#                                                                              #
+# data         Specifies the data to convert.                                  #
+#################################################################################
+
+       # Get the data passed to the subroutine.
+
+       my $class       = shift;
+       my $data        = shift;
+
+       if (!$data){
+               $data = "";
+       }
+
+       $data =~ s/\'/''/g;
+       $data =~ s/\b//g;
+
+       return $data;
+
+}
+
+sub dateconvert{
+#################################################################################
+# dateconvert: Converts a SQL date into a proper date.                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->dateconvert(date);                                                        #
+#                                                                              #
+# date         Specifies the date to convert.                                  #
+#################################################################################
+
+       # Get the date passed to the subroutine.
+
+       my $class       = shift;
+       my $data        = shift;
+
+       # Convert the date given into the proper date.
+
+       # Create the following varialbes to be used later.
+
+       my $date;
+       my $time;
+       my $day;
+       my $day_full;
+       my $month;
+       my $month_check;
+       my $month_full;
+       my $year;
+       my $year_short;
+       my $hour;
+       my $hour_full;
+       my $minute;
+       my $minute_full;
+       my $second;
+       my $second_full;
+       my $seek = 0;
+       my $timelength;
+       my $datelength;
+       my $daylength;
+       my $secondlength;
+       my $startchar = 0;
+       my $char;
+       my $length;
+       my $count = 0;
+
+       # Split the date and time.
+
+       $length = length($data);
+
+       if ($length > 0){
+
+               do {
+
+                       # Get the character and check if it is a space.
+
+                       $char = substr($data, $seek, 1);
+
+                       if ($char eq ' '){
+
+                               # The character is a space, so get the date and time.
+
+                               $date           = substr($data, 0, $seek);
+                               $timelength     = $length - $seek - 1;
+                               $time           = substr($data, $seek + 1, $timelength);
+
+                       }
+
+                       $seek++;
+
+               } until ($seek eq $length);
+
+               # Get the year, month and date.
+
+               $length = length($date);
+               $seek = 0;
+
+               do {
+
+                       # Get the character and check if it is a dash.
+
+                       $char = substr($date, $seek, 1);
+
+                       if ($char eq '-'){
+
+                               # The character is a dash, so get the year, month or day.
+
+                               $datelength = $seek - $startchar;
+
+                               if ($count eq 0){
+
+                                       # Get the year from the date.
+
+                                       $year           = substr($date, 0, $datelength) + 1900;
+                                       $startchar      = $seek;
+                                       $count = 1;
+
+                                       # Get the last two characters to get the short year
+                                       # version.
+
+                                       $year_short     = substr($year, 2, 2);
+
+                               } elsif ($count eq 1){
+
+                                       # Get the month and day from the date.
+
+                                       $month  = substr($date, $startchar + 1, $datelength - 1) + 1;
+
+                                       # Check if the month is less then 10, if it is
+                                       # add a zero to the value.
+
+                                       if ($month < 10){
+
+                                               $month_full = '0' . $month;
+
+                                       } else {
+
+                                               $month_full = $month;
+
+                                       }
+
+                                       $startchar      = $seek;
+                                       $count = 2;
+
+                                       $daylength      = $length - $seek + 1;
+                                       $day            = substr($date, $startchar + 1, $daylength);
+
+                                       $day =~ s/^0//;
+
+                                       # Check if the day is less than 10, if it is
+                                       # add a zero to the value.
+
+                                       if ($day < 10){
+
+                                               $day_full       = '0' . $day;
+
+                                       } else {
+
+                                               $day_full       = $day;
+
+                                       }
+
+                               }
+
+                       }
+
+                       $seek++;
+
+               } until ($seek eq $length);
+
+               # Get the length of the time value and reset certain
+               # values to 0.
+
+               $length = length($time);
+               $seek = 0;
+               $count = 0;
+               $startchar = 0;
+
+               do {
+
+                       # Get the character and check if it is a colon.
+
+                       $char = substr($time, $seek, 1);
+
+                       if ($char eq ':'){
+
+                               # The character is a colon, so get the hour, minute and day.
+
+                               $timelength = $seek - $startchar;
+
+                               if ($count eq 0){
+
+                                       # Get the hour from the time.
+
+                                       $hour = substr($time, 0, $timelength);
+                                       $hour =~ s/^0//;
+                                       $count = 1;
+                                       $startchar = $seek;
+
+                                       # If the hour is less than ten then add a
+                                       # zero.
+
+                                       if ($hour < 10){
+
+                                               $hour_full = '0' . $hour;
+
+                                       } else {
+
+                                               $hour_full = $hour;
+
+                                       }
+
+                               } elsif ($count eq 1){
+
+                                       # Get the minute and second from the time.
+
+                                       $minute = substr($time, $startchar + 1, $timelength - 1);
+                                       $minute =~ s/^0//;
+                                       $count = 2;
+                                               
+                                       # If the minute is less than ten then add a
+                                       # zero.
+
+                                       if ($minute < 10){
+
+                                               $minute_full = '0' . $minute;
+
+                                       } else {
+
+                                               $minute_full = $minute;
+
+                                       }
+
+                                       $startchar = $seek;
+
+                                       $secondlength = $length - $seek + 1;
+                                       $second = substr($time, $startchar + 1, $secondlength);
+                                       $second =~ s/^0//;
+                                       
+                                       # If the second is less than ten then add a
+                                       # zero.
+
+                                       if ($second < 10){
+
+                                               $second_full = '0' . $second;
+
+                                       } else {
+
+                                               $second_full = $second;
+
+                                       }
+
+                               }
+
+                       }
+
+                       $seek++;
+
+               } until ($seek eq $length);
+
+               # Get the setting for displaying the date and time.
+
+               $data = $options{"DateTime"};
+
+               # Process the setting for displaying the date and time
+               # using regular expressions
+
+               $data =~ s/DD/$day_full/g;
+               $data =~ s/D/$day/g;
+               $data =~ s/MM/$month_full/g;
+               $data =~ s/M/$month/g;
+               $data =~ s/YY/$year/g;
+               $data =~ s/Y/$year_short/g;
+
+               $data =~ s/hh/$hour_full/g;
+               $data =~ s/h/$hour/g;
+               $data =~ s/mm/$minute_full/g;
+               $data =~ s/m/$minute/g;
+               $data =~ s/ss/$second_full/g;
+               $data =~ s/s/$second/g;
+
+       }
+
+       return $data;
+
+}
+
+sub geterror{
+#################################################################################
+# geterror: Gets the error message (or extended error message).                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->geterror(extended);                                               #
+#                                                                              #
+# Extended     Specifies if the extended error should be retrieved.            #
+#################################################################################
+
+       # Get the data passed to the subroutine.
+
+       my $class       = shift;
+       my $extended    = shift;
+
+       if (!$extended){
+               $extended = 0;
+       }
+
+       if (!$errorext){
+               $errorext = "";
+       }
+
+       if (!$error){
+               $error = "";
+       }
+
+       # Check to see if extended information should be returned.
+
+       if ($extended eq 1){
+
+               # Extended information should be returned.
+
+               return $errorext;
+
+       } else {
+
+               # Basic information should be returned.
+
+               return $error;
+
+       }
+
+}
+
+#################################################################################
+# General subroutines.                                                         #
+#################################################################################
+
+sub connect{
+#################################################################################
+# connect: Connect to the server.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->connect();                                                                #
+#################################################################################
+
+       $error = "";
+       $errorext = "";
+
+       # Connect to the server.
+
+       $database_handle = DBI->connect("DBI:Pg:dbname=" . $options{"Database"} . ";host=" . $options{"Server"} . ";port=" . $options{"Port"}, $options{"Username"}, $options{"Password"}) or ( $error = "AuthConnectionError", $errorext = DBI->errstr, return );
+       $database_handle->do("SET CLIENT_ENCODING TO 'UTF8'");
+       #$database_handle->do('SET NAMES utf8');
+
+}
+
+sub disconnect{
+#################################################################################
+# connect: Disconnect from the server.                                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->disconnect();                                                     #
+#################################################################################
+       
+       # Disconnect from the server.
+
+       if ($statement_handle){
+
+               $statement_handle->finish();
+
+       }
+
+       if ($database_handle){
+
+               $database_handle->disconnect();
+
+       }
+
+}
+
+sub getuserlist{
+#################################################################################
+# getuserlist: Get the user list.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->getuserlist(options);                                             #
+#                                                                              #
+# options      Specifies the following options in any order.                   #
+#                                                                              #
+# Reduced              Gets a reduced version of the user list.                #
+# ShowDeactivated      Show users that are deactivated from the list.          #
+#################################################################################
+
+       $error = "";
+       $errorext = "";
+
+       # Get the values passed to the subroutine.
+
+       my $class = shift;
+       my ($passedoptions) = @_;
+       my $sqlquery = "";
+       my @user_data;
+       my %user_list;
+       my $user_seek = 1;
+
+       tie(%user_list, 'Tie::IxHash');
+
+       my $reduced_list        = $passedoptions->{"Reduced"};
+       my $deactivated_show    = $passedoptions->{"ShowDeactivated"};
+       $deactivated_show = 0 if !$passedoptions->{"ShowDeactivated"};
+
+       # Check if a reduced version of the user list should be retreived.
+
+       if ($reduced_list eq 1){
+
+               # Get the list of users with reduced information.
+
+               $sqlquery = 'SELECT username, name, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_users';
+
+       } else {
+
+               # Get the list of users.
+
+               $sqlquery = 'SELECT * FROM ' . $class->convert($options{"TablePrefix"}) . '_users';
+
+       }
+
+       # Check if the deactivated users should be hidden.
+
+       if ($deactivated_show eq 0){
+
+               # The deactivated users should be hidden from the list.
+
+               $sqlquery = $sqlquery . ' WHERE enabled=TRUE';
+
+       }
+       
+       $sqlquery = $sqlquery . ' ORDER BY username';
+
+       # Run the query.
+
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+
+       # Process the user list.
+
+       while (@user_data = $statement_handle->fetchrow_array()){
+
+               $user_list{$user_seek}{username}        = decode_utf8($user_data[0]);
+               $user_list{$user_seek}{name}            = decode_utf8($user_data[1]);
+
+               if ($user_data[2] eq 0){
+
+                       $user_list{$user_seek}{deactivated}     = 1;
+
+               } else {
+
+                       $user_list{$user_seek}{deactivated}     = 0;
+
+               }
+
+               $user_seek++;
+
+       }
+
+       return %user_list;
+
+}
+
+sub getpermissions{
+#################################################################################
+# getpermissions: Get the permissions for scanner or module.                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->getpermissions(options);                                          #
+#                                                                              #
+# options      Specifies the following options in any order.                   #
+#                                                                              #
+# Username             Specifies the username to get permissions for.          #
+# PermissionType       Specifies the permission type.                          #
+# PermissionName       Get a specific permission name.                         #
+#                                                                              #
+# If no permission name is specified then a list of permissions will be        #
+# returned as hash otherwise the value will be returned as a normal string.    #
+#################################################################################
+
+       $error = "";
+       $errorext = "";
+
+       # Get the value passed to the subroutine.
+
+       my $class = shift;
+       my ($passedoptions) = @_;
+       
+       my $username            = $passedoptions->{'Username'};
+       my $permissiontype      = $passedoptions->{'PermissionType'};
+       my $permissionname      = $passedoptions->{'PermissionName'};
+       my $sqlquery = "";
+       my $user_exists = 0;
+       
+       my $permissionresult = 0;
+       my @userdata;
+       my @permissiondata;
+       my $uid = 0;
+       
+       if (!$username){
+
+               # The username is blank so return an error.
+
+               $error = "UsernameBlank";
+               return;
+
+       }
+
+       if (!$permissiontype){
+       
+               # The permissions type is blank so return an error.
+               
+               $error = "PermissionTypeBlank";
+               return;
+               
+       }
+       
+       #if (!$permissionname){
+       
+               # The permissions name is blank so return a list of
+               # permissions for that type.
+               
+       #       my %user_permissions;
+               
+       #       return %user_permissions;
+               
+       #}
+       
+       # Get the user ID number.
+       
+       $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
+       
+       # Run the query.
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while(@userdata = $statement_handle->fetchrow_array()){
+               
+               $uid = $userdata[0];
+               
+       }
+       
+       if ($permissiontype eq "OutputModule"){
+               
+               if (!$permissionname){
+                       
+                       my %useroutputinfo;
+                       
+                       # No permission name was specified so get the list of
+                       # scanner permissions.
+                       
+                       $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Output\'';
+                       
+                       # Run the query.
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       # Process the list of permissions.
+                       
+                       while(@permissiondata = $statement_handle->fetchrow_array()){
+                               
+                               $useroutputinfo{$permissiondata[2]}             = $permissiondata[3];
+                               
+                       }
+                       
+                       return %useroutputinfo;
+                       
+               }
+               
+               $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Output\' AND modulename=\'' . $class->convert($permissionname) . '\'';
+
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();           
+
+               # Check to see the value of the permission.
+               
+               while(@permissiondata = $statement_handle->fetchrow_array()){
+                       
+                       if ($permissiondata[3] eq 1){
+                               
+                               $permissionresult = 1;
+                               
+                       } else {
+                               
+                               $permissionresult = 0;
+                               
+                       }
+                       
+               }
+               
+       } elsif ($permissiontype eq "ExportModule"){
+
+               if (!$permissionname){
+                       
+                       my %userexportinfo;
+                       
+                       # No permission name was specified so get the list of
+                       # scanner permissions.
+                       
+                       $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Export\'';
+                       
+                       # Run the query.
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       # Process the list of permissions.
+                       
+                       while(@permissiondata = $statement_handle->fetchrow_array()){
+                               
+                               $userexportinfo{$permissiondata[2]}             = $permissiondata[3];
+                               
+                       }
+                       
+                       return %userexportinfo;
+                       
+               }
+               
+               $sqlquery = 'SELECT uid, moduletype, modulename, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_modules WHERE uid=\'' . $class->convert($uid) . '\' AND moduletype=\'Export\' AND modulename=\'' . $class->convert($permissionname) . '\'';
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();           
+               
+               # Check to see the value of the permission.
+               
+               while(@permissiondata = $statement_handle->fetchrow_array()){
+                       
+                       if ($permissiondata[3] eq 1){
+                               
+                               $permissionresult = 1;
+                               
+                       } else {
+                               
+                               $permissionresult = 0;
+                               
+                       }
+                       
+               }
+               
+       } elsif ($permissiontype eq "Scanner"){
+
+               # The permission type is a Scanner permission.
+               
+               if (!$permissionname){
+               
+                       my %userscannerinfo;
+                       
+                       # No permission name was specified so get the list of
+                       # scanner permissions.
+                       
+                       $sqlquery = 'SELECT uid, scannerid, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_scanners WHERE uid=\'' . $class->convert($uid) . '\'';
+                       
+                       # Run the query.
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       # Process the list of permissions.
+                       
+                       while(@permissiondata = $statement_handle->fetchrow_array()){
+                               
+                               $userscannerinfo{$permissiondata[1]}            = $permissiondata[2];
+                               
+                       }
+                       
+                       return %userscannerinfo;
+                       
+               }
+               
+               # The permission type is a Scanner permission.
+               
+               $sqlquery = 'SELECT uid, scannerid, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_scanners WHERE uid=\'' . $class->convert($uid) . '\' AND scannerid=\'' . $class->convert($permissionname) . '\'';
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               # Check to see the value of the permission.
+               
+               while(@permissiondata = $statement_handle->fetchrow_array()){
+                       
+                       if ($permissiondata[2] eq 1){
+                       
+                               $permissionresult = 1;
+                               
+                       } else {
+                       
+                               $permissionresult = 0;
+                               
+                       }
+                       
+               }
+               
+       } elsif ($permissiontype eq "Admin"){
+       
+               # Check to see if the user has administrative permissions.
+               
+               $sqlquery = 'SELECT uid, admin FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE uid=\'' . $class->convert($uid) . '\' AND admin=TRUE AND enabled=TRUE';
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               # Check to see the value of the admin permission.
+
+               while(@permissiondata = $statement_handle->fetchrow_array()){
+                       
+                       if ($permissiondata[1] eq 1){
+                               
+                               $permissionresult = 1;
+                               
+                       } else {
+                               
+                               $permissionresult = 0;
+                               
+                       }
+                       
+               }
+               
+       } elsif ($permissiontype eq "UserInfo"){
+       
+               my %userinfo;
+               
+               # Get the details of the user.
+               
+               $sqlquery = 'SELECT uid, username, name, admin, enabled FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE uid=\'' . $class->convert($uid) . '\'';
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               while(@permissiondata = $statement_handle->fetchrow_array()){
+               
+                       $userinfo{UID}          = $permissiondata[0];
+                       $userinfo{Username}     = decode_utf8($permissiondata[1]);
+                       $userinfo{Name}         = decode_utf8($permissiondata[2]);
+                       $userinfo{Admin}        = $permissiondata[3];
+                       $userinfo{Enabled}      = $permissiondata[4];
+                       
+               }
+               
+               return %userinfo;
+               
+       }
+       
+       return $permissionresult;
+       
+}
+
+sub adduser{
+#################################################################################
+# adduser: Add a user to the user list with specific permissions.              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->adduser(username, userinfo);                                      #
+#                                                                              #
+# username             Specifies the username.                                 #
+# userinfo             Specifies the user information hash.                    #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       my $class       = shift;
+       
+       my $username    = shift;
+       my %userinfo    = @_;
+       
+       if (!$username){
+               
+               # The username is blank so return an error.
+               
+               $error = "UsernameBlank";
+               return;
+               
+       }
+       
+       # Check if the username exists.
+       
+       my $sqlquery = "";
+       my @user_data;
+       my $user_exists = 0;
+       $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . $class->convert($username) . "'";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while (@user_data = $statement_handle->fetchrow_array()){
+               
+               $user_exists = 1;
+               
+       }
+       
+       if ($user_exists eq 1){
+               
+               $error = "UserExists";
+               return;
+               
+       }
+       
+       $sqlquery = "";
+       
+       my $adminpriv   = "FALSE";
+       my $enabledpriv = "FALSE";
+       
+       if (!$userinfo{"Enabled"}){
+               
+               $userinfo{"Enabled"} = "off";
+               
+       }
+       
+       if (!$userinfo{"Admin"}){
+               
+               $userinfo{"Admin"} = "off";
+               
+       }
+       
+       $adminpriv = "TRUE" if $userinfo{Admin} eq "on";
+       $enabledpriv = "TRUE" if $userinfo{Enabled} eq "on";
+       
+       # Generate a random salt for the password and combine it
+       # with the password.
+       
+       my $digest = Digest->new("SHA-512");
+       
+       my $salt = uc(sprintf("%x",int(rand(50000000))));
+       
+       $digest->add(decode_utf8($userinfo{Password}));
+       $digest->add($salt);
+       
+       $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_users (username, password, salt, version, name, admin, enabled) VALUES(";
+       $sqlquery = $sqlquery . "'" . $class->convert(decode_utf8($userinfo{Username})) . "',";
+       $sqlquery = $sqlquery . "'" . $digest->hexdigest . "',";
+       $sqlquery = $sqlquery . "'" . $salt . "',";
+       $sqlquery = $sqlquery . "1,";
+       $sqlquery = $sqlquery . "'" . $class->convert(decode_utf8($userinfo{Name})) . "',";
+       $sqlquery = $sqlquery . $adminpriv . ",";
+       $sqlquery = $sqlquery . $enabledpriv;
+       $sqlquery = $sqlquery . ")";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       return;
+       
+}
+
+sub edituser{
+#################################################################################
+# edituser: Edit a user on the user list.                                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->edituser(username, type, data);                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# username             Specifies the username to edit.                         #
+# type                 Specifies the type of data to edit.                     #
+# data                 Specifies the data to use (as a hash).                  #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       my $class = shift;
+       
+       my $username            = shift;
+       my $type                = shift;        
+       my (%data)              = @_;
+       
+       #(%permissions)         = @_;
+       #my %permissions_final;
+       #my $user_exists = 0;
+       
+       #if (!$username){
+       
+       # The username is blank so return an error.
+       
+       #       $error = "UsernameBlank";
+       #       return;
+       
+       #}
+       
+       #$username = $data{OriginalUsername};
+       
+       if (!$username){
+               
+               # The username is blank so return an error.
+               
+               $error = "UsernameBlank";
+               return;
+               
+       }
+       
+       if (!$type){
+               
+               # The type is blank so return an error.
+               
+               $error = "TypeBlank";
+               return;
+               
+       }
+       
+       # Check if the username exists.
+       
+       my $sqlquery = "";
+       my @user_data;
+       my $user_exists = 0;
+       
+       $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . decode_utf8($username) . "'";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while (@user_data = $statement_handle->fetchrow_array()){
+               
+               $user_exists = 1;
+               
+       }
+       
+       if ($user_exists ne 1){
+               
+               $error = "UserDoesNotExist";
+               return;
+               
+       }
+       
+       # Check what type of data is being updated.
+       
+       # Get the user ID (UID) number.
+       
+       my $uid = 0;
+       $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
+       @user_data = [];
+       
+       # Run the query.
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while(@user_data = $statement_handle->fetchrow_array()){
+               
+               $uid = $user_data[0];
+               
+       }
+       
+       if ($type eq "User"){
+               
+               # Update the user information.
+               
+               $sqlquery = "UPDATE " . $class->convert($options{"TablePrefix"}) . "_users SET";
+               
+               if (!$data{"Enabled"}){
+                       
+                       $data{"Enabled"} = "off";
+                       
+               }
+               
+               if (!$data{"Admin"}){
+                       
+                       $data{"Admin"} = "off";
+                       
+               }
+               
+               # Check if the account is enabled or not.
+               
+               if ($data{Enabled} eq "on"){
+                       
+                       $sqlquery = $sqlquery . " enabled = TRUE";
+                       
+               } else {
+                       
+                       $sqlquery = $sqlquery . " enabled = FALSE";
+                       
+               }
+               
+               # Check if the account has administrative status or not.
+               
+               if ($data{Admin} eq "on"){
+                       
+                       $sqlquery = $sqlquery . ", admin = TRUE";
+                       
+               } else {
+                       
+                       $sqlquery = $sqlquery . ", admin = FALSE";
+                       
+               }
+               
+               # Add the name to query.
+               
+               $sqlquery = $sqlquery . ", name = '" . $class->convert(decode_utf8($data{Name})) . "'";
+               
+               # Check if the user with the new username already exists.
+               
+               $user_exists = 0;
+               
+               if (decode_utf8($username) ne decode_utf8($data{NewUsername})){
+                       
+                       my $sqlqueryusername = "";
+                       @user_data = [];
+                       $sqlqueryusername = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username='" . $class->convert(decode_utf8($data{NewUsername})) . "'";
+                       
+                       $statement_handle = $database_handle->prepare($sqlqueryusername) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       while (@user_data = $statement_handle->fetchrow_array()){
+                               
+                               $user_exists = 1;
+                               
+                       }
+                       
+                       if ($user_exists eq 1){
+                               
+                               $error = "NewUsernameAlreadyExists";
+                               return;
+                               
+                       }
+                       
+                       $sqlquery = $sqlquery . ", username = \'" . $class->convert(decode_utf8($data{NewUsername})) . "\'";
+                       
+               }
+               
+               # Check if the password needs to be changed.
+               
+               if ($data{Password} ne ""){
+                       
+                       if ($data{Password} eq $data{ConfirmPassword}){
+                               
+                               # Generate a random salt for the password and combine it
+                               # with the password.
+                               
+                               my $digest = Digest->new("SHA-512");
+                               
+                               my $salt = uc(sprintf("%x\n",int(rand(50000000))));
+                               
+                               $digest->add(decode_utf8($data{Password}));
+                               $digest->add($salt);
+                               
+                               $sqlquery = $sqlquery . ", password = \'" . $class->convert($digest->hexdigest) . "\'";
+                               $sqlquery = $sqlquery . ", salt = \'" . $class->convert($salt) . "\'";
+                               $sqlquery = $sqlquery . ", version = 1";
+                               
+                       }
+                       
+               }
+               
+               # Add the user id on the end.
+               
+               $sqlquery = $sqlquery . " WHERE uid = '" . $class->convert($uid) . "'";
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+       } elsif ($type eq "Scanner"){
+               
+               # Drop all scanner information for this user.
+               
+               $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_scanners WHERE uid =\'" . $class->convert($uid)  . "\'";
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();           
+               
+               return if (!%data);
+               
+               # Insert the new scanner information for this user.
+               
+               $sqlquery = "";
+               
+               $sqlquery = "INSERT INTO xestiascan_scanners (uid, scannerid, enabled) VALUES";
+               
+               # Process the hash passed to the subroutine.
+               
+               my $firstline = 1;
+               my $datakeyname;
+               
+               foreach $datakeyname (keys %data){
+                       
+                       if ($firstline eq 1){
+                               
+                               $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",\'" . $class->convert($datakeyname) . "\',";
+                               $firstline = 0;
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",\'" . $class->convert($datakeyname) . "\',";
+                               
+                       }
+                       
+                       if ($data{$datakeyname} eq "on"){
+                               
+                               $sqlquery = $sqlquery . "TRUE)";
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . "FALSE)";                               
+                               
+                       }
+                       
+               }
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+       } elsif ($type eq "OutputModule"){
+               
+               # Drop all output module information for this user.
+               
+               $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules WHERE uid ='" . $class->convert($uid)  . "' AND moduletype ='Output'";
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               return if (!%data);             
+               
+               # Insert the new output module information for this user.
+               
+               $sqlquery = "";
+               
+               $sqlquery = "INSERT INTO xestiascan_modules (uid, moduletype, modulename, enabled) VALUES";
+               
+               # Process the hash passed to the subroutine.
+               
+               my $firstline = 1;
+               my $datakeyname;
+               
+               foreach $datakeyname (keys %data){
+                       
+                       if ($firstline eq 1){
+                               
+                               $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",'Output','" . $class->convert($datakeyname) . "',";
+                               $firstline = 0;
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",'Output','" . $class->convert($datakeyname) . "',";
+                               
+                       }
+                       
+                       if ($data{$datakeyname} eq "on"){
+                               
+                               $sqlquery = $sqlquery . "TRUE)";
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . "FALSE)";                               
+                               
+                       }
+                       
+               }
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+       } elsif ($type eq "ExportModule"){
+               
+               # Drop all export module information for this user.
+               
+               $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules WHERE uid ='" . $class->convert($uid)  . "' AND moduletype ='Export'";
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               return if (!%data);
+               
+               # Insert the new export module information for this user.
+               
+               $sqlquery = "";
+               
+               $sqlquery = "INSERT INTO xestiascan_modules (uid, moduletype, modulename, enabled) VALUES";
+               
+               # Process the hash passed to the subroutine.
+               
+               my $firstline = 1;
+               my $datakeyname;
+               
+               foreach $datakeyname (keys %data){
+                       
+                       if ($firstline eq 1){
+                               
+                               $sqlquery = $sqlquery . "(" . $class->convert($uid) . ",\'Export',\'" . $class->convert($datakeyname) . "\',";
+                               $firstline = 0;
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . ",(" . $class->convert($uid) . ",\'Export\',\'" . $class->convert($datakeyname) . "\',";
+                               
+                       }
+                       
+                       if ($data{$datakeyname} eq "on"){
+                               
+                               $sqlquery = $sqlquery . "TRUE)";
+                               
+                       } else {
+                               
+                               $sqlquery = $sqlquery . "FALSE)";                               
+                               
+                       }
+                       
+               }
+               
+               # Run the query.
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or die; #( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+       }
+       
+}
+
+sub deleteuser{
+#################################################################################
+# deleteuser: Delete a user from the user list.                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->deleteuser(username);                                             #
+#                                                                              #
+# username     Specifies the username to delete from the user list.            #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       my $class = shift;
+       
+       my $username = shift;
+       
+       if (!$username){
+               
+               # User name is blank so return an error.
+               
+               $error = "UsernameBlank";
+               return;
+               
+       }
+       
+       # Check if the user exists before deleting.
+       
+       my $user_exists = 0;
+       my @user_data;
+       
+       my $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+
+       while (@user_data = $statement_handle->fetchrow_array()){
+       
+               $user_exists = 1;
+               
+       }
+       
+       if ($user_exists eq 0){
+       
+               $error = "UserDoesNotExist";
+               return;
+               
+       }
+
+       # Get the user ID (UID) number.
+       
+       my $uid = 0;
+       $sqlquery = 'SELECT uid, username FROM ' . $class->convert($options{"TablePrefix"}) . '_users WHERE username=\'' . $class->convert(decode_utf8($username)) . '\'';
+       @user_data = [];
+       
+       # Run the query.
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while(@user_data = $statement_handle->fetchrow_array()){
+               
+               $uid = $user_data[0];
+               
+       }
+       
+       # Delete the module permissions from the modules table.
+
+       $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_scanners where uid=\'" . $class->convert($uid) . "\'";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       # Delete the scanner permissions from the scanners table.
+       
+       $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_modules where uid=\'" . $class->convert($uid) . "\'";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       # Delete the user from the users table.
+       
+       $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"}) . "_users where username=\'" . $class->convert(decode_utf8($username)) . "\'";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+}
+
+sub userauth{
+#################################################################################
+# authuser: Authenticate a user.                                               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->authuser(type, user, password, keeploggedin);                     #
+#                                                                              #
+# type         Specifies the type of authentication.                           #
+# user         Specifies the name of the user.                                 #
+# password     Specifies the password or authentication token.                 #
+# keeploggedin Specifies if the user should stay logged in for one year.       #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       my $class = shift;
+       
+       my $type = shift;
+       my $username = shift;
+       my $password = shift;
+       my $keeploggedin = shift;
+
+       my $user_exists = 0;
+       my @user_data;
+
+       # Check to see if the user exists before authenticating.
+       
+       #my $sqlquery = "";
+       my $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+       while (@user_data = $statement_handle->fetchrow_array()){
+               
+               $user_exists = 1;
+               
+       }
+       
+       if ($user_exists eq 0){
+               
+               $error = "UserDoesNotExist";
+               return 0;
+               
+       }
+       
+       # Authenticate the user.
+       
+       my @auth_data;
+       my $valid_login = 0;
+       
+       if ($type eq "seed"){
+               
+               $sqlquery = "SELECT * FROM " . $class->convert($options{"TablePrefix"}) . "_sessions WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' AND seed=\'" . $class->convert($password) . "\' AND expires > now() LIMIT 1";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               while (@auth_data = $statement_handle->fetchrow_array()){
+                       
+                       $valid_login = 1;
+                       
+               }
+               
+               return $valid_login;
+               
+       } elsif ($type eq "password") {
+               
+               $sqlquery = "SELECT username, salt, enabled FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' LIMIT 1";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               my $digest = Digest->new("SHA-512");
+               my $salt = "";
+               my $hash = "";
+               
+               while (@auth_data = $statement_handle->fetchrow_array()){
+                       
+                       $valid_login = 1;
+                       
+                       # Check if the user account has been disabled.
+                       
+                       if ($auth_data[2] eq 0){
+                               
+                               # Account has been disabled so login is invalid.
+                               
+                               $valid_login = 0;
+                               
+                       } else {
+                               
+                               # Generate the passsword hash using the password and salt given.
+                               
+                               $salt = $auth_data[1];
+                               $digest->add(decode_utf8($password));
+                               $digest->add($salt);
+                               
+                       }
+                       
+               }
+               
+               return if $valid_login eq 0;
+               
+               $sqlquery = "SELECT username, password, enabled FROM " . $class->convert($options{"TablePrefix"}) . "_users WHERE username=\'" . $class->convert(decode_utf8($username)) . "\' AND password =\'" . $class->convert($digest->hexdigest) . "\' LIMIT 1";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               $valid_login = 0;
+               
+               while (@auth_data = $statement_handle->fetchrow_array()){
+                       
+                       $valid_login = 1;
+                       
+                       # Check if the user account has been disabled.
+                       
+                       if ($auth_data[2] eq 0){
+                               
+                               # Account has been disabled so login is invalid.
+                               
+                               $valid_login = 0;
+                               
+                       }
+                       
+               }
+               
+               if ($valid_login eq 1){
+                       
+                       my $auth_seed_unique = "yes";
+                       my $new_auth_seed;
+                       my @auth_seed_data;
+                       
+                       # Check if the auth seed already exists and generate
+                       # a new random number if it does exist.
+                       
+                       do {
+                               
+                               $auth_seed_unique = "yes";
+                               $new_auth_seed = int(rand(192000000));
+                               
+                               $sqlquery = "SELECT * FROM  " . $class->convert($options{"TablePrefix"}) . "_sessions WHERE seed=\'" . $class->convert($new_auth_seed) . "\' LIMIT 1";
+                               
+                               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                               $statement_handle->execute();                           
+                               
+                               while (@auth_seed_data = $statement_handle->fetchrow_array()){
+                                       
+                                       $auth_seed_unique = "no";
+                                       
+                               }
+                               
+                       } until ($auth_seed_unique eq "yes");
+                       
+                       # Insert this into the sessions database. 
+                       
+                       if ($keeploggedin eq 1){
+                               
+                               $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_sessions (username, seed, expires) VALUES( '" . $class->convert(decode_utf8($username)) . "', '" . $class->convert($new_auth_seed) . "', 'now'::timestamp + '1 year'::interval);";
+                               
+                       } else {
+                               
+                               $sqlquery = "INSERT INTO " . $class->convert($options{"TablePrefix"}) . "_sessions (username, seed, expires) VALUES( '" . $class->convert(decode_utf8($username)) . "', '" . $class->convert($new_auth_seed) . "', 'now'::timestamp + '3 hours'::interval);";                           
+                               
+                       }
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       return ($valid_login, $new_auth_seed);
+                       
+               }
+               
+               # Return the result.
+               
+               return $valid_login;
+               
+       }
+               
+}
+
+sub flushusers{
+#################################################################################
+# flushusers: Flush all users from the sessions table.                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule->flushusers();                                                     #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       # Flush all users from the sessions table. (This includes the user who
+       # called the action to flush the table).
+       
+       my $class = shift;
+       
+       my $sqlquery = "DELETE FROM " . $class->convert($options{"TablePrefix"})  . "_sessions";
+       
+       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+       $statement_handle->execute();
+       
+}
+
+sub populatetables{
+#################################################################################
+# populatetables: Populate the database with tables.                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# type         Specifies the type of table to populate.                        #
+# forcerecreate        Force recreates the table (delete and create).                  #
+#################################################################################
+       
+       $error = "";
+       $errorext = "";
+       
+       my $class = shift;
+       
+       my $type = shift;
+       my $forcerecreate = shift;
+       
+       my $sqlquery = "";
+       
+       if ($type eq "modules"){
+               
+               if ($forcerecreate eq 1){
+               
+                       $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"})  . "_modules";
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       if ($DBI::err){
+                               
+                               $error = "DatabaseError";
+                               $errorext = $DBI::errstr;
+                               return;
+                               
+                       }
+                       
+               }
+               
+               $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"})  . "_modules (
+               uid bigint NOT NULL,
+               moduletype varchar(12) NOT NULL,
+               modulename varchar(256) NOT NULL,
+               enabled boolean NOT NULL
+               )";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();           
+               
+               if ($DBI::err){
+               
+                       $error = "DatabaseError";
+                       $errorext = $DBI::errstr;
+                       return;
+                       
+               }
+               
+       } elsif ($type eq "scanners"){
+               
+               if ($forcerecreate eq 1){
+                       
+                       $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"})  . "_scanners";
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       if ($DBI::err){
+                               
+                               $error = "DatabaseError";
+                               $errorext = $DBI::errstr;
+                               return;
+                               
+                       }
+               
+               }
+               
+               $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"})  . "_scanners (
+               uid bigint NOT NULL,
+               scannerid varchar(256) NOT NULL,
+               enabled boolean NOT NULL
+               )";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+               
+               if ($DBI::err){
+                       
+                       $error = "DatabaseError";
+                       $errorext = $DBI::errstr;
+                       return;
+                       
+               }
+               
+       } elsif ($type eq "sessions"){
+               
+               if ($forcerecreate eq 1){
+                       
+                       $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"})  . "_sessions";
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       if ($DBI::err){
+                               
+                               $error = "DatabaseError";
+                               $errorext = $DBI::errstr;
+                               return;
+                               
+                       }
+                       
+               }
+               
+               $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"})  . "_sessions (
+               seed varchar(32) UNIQUE PRIMARY KEY NOT NULL,
+               username text NOT NULL,
+               expires timestamp NOT NULL
+               )";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();   
+
+               if ($DBI::err){
+                       
+                       $error = "DatabaseError";
+                       $errorext = $DBI::errstr;
+                       return;
+                       
+               }
+               
+       } elsif ($type eq "users"){
+       
+               if ($forcerecreate eq 1){
+                       
+                       $sqlquery = "DROP TABLE " . $class->convert($options{"TablePrefix"})  . "_users";
+                       
+                       $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+                       $statement_handle->execute();
+                       
+                       if ($DBI::err){
+                               
+                               $error = "DatabaseError";
+                               $errorext = $DBI::errstr;
+                               return;
+                               
+                       }
+                       
+               }
+               
+               $sqlquery = "CREATE TABLE " . $class->convert($options{"TablePrefix"})  . "_users (
+               uid SERIAL PRIMARY KEY,
+               username varchar(64) UNIQUE NOT NULL,
+               password text NOT NULL,
+               salt varchar(512) NOT NULL,
+               version integer NOT NULL,
+               name varchar(128) NOT NULL,
+               admin boolean NOT NULL,
+               enabled boolean NOT NULL
+               )";
+               
+               $statement_handle = $database_handle->prepare($sqlquery) or ( $error = "DatabaseError", $errorext = $database_handle->errstr, return );
+               $statement_handle->execute();
+       
+               if ($DBI::err){
+                       
+                       $error = "DatabaseError";
+                       $errorext = $DBI::errstr;
+                       return;
+                       
+               }
+               
+       }
+       
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/Export/Download.pm b/cgi-files/Modules/Export/Download.pm
new file mode 100644 (file)
index 0000000..6bb117c
--- /dev/null
@@ -0,0 +1,255 @@
+#################################################################################
+# Xestia Scanner Server - Download Export Module.                              #
+# Presents the scanned image after being processed as a download link.         #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# Define the package (perl module) name.
+
+package Modules::Export::Download;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+use Encode qw(decode_utf8);
+use Modules::System::Common;
+use File::Copy;
+use File::Basename;
+
+# Set the following values.
+
+our $VERSION = "0.1.0";
+
+my $error_flag = 0;
+my $error_message = "";
+my $language_name = "";
+my %optionshash = ();
+
+sub new{
+#################################################################################
+# new: Create an instance of Modules::Output::Normal                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule = Modules::Output::Normal->new();                                  #
+#################################################################################
+       
+       # Get the perl module name.
+
+       my $class = shift;
+       my $self = {};
+
+       return bless($self, $class);
+
+}
+
+sub initialise{
+#################################################################################
+# initialise: Initialises the output module.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->initialise();                                                 #
+#################################################################################
+
+}
+
+sub loadsettings{
+#################################################################################
+# loadsettings: Loads some settings for the output module.                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->loadsettings(language);                                       #
+#                                                                              #
+# language     Specifies the language to use.                                  #
+#################################################################################
+       
+       my $class = shift;
+       my $passed_lang = shift;
+       
+       $language_name = $passed_lang;
+       
+}
+
+sub getoptions{
+#################################################################################
+# getoptions: Gets the options that will be used.                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# %options = $outputmodule->getoptions();                                      #
+#################################################################################
+
+       my (%options, $options);
+       tie(%options, "Tie::IxHash");
+       
+       $options{filenameforexport}{type} = "textbox";
+       $options{filenameforexport}{string} = languagestrings("filenametouse");
+       $options{filenameforexport}{maxlength} = "256";
+       $options{filenameforexport}{size} = "64";
+       
+       return %options;
+
+}
+
+sub exportimage{
+#################################################################################
+# exportimage: Exports the image.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $exportmodule->exportimage(processedfilename, scansuridirectory,             #
+#                              scansfsdirectory, exportoptions);               #
+#                                                                              #
+# processedfilename    Specifies the processed file to export.                 #
+# scansuridirectory    Specifies the URI of the scans directory.               #
+# scansfsdirectory     Specifies the FS location of the scans directory.       #
+# exportoptions                Specifies the options for the export module.            #
+#################################################################################
+
+       my ($exportoptions, %exportoptions);
+       
+       my $class = shift;
+       my $processed_filename = shift;
+       my $scans_uri = shift;
+       my $scans_fs = shift;
+       %exportoptions = @_;
+       
+       # Copy the file to the download directory.
+       
+       $! = 0;
+
+       # Remove everything before the last slash.
+       
+       my $processed_filename_nopath = fileparse($processed_filename);
+       
+       copy($processed_filename, "scans/" . $processed_filename_nopath) or ($error_flag = 1, $error_message = $!, return);
+       
+       # Move the file into the scans folder.
+       
+       if ($exportoptions{filenameforexport}){
+               
+               # Remove everything before the last slash.
+               
+               my $processedexportname = basename($exportoptions{filenameforexport});
+               
+               move("scans/" . $processed_filename_nopath, $scans_fs . "/" . $processedexportname) or ($error_flag = 1, $error_message = $!, return);
+               $processed_filename_nopath = $processedexportname;
+
+               
+       } else {
+       
+               move("scans/" . $processed_filename_nopath, $scans_fs . "/" . $processed_filename_nopath) or ($error_flag = 1, $error_message = $!, return);
+               
+       }
+       
+       # Print Link.
+       
+       $main::xestiascan_presmodule->addlink($scans_uri . "/" . $processed_filename_nopath, { Text => languagestrings("clicklink") });
+       
+       return;
+
+}
+
+sub errorflag{
+#################################################################################
+# errorflag: Returns an error flag (if any).                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errorflag   = $outputmodule->errorflag();                                   #
+#################################################################################
+       
+       return $error_flag;
+
+}
+
+sub errormessage{
+#################################################################################
+# errormessage: Returns an error message (if any).                             #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errormessage = $outputmodule->errormessage();                               #
+#################################################################################
+
+       return $error_message;
+
+}
+
+sub clearflag{
+#################################################################################
+# clearflag: Clears the error message flag and the error message itself.       #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->clearflag();                                                  #
+#################################################################################
+
+       $error_flag     = 0;
+       $error_message  = "";
+
+}
+
+sub languagestrings{
+#################################################################################
+# languagestrings: Language strings that are used in this module.              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $string = $outputmodule->languagestrings("langstring");                      #
+#################################################################################
+
+       my $langstring = shift;
+
+       my $language_string;
+       my ($language_strings, %language_strings);
+       my $item;
+       
+       if ($language_name eq "en-GB"){
+
+               # Language strings for English (British) language.
+               
+               $language_strings{clicklink} = "Click on or select this link to download the image.";
+               $language_strings{filenametouse} = "Filename to use (leave blank for default):";
+
+       } else {
+
+               # Invalid language so use English (British) as default.
+
+               $language_strings{clicklink} = "Click on or select this link to download the image.";
+               $language_strings{filenametouse} = "Filename to use (leave blank for default):";
+               
+       }
+
+       $language_string = $language_strings{$langstring};
+       
+       foreach $item (@_){
+
+                $language_string =~ s/%s/$item/;
+
+        }
+
+       return $language_string;
+
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/Export/Email.pm b/cgi-files/Modules/Export/Email.pm
new file mode 100644 (file)
index 0000000..40b7e6e
--- /dev/null
@@ -0,0 +1,370 @@
+#################################################################################
+# Xestia Scanner Server - Email Export Module.                                 #
+# Sends the page as an email.                                                  #
+#                                                                              #
+# Copyright (C) 2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>             #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# Define the package (perl module) name.
+
+package Modules::Export::Email;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+use Encode qw(decode_utf8);
+use Tie::IxHash;
+use Modules::System::Common;
+use MIME::Base64 3.13 qw(encode_base64);
+use File::Basename;
+use Net::Domain qw(hostfqdn);
+use Net::SMTP;
+use File::Basename;
+use File::MimeInfo;
+
+# Set the following values.
+
+our $VERSION = "0.1.0";
+
+my $error_flag = 0;
+my $error_message = "";
+my $language_name = "";
+my %optionshash = ();
+
+sub new{
+#################################################################################
+# new: Create an instance of Modules::Output::Normal                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule = Modules::Output::Normal->new();                                  #
+#################################################################################
+       
+       # Get the perl module name.
+       
+       my $class = shift;
+       my $self = {};
+       
+       return bless($self, $class);
+       
+}
+
+sub initialise{
+#################################################################################
+# initialise: Initialises the output module.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->initialise();                                                 #
+#################################################################################
+       
+}
+
+sub loadsettings{
+#################################################################################
+# loadsettings: Loads some settings for the output module.                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->loadsettings(language);                                       #
+#                                                                              #
+# language     Specifies the language to use.                                  #
+#################################################################################
+       
+       my $class = shift;
+       my $passed_lang = shift;
+       
+       $language_name = $passed_lang;
+
+}
+
+sub getoptions{
+#################################################################################
+# getoptions: Gets the options that will be used.                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# %options = $outputmodule->getoptions();                                      #
+#################################################################################
+       
+       my (%options, $options);
+       tie(%options, "Tie::IxHash");
+       
+       $options{servername}{type} = "textbox";
+       $options{servername}{string} = languagestrings("servername");
+       $options{servername}{maxlength} = "256";
+       $options{servername}{size} = "64";
+       
+       $options{serverport}{type} = "textbox";
+       $options{serverport}{string} = languagestrings("serverport");
+       $options{serverport}{value} = "25";
+       $options{serverport}{maxlength} = "5";
+       $options{serverport}{size} = "5";
+       
+       #$options{smtpssl}{type} = "checkbox";
+       #$options{smtpssl}{string} = "Enable SSL/TLS";
+       #$options{smtpssl}{checked} = 1;
+
+       $options{senderaddress}{type} = "textbox";
+       $options{senderaddress}{string} = languagestrings("senderaddress");
+       $options{senderaddress}{maxlength} = "256";
+       $options{senderaddress}{size} = "64";
+       
+       $options{emailaddress}{type} = "textbox";
+       $options{emailaddress}{string} = languagestrings("emailaddress");
+       $options{emailaddress}{maxlength} = "256";
+       $options{emailaddress}{size} = "64";
+       
+       $options{username}{type} = "textbox";
+       $options{username}{string} = languagestrings("username");
+       $options{username}{maxlength} = "256";
+       $options{username}{size} = "32";
+       
+       $options{password}{type} = "textbox";
+       $options{password}{string} = languagestrings("password");
+       $options{password}{maxlength} = "256";
+       $options{password}{password} = 1;
+       $options{password}{size} = "32";
+
+       $options{filename}{type} = "textbox";
+       $options{filename}{string} = languagestrings("filename");
+       $options{filename}{maxlength} = "256";
+       $options{filename}{size} = "64";
+       
+       $options{subjectline}{type} = "textbox";
+       $options{subjectline}{string} = languagestrings("subjectline");
+       $options{subjectline}{maxlength} = "256";
+       $options{subjectline}{value} = languagestrings("scannedimage");
+       $options{subjectline}{size} = "64";
+       
+       $options{personalmessage}{type} = "textbox";
+       $options{personalmessage}{string} = languagestrings("personalmessage");
+       $options{personalmessage}{maxlength} = "1024";
+       $options{personalmessage}{size} = "64";
+       
+       return %options;
+       
+}
+
+sub errorflag{
+#################################################################################
+# errorflag: Returns an error flag (if any).                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errorflag   = $outputmodule->errorflag();                                   #
+#################################################################################
+       
+       return $error_flag;
+       
+}
+
+sub errormessage{
+#################################################################################
+# errormessage: Returns an error message (if any).                             #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errormessage = $outputmodule->errormessage();                               #
+#################################################################################
+       
+       return $error_message;
+       
+}
+
+sub clearflag{
+#################################################################################
+# clearflag: Clears the error message flag and the error message itself.       #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->clearflag();                                                  #
+#################################################################################
+       
+       $error_flag     = 0;
+       $error_message  = "";
+       
+}
+
+sub exportimage{
+#################################################################################
+# exportimage: Exports the image.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $exportmodule->exportimage(processedfilename, scansuridirectory,             #
+#                              scansfsdirectory, exportoptions);               #
+#                                                                              #
+# processedfilename    Specifies the processed file to export.                 #
+# scansuridirectory    Specifies the URI of the scans directory.               #
+# scansfsdirectory     Specifies the FS location of the scans directory.       #
+# exportoptions                Specifies the options for the export module.            #
+#################################################################################
+
+       my ($exportoptions, %exportoptions);
+       
+       my $class = shift;
+       my $processed_filename = shift;
+       my $scans_uri = shift;
+       my $scans_fs = shift;
+       %exportoptions = @_;
+       
+       if (!$exportoptions{filename}){
+       
+               $exportoptions{filename} = basename($processed_filename);
+               
+       }
+       
+       # Try to connect to the SMTP server.
+       
+       my $smtp = Net::SMTP->new($exportoptions{servername},
+               Hello => hostfqdn,
+               Port => $exportoptions{serverport}
+       ) or ($error_flag = 1, $error_message = $!, return);
+       
+       $smtp->auth($exportoptions{username}, $exportoptions{password}) or ($error_flag = 1, $error_message = $smtp->message(), return);
+       
+       # Setup the sender and recipient addresses.
+       
+       $smtp->mail($exportoptions{senderaddress}) or ($error_flag = 1, $error_message = $smtp->message(), return);
+       
+       $smtp->recipient($exportoptions{emailaddress}) or ($error_flag = 1, $error_message = $smtp->message(), return);
+       
+       $smtp->data() or ($error_flag = 1, $error_message = $smtp->message(), return);
+       
+       # Generate a random value and get the MIME type for the file.
+       
+       my $randomhex = uc(sprintf("%x",int(rand(75000000))));
+       my $mime_type = mimetype($processed_filename);
+       
+       # Write out the header.
+
+       $smtp->datasend("Content-Disposition: inline\n");
+       $smtp->datasend("Content-Type: multipart/mixed; boundary=\"=-" . $randomhex ."\"\n");
+       $smtp->datasend("MIME-Version: 1.0\n");
+       $smtp->datasend("Subject: " . $exportoptions{subjectline} . "\n");
+       $smtp->datasend("To:" . $exportoptions{emailaddress} . "\n");
+       $smtp->datasend("X-Mailer: Xestia Scanner Server 0.1.0 (Email.pm; http://xestia.co.uk/scannerserver)\n");
+       
+       # Write the message (if there).
+       
+       $smtp->datasend("\n");
+       
+       $smtp->datasend("--=-" . $randomhex . "\n");
+       $smtp->datasend("Content-Type: text/plain;\n");
+       $smtp->datasend("\tcharset=utf-8\n");
+       $smtp->datasend("Content-Transfer-Encoding: 7bit\n\n");
+       
+       $smtp->datasend($exportoptions{personalmessage} . "\n\n");
+
+       $smtp->datasend("--=-" . $randomhex . "\n");
+       
+       # Encode the file to Base64 and "attach" to the email.
+
+       $smtp->datasend("Content-Disposition: attachment;\n");
+       $smtp->datasend("\tfilename=" . $exportoptions{filename} . "\n");
+       $smtp->datasend("Content-Type: " . $mime_type . ";\n");
+       $smtp->datasend("\tcharset=us-ascii;\n");
+       $smtp->datasend("\tname=" . $exportoptions{filename} . "\n");
+       $smtp->datasend("Content-Transfer-Encoding: base64\n\n");
+
+       # Open the file and process it into Base64.
+       
+       open((my $picture), "<", $processed_filename) or ($error_flag = 1, $error_message = $!, return);
+       binmode($picture);
+       
+       my $line;
+       
+       while (read($picture, $line, 60*57)){
+               
+               $smtp->datasend(encode_base64($line));
+               
+       }
+       
+       close($picture);
+       
+       $smtp->datasend("--" . $randomhex . "--\n");
+       $smtp->datasend("\n--=-" . $randomhex . "--\n");
+       
+       $smtp->dataend();
+       
+       $smtp->quit();
+       
+}
+
+sub languagestrings{
+#################################################################################
+# languagestrings: Language strings that are used in this module.              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $string = $outputmodule->languagestrings("langstring");                      #
+#################################################################################
+       
+       my $langstring = shift;
+       
+       my $language_string;
+       my ($language_strings, %language_strings);
+       my $item;
+       
+       if ($language_name eq "en-GB" or !$language_name){
+               
+               # Language strings for English (British) language.
+               
+               $language_strings{servername} = "Server name:";
+               $language_strings{serverport} = "Server port:";
+               $language_strings{senderaddress} = "Sender email address:";
+               $language_strings{emailaddress} = "Recipient email address:";
+               $language_strings{username} = "Username:";
+               $language_strings{password} = "Password:";
+               $language_strings{filename} = "Filename for image (blank for default):";
+               $language_strings{subjectline} = "Subject line:";
+               $language_strings{scannedimage} = "Scanned Image";
+               $language_strings{personalmessage} = "Personal Message:";
+               
+       } else {
+               
+               # Invalid language so use English (British) as default.
+               
+               $language_strings{servername} = "Server name:";
+               $language_strings{serverport} = "Server port:";
+               $language_strings{senderaddress} = "Sender email address:";
+               $language_strings{emailaddress} = "Recipient email address:";
+               $language_strings{username} = "Username:";
+               $language_strings{password} = "Password:";
+               $language_strings{filename} = "Filename for image (blank for default):";
+               $language_strings{subjectline} = "Subject line:";
+               $language_strings{scannedimage} = "Scanned Image";
+               $language_strings{personalmessage} = "Personal Message:";
+               
+       }
+       
+       $language_string = $language_strings{$langstring};
+       
+       foreach $item (@_){
+               
+                $language_string =~ s/%s/$item/;
+               
+        }
+       
+       return $language_string;
+       
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/Output/JPEG.pm b/cgi-files/Modules/Output/JPEG.pm
new file mode 100644 (file)
index 0000000..f7ff1f7
--- /dev/null
@@ -0,0 +1,231 @@
+#################################################################################
+# Xestia Scanner Server Output Module - JPEG Output Module.                    #
+# Outputs the image into the JPEG format.                                      #
+#                                                                              #
+# Copyright (C) 2010-11 Steve Brokenshire <sbrokenshire@xestia.co.uk>          #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# Define the package (perl module) name.
+
+package Modules::Output::JPEG;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+use Encode qw(decode_utf8);
+use Tie::IxHash;
+use Modules::System::Common;
+use Image::Magick;
+
+# Set the following values.
+
+our $VERSION = "0.1.0";
+my ($pages, %pages);
+my $error_flag = 0;
+my $error_message = "";
+my $language_name = "";
+my %optionshash = ();
+
+tie(%pages, "Tie::IxHash");
+
+sub new{
+#################################################################################
+# new: Create an instance of Modules::Output::Normal                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule = Modules::Output::Normal->new();                                  #
+#################################################################################
+       
+       # Get the perl module name.
+
+       my $class = shift;
+       my $self = {};
+
+       return bless($self, $class);
+
+}
+
+sub initialise{
+#################################################################################
+# initialise: Initialises the output module.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->initialise();                                                 #
+#################################################################################
+
+}
+
+sub loadsettings{
+#################################################################################
+# loadsettings: Loads some settings for the output module.                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->loadsettings(language);                                       #
+#                                                                              #
+# language     Specifies the language to use.                                  #
+#################################################################################
+       
+       my $class = shift;
+       my $passed_lang = shift;
+       
+       $language_name = $passed_lang;
+       
+}
+
+sub getoptions{
+#################################################################################
+# getoptions: Gets the options that will be used.                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# %options = $outputmodule->getoptions();                                      #
+#################################################################################
+
+       my (%options, $options);
+       tie(%options, "Tie::IxHash");
+       
+       $options{compression}{type} = "textbox";
+       $options{compression}{string} = languagestrings("compressionratio");
+       $options{compression}{maxlength} = "3";
+       $options{compression}{value} = "100";
+       $options{compression}{size} = "3";
+       
+       return %options;
+
+}
+
+sub errorflag{
+#################################################################################
+# errorflag: Returns an error flag (if any).                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errorflag   = $outputmodule->errorflag();                                   #
+#################################################################################
+       
+       return $error_flag;
+
+}
+
+sub errormessage{
+#################################################################################
+# errormessage: Returns an error message (if any).                             #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errormessage = $outputmodule->errormessage();                               #
+#################################################################################
+
+       return $error_message;
+
+}
+
+sub clearflag{
+#################################################################################
+# clearflag: Clears the error message flag and the error message itself.       #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->clearflag();                                                  #
+#################################################################################
+
+       $error_flag     = 0;
+       $error_message  = "";
+
+}
+
+sub processimage{
+#################################################################################
+# processimage: Processes the image.                                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->processimage(hexnumber, outputmoduleoptions);                 #
+#                                                                              #
+# hexnumber            Specifies the hex number for the image.                 #
+# outputmoduleoptions  Specifies the options for the output module as a hash.  #
+#################################################################################
+       
+       my ($outputmoduleoptions, %outputmoduleoptions);
+       
+       my $class = shift;
+       my $hexnumber = shift;
+       %outputmoduleoptions = @_;
+       
+       my $compression = $outputmoduleoptions{compression};
+       
+       my $im = new Image::Magick;
+       $im->Read("/tmp/xestiascanserver-preview-" . $hexnumber . ".pnm");
+       
+       $compression = 100 if $compression > 100;
+       $compression = 0 if $compression < 0;
+       
+       $im->Set(quality => $compression);
+       
+       $im->Write("/tmp/xestiascanserver-final-" . $hexnumber . ".jpg");
+       
+       return "/tmp/xestiascanserver-final-" . $hexnumber . ".jpg";
+       
+}
+
+sub languagestrings{
+#################################################################################
+# languagestrings: Language strings that are used in this module.              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $string = $outputmodule->languagestrings("langstring");                      #
+#################################################################################
+
+       my $langstring = shift;
+
+       my $language_string;
+       my ($language_strings, %language_strings);
+       my $item;
+       
+       if ($language_name eq "en-GB"){
+
+               # Language strings for English (British) language.
+
+               $language_strings{compressionratio} = "Compression Ratio (%):";
+
+       } else {
+
+               # Invalid language so use English (British) as default.
+
+               $language_strings{compressionratio} = "Compression Ratio (%):";
+
+       }
+
+       $language_string = $language_strings{$langstring};
+       
+       foreach $item (@_){
+
+                $language_string =~ s/%s/$item/;
+
+        }
+
+       return $language_string;
+
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/Output/PNG.pm b/cgi-files/Modules/Output/PNG.pm
new file mode 100644 (file)
index 0000000..934e093
--- /dev/null
@@ -0,0 +1,238 @@
+#################################################################################
+# Xestia Scanner Server Output Module - PNG Output Module.                     #
+# Outputs the image into the PNG format.                                       #
+#                                                                              #
+# Copyright (C) 2010-11 Steve Brokenshire <sbrokenshire@xestia.co.uk>          #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# Define the package (perl module) name.
+
+package Modules::Output::PNG;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+use Encode qw(decode_utf8);
+use Tie::IxHash;
+use Modules::System::Common;
+use Image::Magick;
+
+# Set the following values.
+
+our $VERSION = "0.1.0";
+my ($pages, %pages);
+my $error_flag = 0;
+my $error_message = "";
+my $language_name = "";
+my %optionshash = ();
+
+tie(%pages, "Tie::IxHash");
+
+sub new{
+#################################################################################
+# new: Create an instance of Modules::Output::Normal                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $dbmodule = Modules::Output::Normal->new();                                  #
+#################################################################################
+       
+       # Get the perl module name.
+
+       my $class = shift;
+       my $self = {};
+
+       return bless($self, $class);
+
+}
+
+sub initialise{
+#################################################################################
+# initialise: Initialises the output module.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->initialise();                                                 #
+#################################################################################
+
+}
+
+sub loadsettings{
+#################################################################################
+# loadsettings: Loads some settings for the output module.                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->loadsettings(language);                                       #
+#                                                                              #
+# language     Specifies the language to use.                                  #
+#################################################################################
+       
+       my $class = shift;
+       my $passed_lang = shift;
+       
+       $language_name = $passed_lang;
+       
+}
+
+sub getoptions{
+#################################################################################
+# getoptions: Gets the options that will be used.                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# %options = $outputmodule->getoptions();                                      #
+#################################################################################
+
+       my (%options, $options);
+       tie(%options, "Tie::IxHash");
+
+       #$options{seperatedirdatabase}{type} = "checkbox";
+       #$options{seperatedirdatabase}{string} = "Disable content type (make browser guess!)";
+       return %options;
+
+}
+
+sub errorflag{
+#################################################################################
+# errorflag: Returns an error flag (if any).                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errorflag   = $outputmodule->errorflag();                                   #
+#################################################################################
+       
+       return $error_flag;
+
+}
+
+sub errormessage{
+#################################################################################
+# errormessage: Returns an error message (if any).                             #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $errormessage = $outputmodule->errormessage();                               #
+#################################################################################
+
+       return $error_message;
+
+}
+
+sub clearflag{
+#################################################################################
+# clearflag: Clears the error message flag and the error message itself.       #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->clearflag();                                                  #
+#################################################################################
+
+       $error_flag     = 0;
+       $error_message  = "";
+
+}
+
+sub processimage{
+#################################################################################
+# processimage: Processes the image.                                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $outputmodule->processimage(hexnumber, outputmoduleoptions);                 #
+#                                                                              #
+# hexnumber            Specifies the hex number for the image.                 #
+# outputmoduleoptions  Specifies the options for the output module as a hash.  #
+#################################################################################
+       
+       my $class = shift;
+       my $hexnumber = shift;
+       my $outputmoduleoptions = @_;
+       
+       my $errmsg;
+       
+       my $im = new Image::Magick;
+       $errmsg = $im->Read("/tmp/xestiascanserver-preview-" . $hexnumber . ".pnm");
+       
+       if ($errmsg){
+               
+               $error_flag = 1;
+               $error_message = $errmsg;
+               return;
+               
+       }
+       
+       $errmsg = $im->Write("/tmp/xestiascanserver-final-" . $hexnumber . ".png");
+
+       if ($errmsg){
+               
+               $error_flag = 1;
+               $error_message = $errmsg;
+               return;
+               
+       }
+       
+       return "/tmp/xestiascanserver-final-" . $hexnumber . ".png";
+       
+}
+
+sub languagestrings{
+#################################################################################
+# languagestrings: Language strings that are used in this module.              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $string = $outputmodule->languagestrings("langstring");                      #
+#################################################################################
+
+       my $langstring = shift;
+
+       my $language_string;
+       my ($language_strings, %language_strings);
+       my $item;
+
+       if ($language_name eq "en-GB" or !$language_name){
+
+               # Language strings for English (British) language.
+
+               $language_strings{seperatedirdatabase} = "Seperate directory for each database.";
+               $language_strings{invalidpermissionset} = "Invalid file permissions set.";
+
+       } else {
+
+               # Invalid language so use English (British) as default.
+
+               $language_strings{seperatedirdatabase} = "Seperate directory for each database.";
+               $language_strings{invalidpermissionset} = "Invalid file permissions set.";
+
+       }
+
+       $language_string = $language_strings{$langstring};
+       
+       foreach $item (@_){
+
+                $language_string =~ s/%s/$item/;
+
+        }
+
+       return $language_string;
+
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/Presentation/HTML4S.pm b/cgi-files/Modules/Presentation/HTML4S.pm
new file mode 100644 (file)
index 0000000..db7213f
--- /dev/null
@@ -0,0 +1,2068 @@
+#################################################################################
+# Xestia Scanner Server Presentation Module - HTML 4.0 Strict (HTML4S.pm)      #
+# Output Module for writing pages to the HTML 4.0 Strict Standard              #
+#                                                                              #
+# Copyright (C) 2007-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+# Define the package (perl module) name.
+
+package Modules::Presentation::HTML4S;
+
+# Enable strict and use warnings.
+
+use strict;
+use warnings;
+
+# Set the following values.
+
+our $VERSION = "0.1.0";
+my $pagedata = "";
+my $tablevel = 0;
+
+#################################################################################
+# Generic Subroutines.                                                         #
+#################################################################################
+
+sub new{
+#################################################################################
+# new: Create an instance of HTML4S                                            #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule = Modules::Presentation::HTML4S->new();                          #
+#################################################################################
+       
+       # Get the perl module name.
+
+       my $class = shift;
+       my $self = {};
+
+       return bless($self, $class);
+
+}
+
+sub clear{
+#################################################################################
+# clear: Clear the current layout created by this module.                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->clear();                                                                #
+#################################################################################
+
+       $pagedata = "";
+       return;
+
+}
+
+sub grab{
+#################################################################################
+# grab: Grab the current layout created by this module.                                #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->grab();                                                         #
+#################################################################################
+
+       return $pagedata;
+
+}
+
+sub convert{
+#################################################################################
+# convert: Converts the data passed into data that is compliant with the output #
+# format.                                                                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->convert(data, type);                                            #
+#                                                                              #
+# data         Specifies the data to be converted.                             #
+# type         Specifies the type the data should be converted to.             #
+#################################################################################
+
+       # Get the data and type passed.
+
+       my $class = shift;
+       my ($data, $type) = @_;
+
+       # Check if certain values are undefined and if they are
+       # then set them blank or return an error.
+
+       if (!$data){
+               $data = "";
+       }
+
+       if (!$type){
+               die("No type was specified");
+       }
+
+       # Check what type is being used and process the data
+       # according the type being used.
+
+       if ($type eq "content"){
+
+               $data =~ s/&/&amp;/g;
+               $data =~ s/#/&#35;/g;
+               $data =~ s/\"/&#34;/g;
+               $data =~ s/'/'/g;
+               $data =~ s/>/&gt;/g;
+               $data =~ s/</&lt;/g;
+               $data =~ s/\+/&#43;/g;
+               $data =~ s/-/&#45;/g;
+               $data =~ s/_/&#95;/g;
+               $data =~ s/\@/&#64;/g;
+               $data =~ s/~/&#126;/g;
+               $data =~ s/\?/&#63;/g;
+               $data =~ s/'/&#39;/g;
+               $data =~ s/\0//g;
+               $data =~ s/\b//g;
+
+       } elsif ($type eq "link"){
+
+               $data =~ s/&/&amp;/g;
+               $data =~ s/\+/\%2B/g;
+               $data =~ s/\?/\%3F/g;
+               $data =~ s/%3F/\?/;
+               $data =~ s/-/\%2D/g;
+               $data =~ s/_/\%5F/g;
+               $data =~ s/\@/\%40/g;
+               $data =~ s/#/\%23/g;
+               $data =~ s/>/\%3E/g;
+               $data =~ s/</\%3C/g;
+               $data =~ s/~/\%7E/g;
+               $data =~ s/'/\%27/;
+               $data =~ s/!/\%21/g;
+
+       } else {
+
+               die("An invalid type was specified.");
+
+       }
+
+       return $data;
+
+}
+
+#################################################################################
+# Tags for creating tables.                                                    #
+#################################################################################
+
+sub starttable{
+#################################################################################
+# starttable: Start a table.                                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->starttable(cssstyle, {options});                                        #
+#                                                                              #
+# cssstyle     Specifies the CSS style name to use.                            #
+# options      Specifies the following options (in any order):                 #
+#                                                                              #
+# CellPadding  The cell padding to be used for each table.                     #
+# CellSpacing  The cell spacing to be used for each table.                     #
+#################################################################################
+
+       # Get the CSS style and options.
+
+       my $class = shift;
+       my ($cssstyle, $options) = @_;
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       my $cellpadding = $options->{'CellPadding'};
+       my $cellspacing = $options->{'CellSpacing'};
+
+       # Check if the cell padding and cell spacing and 
+       # CSS style values are blank and if they are then 
+       # set them blank.
+
+       if (!$cellpadding){
+               $cellpadding = 0;
+       }
+
+       if (!$cellspacing){
+               $cellspacing = 0;
+       }
+
+       if (!$cssstyle){
+               $cssstyle = "";
+       }
+
+       # Check if the cell padding and cell spacing values
+       # are valid and die if it isn't.
+
+       my $cellpadding_validated = $cellpadding;
+       my $cellspacing_validated = $cellspacing;
+
+       $cellpadding_validated =~ tr/0-9//d;
+       $cellspacing_validated =~ tr/0-9//d;
+
+       if ($cellpadding_validated ne ""){
+               die("Cell padding value given is invalid.");
+       }
+
+       if ($cellspacing_validated ne ""){
+               die("Cell spacing value given is invalid.");
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Start a table.
+
+       $tagdata = $tagdata . "<table";
+
+       # Check if the cell spacing and cell padding has values
+       # more than 0.
+
+       if ($cellspacing >= 0){
+               $tagdata = $tagdata . " cellspacing=\"" . $cellspacing . "\"";
+       }
+
+       if ($cellpadding > 0){
+               $tagdata = $tagdata . " cellpadding=\"" . $cellpadding . "\"";
+       }
+
+       if ($cssstyle ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($cssstyle, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub startheader{
+#################################################################################
+# startheader: Start a table header.                                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->startheader();                                                  #
+#################################################################################
+
+       # Start a table header row.
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<tr>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub addheader{
+#################################################################################
+# addheader: Add a table header.                                               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addheader(headername, {options});                               #
+#                                                                              #
+# headername   Specifies the name of the table header to use.                  #
+# options      Specifies the following options below (in any order):           #
+#                                                                              #
+# Style                Specifies the CSS Style to use for the table header.            #
+#################################################################################
+
+       # Get the header name and options.
+
+       my $class       = shift;
+       my ($headername, $options)      = @_;
+
+       my $cssstyle    = $options->{'Style'};
+
+       # Check if the CSS Style or header name is undefined and
+       # if they are then set them blank.
+
+       if (!$headername){
+               $headername = "";
+       }
+
+       if (!$cssstyle){
+               $cssstyle = "";
+       }
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<th";
+       
+       if ($cssstyle ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($cssstyle, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . $class->convert($headername, "content") . "</th>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endheader{
+#################################################################################
+# endheader: End a table header row                                            #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endheader();                                                    #
+#################################################################################
+
+       # End a table header row.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</tr>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub startrow{
+#################################################################################
+# startrow: Start a table row.                                                 #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->startrow();                                                     #
+#################################################################################
+
+       # Start a table row.
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<tr>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub addcell{
+#################################################################################
+# addcell: Add a table cell.                                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addcell(style);                                                 #
+#                                                                              #
+# style                Specifies which CSS Style to use.                               #
+#################################################################################
+
+       # Get the cell information and options.
+
+       my $class       = shift;
+       my ($cssstyle)  = @_;
+       my $tabcount    = $tablevel;
+       my $tagdata     = "";
+
+       # Check if the cell data and CSS style are undefined
+       # and if they are then set them blank.
+
+       if (!$cssstyle){
+               $cssstyle = "";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<td";
+
+       if ($cssstyle ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($cssstyle, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endcell{
+#################################################################################
+# endcell: End a table cell.                                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endcell();                                                      #
+################################################################################# 
+
+       # End a table cell.
+
+       my $tagdata = "";
+
+       $tagdata = $tagdata . "</td>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endrow{
+#################################################################################
+# endrow: Ends a table row.                                                    #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endrow();                                                       #
+#################################################################################
+
+       # End a table row.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</tr>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endtable{
+#################################################################################
+# endtable: Ends a table.                                                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endtable();                                                     #
+#################################################################################
+
+       # End a table.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</table>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Information box.                                                             #
+#################################################################################
+
+sub startbox{
+#################################################################################
+# startbox: Start an information box.                                          #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->startbox(cssstyle);                                             #
+#                                                                              #
+# cssstyle     Specifies the CSS Style to use.                                 #
+#################################################################################
+
+       # Get the CSS Style name.
+
+       my $class       = shift;
+       my $cssstyle    = shift;
+
+       # Check if the CSS style given is undefined and
+       # if it is then set it blank.
+
+       if (!$cssstyle){
+               $cssstyle = "";
+       }
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Start an information box.
+
+       $tagdata = $tagdata . "<div";
+       
+       if ($cssstyle ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($cssstyle, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub enterdata{
+#################################################################################
+# enterdata: Enter data into a information box.                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->enterdata(data);                                                        #
+#                                                                              #
+# data         Specifies what data should be entered into the information box. #
+#################################################################################
+
+       # Get the data for the information box.
+
+       my $class       = shift;
+       my $data        = shift;
+
+       # Append the data to the page data.
+
+       $pagedata = $pagedata . $class->convert($data, "content");
+
+}
+
+sub endbox{
+#################################################################################
+# endbox: End an information box.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endbox();                                                       #
+#################################################################################
+
+       # End an information box.
+
+       my $tagdata = "";
+       $tagdata = $tagdata . "</div>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Form boxes.                                                                  #
+#################################################################################
+
+sub startform{
+#################################################################################
+# startform: Start a form.                                                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->startform(action, method);                                      #
+#                                                                              #
+# action       Specifies the action (address) the data should be sent to.      #
+# method       Specifies the method to use (POST, GET)                         #
+#################################################################################
+
+       my $class       = shift;
+       my $action      = shift;
+       my $method      = shift;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Check if the action and method values given
+       # are undefined and if they are set default
+       # values.
+
+       if (!$action){
+               $action = "";
+       }
+
+       if (!$method){
+               # The method is blank so set it to POST.
+               $method = "POST";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<form action=\"" . $class->convert($action, "content") . "\" method=\"" . $class->convert($method, "content") . "\">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub addcheckbox{
+#################################################################################
+# addcheckbox: Add a check box.                                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addcheckbox(checkboxname, {options});                           #
+#                                                                              #
+# checkboxname Specifies the check box name.                                   #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# OptionDescription    Specifies a description for the checkbox value.         #
+# Style                        Specifies the CSS style to use.                         #
+# Checked              Specifies if the checkbox is checked.                   #
+# LineBreak            Specifies if a line break should be added.              #
+# ReadOnly             Specifies the check box is read only.                   #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($checkboxname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $optiondescription   = $options->{'OptionDescription'};
+       my $style               = $options->{'Style'};
+       my $checked             = $options->{'Checked'};
+       my $linebreak           = $options->{'LineBreak'};
+       my $readonly            = $options->{'ReadOnly'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$checkboxname){
+               die("The checkbox name is blank.");
+       }
+
+       if (!$optiondescription){
+               $optiondescription = "";
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$checked){
+               $checked = 0;
+       }
+
+       if (!$linebreak){
+               $linebreak = 0;
+       }
+       
+       if (!$readonly){
+               $readonly = 0;
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a check box.
+
+       $tagdata = $tagdata . "<input type=\"checkbox\" name=\"" . $class->convert($checkboxname, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($checked eq 1){
+               $tagdata = $tagdata . " checked";
+       }
+       
+       if ($readonly eq 1){
+               $tagdata = $tagdata . " disabled";
+       }
+
+       $tagdata = $tagdata . ">";
+
+       if ($optiondescription ne ""){
+               $tagdata = $tagdata . "&nbsp;" . $class->convert($optiondescription, "content");
+       }
+
+       if ($linebreak eq 1){
+               $tagdata = $tagdata . "<br>";
+       }
+
+       $tagdata = $tagdata . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addradiobox{
+#################################################################################
+# addradiobox: Add a radio box.                                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addradiobox(radioboxname, {options});                           #
+#                                                                              #
+# radioboxname The name of the radio box.                                      #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Description          Specifies a description for the checkbox value.         #
+# Style                        Specifies the CSS style to use.                         #
+# Selected             Specifies if the radio box is selected.                 #
+# LineBreak            Specifies if a line break should be used.               #
+# Value                        Specifies the value of the radio box.                   #
+# ReadOnly             Specifies the radio box is read only.                   #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($radioboxname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $optiondescription   = $options->{'Description'};
+       my $style               = $options->{'Style'};
+       my $selected            = $options->{'Selected'};
+       my $linebreak           = $options->{'LineBreak'};
+       my $value               = $options->{'Value'};
+       my $readonly            = $options->{'ReadOnly'};
+       
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.        
+
+       if (!$radioboxname){
+               die("The radio box name is blank.");
+       }
+
+       if (!$value){
+               $value = "";
+       }
+
+       if (!$optiondescription){
+               $optiondescription = "";
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$selected){
+               $selected = 0;
+       }
+
+       if (!$linebreak){
+               $linebreak = 0;
+       }
+
+       if (!$readonly){
+               $readonly = 0;
+       }
+       
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a radio box.
+
+       $tagdata = $tagdata . "<input type=\"radio\" name=\"" . $class->convert($radioboxname, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($selected eq 1){
+               $tagdata = $tagdata . " checked";
+       }
+       
+       if ($readonly eq 1){
+               $tagdata = $tagdata . " disabled";
+       }
+
+       if ($value ne ""){
+               $tagdata = $tagdata . " value=\"" . $class->convert($value, "content") . "\"";
+       } else {
+               $tagdata = $tagdata . " value=\"0\"";
+       }
+
+       $tagdata = $tagdata . ">";
+
+       if ($optiondescription ne ""){
+               $tagdata = $tagdata . "&nbsp;" . $class->convert($optiondescription, "content");
+       }
+
+       if ($linebreak eq 1){
+               $tagdata = $tagdata . "<br>";
+       }
+
+       $tagdata = $tagdata . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+}
+
+sub addselectbox{
+#################################################################################
+# addselectbox: Add a select box.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addselectbox(selectname, {options});                            #
+#                                                                              #
+# selectboxname        Specifies the name of the select box.                           #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+# ReadOnly     Specifies the select box is read only.                          #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($selectboxname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+       my $readonly    = $options->{'ReadOnly'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$selectboxname){
+               die("The select box name is blank.")
+       }
+
+       if (!$style){
+               $style = "";
+       }
+       
+       if (!$readonly){
+               $readonly = 0;
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a select box.
+
+       $tagdata = $tagdata . "<select name=\"" . $class->convert($selectboxname, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata = " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($readonly eq 1){
+               $tagdata = $tagdata . " disabled";
+       }
+       
+       $tagdata = $tagdata . ">";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub addoption{
+#################################################################################
+# addoption: Add an option for a select box.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addoption(optionname, options);                                 #
+#                                                                              #
+# optionname   Specifies the name (description) of the option.                 #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Style                Specifies the CSS style to be used.                             #
+# Value                Specifies the value of the option.                              #
+# Selected     This option is selected as default when the page is displayed.  #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($optionname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+       my $value       = $options->{'Value'};
+       my $selected    = $options->{'Selected'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$optionname){
+               die("The option name given is blank.");
+       }
+
+       if (!$value){
+               die("No value for the option was given.");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$selected){
+               $selected = 0;
+       }
+
+       # Check if certain values are valid and return
+       # an error if they aren't.
+
+       my $selected_validated = $selected;
+
+       $selected_validated =~ tr/0-9//d;
+
+       if ($selected_validated ne ""){
+               die("The selection option is invalid.");
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add an option for a select box.
+
+       $tagdata = $tagdata . "<option value=\"" . $class->convert($value, "content") . "\"";
+       
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($selected eq 1){
+               $tagdata = $tagdata . " selected";
+       }
+       
+       $tagdata = $tagdata . ">" . $class->convert($optionname, "content") .  "</option>\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endselectbox{
+#################################################################################
+# endselectbox: Ends a select box.                                             #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endselectbox();                                                 #
+#################################################################################
+
+       # End a select box.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</select>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addinputbox{
+#################################################################################
+# addinputbox: Add a input text box.                                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addinputbox(inputboxname, options);                             #
+#                                                                              #
+# inputboxname Specifies the name of the input text box.                       #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Size         Specifies the size of the input text box.                       #
+# MaxLength    Specifies the maximum length of the input text box.             #
+# Style                Specifies the CSS style to use.                                 #
+# Value                Specifies a value for the input box.                            #
+# Password     Specifies the input box is a password box.                      #
+# ReadOnly     Specifies the input box is read only.                           #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($inputboxname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $size        = $options->{'Size'};
+       my $maxlength   = $options->{'MaxLength'};
+       my $style       = $options->{'Style'};
+       my $value       = $options->{'Value'};
+       my $password    = $options->{'Password'};
+       my $readonly    = $options->{'ReadOnly'};
+       my $zerointeger = $options->{'ZeroInteger'};
+
+
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$inputboxname){
+               die("The input box name given is blank.");
+       }
+
+       if (!$size){
+               $size = 0;
+       }
+
+       if (!$maxlength){
+               $maxlength = 0;
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$value){
+               $value = "";
+       }
+
+       if (!$zerointeger){
+               $zerointeger = 0;
+       }
+
+       if (!$password){
+               $password = 0;
+       }
+
+       if (!$readonly){
+               $readonly = 0;
+       }
+       
+       # Check if certain values are valid and return
+       # an error if they aren't.
+
+       my $size_validated = $size;
+       my $maxlength_validated = $maxlength;
+
+       $size_validated         =~ tr/0-9//d;
+       $maxlength_validated    =~ tr/0-9//d;
+
+       if ($size_validated ne ""){
+               die("The size given is invalid.");
+       }
+
+       if ($maxlength_validated ne ""){
+               die("The maximum length given is invalid.");
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add an input text box.
+
+       $tagdata = "<input "; 
+
+       # Check if it should be a password field.
+
+       if ($password eq 1){
+
+               # The field should be a password field.
+
+               $tagdata = $tagdata . "type=\"password\" ";
+
+       } else {
+
+               # The field should be a text field.
+
+               $tagdata = $tagdata . "type=\"text\" ";
+
+       }
+
+       $tagdata = $tagdata . "name=\"" . $class->convert($inputboxname, "content") . "\"";
+       
+       if ($size > 0){
+               $tagdata = $tagdata . " size=\"" . $class->convert($size, "content") . "\"";
+       }
+
+       if ($maxlength > 0){
+               $tagdata = $tagdata . " maxlength=\"" . $class->convert($maxlength, "content") . "\"";
+       }
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($value ne ""){
+               $tagdata = $tagdata . " value=\"" . $class->convert($value, "content") . "\"";
+       }
+
+       if ($value eq "" && $zerointeger eq 1){
+               $tagdata = $tagdata . " value=\"0\"";
+       }
+
+       if ($readonly eq 1){
+               $tagdata = $tagdata . " disabled";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addtextbox{
+#################################################################################
+# addtextbox: Add a multiple line text box.                                    #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addtextbox(textboxname, options);                               #
+#                                                                              #
+# textboxname  Specifies the name of the multiple line text box.               #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Columns      Specifies the width of the multiple line text box.              #
+# Rows         Specifies the height of the multiple line text box.             #
+# Style                Specifies the CSS style to use.                                 #
+# Value                Specifies a value for the multiple line text box.               #
+# ReadOnly     Specifies if the text box is read only.                         #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($textboxname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $columns     = $options->{'Columns'};
+       my $rows        = $options->{'Rows'};
+       my $style       = $options->{'Style'};
+       my $value       = $options->{'Value'};
+       my $readonly    = $options->{'ReadOnly'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$textboxname){
+               die("The multiple line text box name is blank.");
+       }
+       
+       if (!$columns){
+               $columns = 0;
+       }
+
+       if (!$rows){
+               $rows = 0;
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$value){
+               $value = "";
+       }
+       
+       if (!$readonly){
+               $readonly = 0;
+       }
+
+       # Check if certain values are valid and return
+       # an error if they aren't.
+
+       my $columns_validated   = $columns;
+       my $rows_validated      = $rows;
+
+       $columns_validated      =~ tr/0-9//d;
+       $rows_validated         =~ tr/0-9//d;
+
+       if ($columns_validated ne ""){
+               die("The columns value given is invalid.");
+       }
+
+       if ($rows_validated ne ""){
+               die("The rows value given is invalid.");
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a multiple line text box.
+
+       $tagdata = $tagdata . "<textarea name=\"" . $class->convert($textboxname, "content") . "\"";
+
+       if ($columns > 0){
+               $tagdata = $tagdata . " cols=\"" . $class->convert($columns, "content") . "\"";
+       }       
+
+       if ($rows > 0){
+               $tagdata = $tagdata . " rows=\"" . $class->convert($rows, "content") . "\"";
+       }
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }       
+
+       if ($readonly eq 1){
+               $tagdata = $tagdata . " disabled";
+       }
+       
+       $tagdata = $tagdata . ">";
+       $tagdata = $tagdata . $class->convert($value, "content");
+       $tagdata = $tagdata . "</textarea>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addsubmit{
+#################################################################################
+# addsubmit: Add a submit button.                                              #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $pagemodule->addsubmit(submitname, options);                                 #
+#                                                                              #
+# submitname   Specifies the name (label) of the submit button.                #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($submitname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+       
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$submitname){
+               die("The submit name is blank.");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a submit button.
+
+       $tagdata = $tagdata . "<input type=\"submit\" value=\"" . $class->convert($submitname, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addreset{
+#################################################################################
+# addreset: Add a reset button.                                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $pagemodule->addreset(resetname, options);                                   #
+#                                                                              #
+# resetname    Specifies the name (label) of the reset button.                 #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($resetname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+       
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$resetname){
+               die("The reset name is blank.");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a reset button.
+
+       $tagdata = $tagdata . "<input type=\"reset\" value=\"" . $class->convert($resetname, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addhiddendata{
+#################################################################################
+# addhiddendata: Adds hidden data to the form.                                 #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addhiddendata(name, value);                                     #
+#                                                                              #
+# name         Specifies the name of the hidden data.                          #
+# value                Specifies the value of the hidden data.                         #
+#################################################################################
+
+       # Get the name and value.
+
+       my $class       = shift;
+       my ($name, $value) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$name){
+               die("The name for the hidden data is blank.");
+       }
+
+       if (!$value){
+               $value = "";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add hidden data.
+
+       $tagdata = $tagdata . "<input type=\"hidden\" name=\"" . $class->convert($name, "content") . "\"";
+
+       if ($value ne ""){
+               $tagdata = $tagdata . " value=\"" . $class->convert($value, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Add the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addbutton{
+#################################################################################
+# addbutton: Add a button.                                                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addbutton(buttonname, options);                                 #
+#                                                                              #
+# buttonname   Specifies the name of button.                                   #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Value                Specifies the value of the button.                              #
+# Description  Specifies the description (label) of the button.                #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($buttonname, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $value       = $options->{'Value'};
+       my $description = $options->{'Description'};
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$buttonname){
+               die("The name for button is blank.");
+       }
+
+       if (!$value){
+               $value = "";
+       }
+
+       if (!$description){
+               die("The description for the button is blank.");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a button.
+
+       $tagdata = $tagdata . "<button name=\"" . $class->convert($buttonname, "content") . "\"";       
+
+       if ($value ne ""){
+               $tagdata = $tagdata . " value=\"" . $class->convert($value, "content") . "\"";
+       }
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . $class->convert($description, "content") . "</button>\r\n";
+
+       # Add the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endform{
+#################################################################################
+# endform: Ends a form.                                                                #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->endform();                                                      #
+#################################################################################
+
+       # End a form.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</form>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Page Link.                                                                   #
+#################################################################################
+
+sub addlink{
+#################################################################################
+# addlink: Adds a link.                                                                #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addlink(link, options);                                         #
+#                                                                              #
+# Link         Specifies the location of the link.                             #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Target       Specifies the target window for the link.                       #
+# Text         Specifies the text to use.                                      #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($link, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $target      = $options->{'Target'}; 
+       my $name        = $options->{'Text'};
+       my $embed       = $options->{'Embed'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$link){
+               die("The link specified was blank.");
+       }
+
+       if (!$target){
+               $target = "";
+       }
+
+       if (!$embed){
+               $embed = 0;
+       }
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add a link.
+
+       $tagdata = "<a href=\"" . $class->convert($link, "link") . "\"";        
+
+       if ($target ne ""){
+               $tagdata = $tagdata . " target=\"" . $class->convert($target, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . $class->convert($name, "content")  . "</a>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Image.                                                                       #
+#################################################################################
+
+sub addimage{
+#################################################################################
+# addimage: Adds an image.                                                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addimage(image, options);                                       #
+#                                                                              #
+# image                Specifies the location of the image.                            #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+# Description  Specifies the description of the image.                         #
+# Width                Specifies the width of the image.                               #
+# Height       Specifies the height of the image.                              #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($image, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+       my $width       = $options->{'Width'};
+       my $height      = $options->{'Height'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$image){
+               die("The link to the image given is blank");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$width){
+               $width = int(0);
+       }
+
+       if (!$height){
+               $height = int(0);
+       }
+
+       # Check if certain values are valid and return
+       # an error if they aren't.
+
+       my $width_validated     = $width;
+       my $height_validated    = $height;
+
+       $width_validated        =~ tr/0-9//d;
+       $height_validated       =~ tr/0-9//d;
+
+       #if (!$width_validated){
+       #       die("The width value given is invalid.");
+       #}
+
+       #if (!$height_validated){
+       #       die("The height value given is invalid.");
+       #}
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       # Add an image.
+
+       $tagdata = $tagdata . "<img src=\"" . $class->convert($image, "content") . "\"";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       if ($width ne 0){
+               $tagdata = $tagdata . " width=\"" . $class->convert($width, "content") . "\"";
+       }
+
+       if ($height ne 0){
+               $tagdata = $tagdata . " height=\"" . $class->convert($height, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Text.                                                                                #
+#################################################################################
+
+sub addtext{
+#################################################################################
+# addtext: Adds some text.                                                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addtext(text, options);                                         #
+#                                                                              #
+# text         Specifies the text to add.                                      #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($text, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$style){
+               $style = "";
+       }
+
+       if (!$text){
+               $text = "";
+       }
+
+       # Add some text.
+
+       if ($style ne ""){
+               $tagdata = $tagdata . "<span class=\"" . $class->convert($style, "content") . "\">" . $class->convert($text, "content") . "</span>";
+       } else {
+               $tagdata = $tagdata . $class->convert($text, "content");
+       }       
+
+       # Append the tagdata to the pagedata.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addboldtext{
+#################################################################################
+# addboldtext: Adds some bold text.                                            #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addboldtext(text, options);                                     #
+#                                                                              #
+# text         Specifies the text to add.                                      #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($text, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$text){
+               die("The text given was blank.");
+       }       
+
+       if (!$style){
+               $style = "";
+       }
+
+       # Add some bold text.
+
+       if ($style ne ""){
+               $tagdata = $tagdata . "<span class=\"" . $style . "\">" . $class->convert($text, "content") . "</span>";
+       } else {
+               $tagdata = $tagdata . "<b>" . $class->convert($text, "content") . "</b>";
+       }
+
+       # Append the tagdata to the pagedata.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub additalictext{
+#################################################################################
+# addboldtext: Adds some italic text.                                          #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->additalictext(text, options);                                   #
+#                                                                              #
+# text         Specifies the text to add.                                      #
+# options      Specifies the following options below (in any order).           #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+       # Get the options recieved.
+
+       my $class       = shift;
+       my ($text, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$text){
+               die("The text given was blank.");
+       }       
+
+       if (!$style){
+               $style = "";
+       }
+
+       # Add some italic text.
+
+       if ($style ne ""){
+               $tagdata = $tagdata . "<span class=\"\">" . $class->convert($text, "content") . "</span>";              
+       } else {
+               $tagdata = $tagdata . "<i>" . $class->convert($text, "content") . "</i>";
+       }
+
+       # Append the tagdata to the pagedata.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addlinebreak{
+#################################################################################
+# addlinebreak: Adds a line break specific to the output format.               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addlinebreak();                                                 #
+#################################################################################
+
+       # Add a line break.
+
+       my $tagdata = "";
+
+       $tagdata = "<br>" . "\r\n";
+
+       # Append the tagdata to the pagedata.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub addhorizontalline{
+#################################################################################
+# addhorizontalline: Adds a horizontal line.                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->addhorizontalline();                                            #
+#################################################################################
+
+       # Add a horizontal line.
+
+       my $tagdata = "";
+       
+       $tagdata = "<hr>" . "\r\n";
+
+       # Append the tagdata to the pagedata.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+#################################################################################
+# Other.                                                                       #
+#################################################################################
+
+sub startlist{
+#################################################################################
+# startlist: Start a list.                                                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->startlist();                                                    #
+#################################################################################
+
+       # Start a list.
+
+       my $tagdata = "";
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "<ul>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+       $tablevel++;
+
+}
+
+sub additem{
+#################################################################################
+# additem: Adds an item to the list.                                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule->additem(text, options);                                         #
+#                                                                              #
+# text         Specifies the text to use for the item.                         #
+# options      Specifies the following options (in any order).                 #
+#                                                                              #
+# Style                Specifies the CSS style to use.                                 #
+#################################################################################
+
+        # Get the options recieved.
+
+       my $class       = shift;
+       my ($text, $options) = @_;
+
+       my $tagdata     = "";
+       my $tabcount    = $tablevel;
+
+       # Get certain values from the hash.
+
+       my $style       = $options->{'Style'};
+
+       # Check if certain values are undefined and if they
+       # are then set them blank or to a default value.
+
+       if (!$text){
+               die("The text given was blank.");
+       }
+
+       if (!$style){
+               $style = "";
+       }
+
+       # Add an item to the list.
+
+       $tagdata = $tagdata . "<li ";
+
+       if ($style ne ""){
+               $tagdata = $tagdata . " class=\"" . $class->convert($style, "content") . "\"";
+       }
+
+       $tagdata = $tagdata . ">" . $class->convert($text, "content");
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+sub endlist{
+#################################################################################
+# endlist: End a list.                                                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# $presmodule-endlist();                                                       #
+#################################################################################
+
+       # End a list.
+
+       my $tagdata = "";
+       $tablevel = ($tablevel - 1);
+       my $tabcount = $tablevel;
+
+       while ($tabcount > 0){
+               $tagdata = $tagdata . "\t";
+               $tabcount = $tabcount - 1;
+       }
+
+       $tagdata = $tagdata . "</ul>" . "\r\n";
+
+       # Append the tag data to the page data.
+
+       $pagedata = $pagedata . $tagdata;
+
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/System/Auth.pm b/cgi-files/Modules/System/Auth.pm
new file mode 100644 (file)
index 0000000..056934b
--- /dev/null
@@ -0,0 +1,123 @@
+#################################################################################
+# Xestia Scanner Server - Auth System Module                                   #
+# Version 0.1.0                                                                        #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+package Modules::System::Auth;
+
+use Modules::System::Common;
+use strict;
+use warnings;
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(xestiascan_auth_authenticate xestiascan_auth_logout);
+
+sub xestiascan_auth_authenticate{
+#################################################################################
+# xestiascan_auth_authenticate: Provides a form for authentication.            #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_auth_authenticate(authfailure);                                   #
+#                                                                              #
+# authfailure  Display authentication failure message.                         #
+#################################################################################
+       
+       my $authfailure = shift;
+       
+       $authfailure = 0 if !$authfailure;
+       
+       if ($authfailure eq 1){
+       
+               $main::xestiascan_presmodule->startbox("errorsectionbox");
+               $main::xestiascan_presmodule->startbox("errorboxheader");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("errorbox");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{loginerror});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();         
+               
+       }
+       
+       $main::xestiascan_presmodule->startbox("sectionbox");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{login});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");
+       
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "auth");
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{username});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("username", { Size => 32, MaxLength => 32 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{password});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("password", { Size => 64, MaxLength => 128, Password => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{common}{options});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addcheckbox("stayloggedin", { OptionDescription => $main::xestiascan_lang{auth}{keeploggedin} });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow(); 
+       $main::xestiascan_presmodule->endtable();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{auth}{loginbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{clearvalues});
+       $main::xestiascan_presmodule->endform();
+       
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
+
+sub xestiascan_auth_logout{
+#################################################################################
+# xestiascan_auth_logout: Logout of the Xestia Scanner Server installation.    #
+#################################################################################
+       
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{loggedout}, { Style => "pageheader" });
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{auth}{loggedoutmsg});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}, { Text => $main::xestiascan_lang{auth}{displaylogin} });
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
\ No newline at end of file
diff --git a/cgi-files/Modules/System/Common.pm b/cgi-files/Modules/System/Common.pm
new file mode 100644 (file)
index 0000000..e36775f
--- /dev/null
@@ -0,0 +1,1973 @@
+#################################################################################
+# Xestia Scanner Server - Common System Module                                 #
+# Version 0.1.0                                                                        #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+package Modules::System::Common;
+
+use strict;
+use warnings;
+use Exporter;
+use CGI::Lite;
+use MIME::Base64 qw(encode_base64url);
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(xestiascan_initialise xestiascan_settings_load xestiascan_fileexists xestiascan_filepermissions xestiascan_output_header xestiascan_output_page xestiascan_variablecheck xestiascan_processconfig xestiascan_processfilename xestiascan_utf8convert xestiascan_language xestiascan_error);
+
+sub xestiascan_initialise{
+#################################################################################
+# xestiascan_initialise: Get the enviroment stuff.                             #
+#################################################################################
+
+       # Get the script filename.
+
+       my $env_script_name = $ENV{'SCRIPT_NAME'};
+
+       # Process the script filename until there is only the
+       # filename itself.
+
+       my $env_script_name_length = length($env_script_name);
+       my $filename_seek = 0;
+       my $filename_char = "";
+       my $filename_last = 0;
+
+       do {
+               $filename_char = substr($env_script_name, $filename_seek, 1);
+               if ($filename_char eq "/"){
+                       $filename_last = $filename_seek + 1;
+               }
+               $filename_seek++;
+       } until ($filename_seek eq $env_script_name_length || $env_script_name_length eq 0);
+
+       my $env_script_name_finallength = $env_script_name_length - $filename_last;
+       my $script_filename = substr($env_script_name, $filename_last, $env_script_name_finallength);
+
+       # Setup the needed enviroment variables for Xestia Scanner Server.
+
+       %main::xestiascan_env = (
+               "script_filename" => $script_filename,
+       );
+
+}
+
+sub xestiascan_settings_load{
+#################################################################################
+# xestiascan_settings_load: Load the configuration settings into the global    #
+# variables.                                                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_settings_load();                                                  #
+#################################################################################
+
+       # Check if the Xestia Scanner Server configuration file exists before 
+       # using it and return an critical error if it doesn't exist.
+
+       my ($xestiascan_settingsfilehandle, @config_data, %config, $config);
+       my $xestiascan_conf_exist = xestiascan_fileexists("xsdss.cfg");
+
+       if ($xestiascan_conf_exist eq 1){
+
+               # The configuration really does not exist so return an critical error.
+
+               xestiascan_critical("configfilemissing");
+
+       }
+
+       # Check if the Xestia Scanner Server configuration file has valid permission 
+       # settings before using it and return an critical error if it doesn't have the
+       # valid permission settings.
+
+       my $xestiascan_conf_permissions = xestiascan_filepermissions("xsdss.cfg", 1, 0);
+
+       if ($xestiascan_conf_permissions eq 1){
+
+               # The permission settings for the Xestia Scanner Server configuration 
+               # file are invalid, so return an critical error.
+
+               xestiascan_critical("configfileinvalidpermissions");
+
+       }
+
+       # Converts the file into meaningful data for later on in this subroutine.
+
+       my $xestiascan_conf_file = 'xsdss.cfg';
+
+       open($xestiascan_settingsfilehandle, $xestiascan_conf_file);
+       binmode $xestiascan_settingsfilehandle, ':utf8';
+       @config_data = <$xestiascan_settingsfilehandle>;
+       %config = xestiascan_processconfig(@config_data);
+       close($xestiascan_settingsfilehandle);
+
+       # Go and fetch the settings and place them into a hash (that is global).
+
+       %main::xestiascan_config = (
+
+               "directory_noncgi_images"       => $config{config}{directory_noncgi_images},
+               "directory_noncgi_scans"        => $config{config}{directory_noncgi_scans},
+               "directory_fs_scans"            => $config{config}{directory_fs_scans},
+
+               "system_language"               => $config{config}{system_language},
+               "system_presmodule"             => $config{config}{system_presmodule},
+               "system_authmodule"             => $config{config}{system_authmodule},
+               "system_outputmodule"           => $config{config}{system_outputmodule},
+               "system_datetime"               => $config{config}{system_datetime},
+
+               "database_server"               => $config{config}{database_server},
+               "database_port"                 => $config{config}{database_port},
+               "database_protocol"             => $config{config}{database_protocol},
+               "database_sqldatabase"          => $config{config}{database_sqldatabase},
+               "database_username"             => $config{config}{database_username},
+               "database_password"             => $config{config}{database_password},
+               "database_tableprefix"          => $config{config}{database_tableprefix}
+
+       );
+
+       # Do a validation check on all of the variables that were loaded into the global configuration hash.
+
+       xestiascan_variablecheck($main::xestiascan_config{"directory_noncgi_images"}, "maxlength", 512, 0);
+       xestiascan_variablecheck($main::xestiascan_config{"directory_noncgi_scans"}, "maxlength", 512, 0);
+       
+       xestiascan_variablecheck($main::xestiascan_config{"directory_fs_scans"}, "maxlength", 4096, 0);
+
+       my $xestiascan_config_language_filename = xestiascan_variablecheck($main::xestiascan_config{"system_language"}, "language_filename", "", 1);
+       my $xestiascan_config_presmodule_filename = xestiascan_variablecheck($main::xestiascan_config{"system_presmodule"}, "module", 0, 1);
+       my $xestiascan_config_authmodule_filename = xestiascan_variablecheck($main::xestiascan_config{"system_authmodule"}, "module", 0, 1);
+       # Check if the language filename is valid and return an critical error if
+       # they aren't.
+
+       if ($xestiascan_config_language_filename eq 1){
+
+               # The language filename is blank so return an critical error.
+
+               xestiascan_critical("languagefilenameblank");
+
+       } elsif ($xestiascan_config_language_filename eq 2){
+
+               # The language filename is invalid so return an critical error.
+
+               xestiascan_critical("languagefilenameinvalid");
+
+       }
+
+       # Check if the presentation and database module names are valid and return a critical
+       # error if they aren't.
+
+       if ($xestiascan_config_presmodule_filename eq 1){
+
+               # The presentation module filename given is blank so return an 
+               # critical error.
+
+               xestiascan_critical("presmoduleblank");
+
+       }
+
+       if ($xestiascan_config_presmodule_filename eq 2){
+
+               # The presentation module filename is invalid so return an
+               # critical error.
+
+               xestiascan_critical("presmoduleinvalid");
+
+       }
+
+       if ($xestiascan_config_authmodule_filename eq 1){
+
+               # The database module filename given is blank so return an
+               # critical error.
+
+               xestiascan_critical("authmoduleblank");
+
+       }
+
+       if ($xestiascan_config_authmodule_filename eq 2){
+
+               # The database module filename given is invalid so return
+               # an critical error.
+
+               xestiascan_critical("authmoduleinvalid");
+
+       }
+
+       # Check if the language file does exist before loading it and return an critical error
+       # if it does not exist.
+
+       my $xestiascan_config_language_fileexists = xestiascan_fileexists("lang/" . $main::xestiascan_config{"system_language"} . ".lang");
+
+       if ($xestiascan_config_language_fileexists eq 1){
+
+               # Language file does not exist so return an critical error.
+
+               xestiascan_critical("languagefilemissing");
+
+       }
+
+       # Check if the language file has valid permission settings and return an critical error if
+       # the language file has invalid permissions settings.
+
+       my $xestiascan_config_language_filepermissions = xestiascan_filepermissions("lang/" . $main::xestiascan_config{"system_language"} . ".lang", 1, 0);
+
+       if ($xestiascan_config_language_filepermissions eq 1){
+
+               # Language file contains invalid permissions so return an critical error.
+
+               xestiascan_critical("languagefilenameinvalidpermissions");
+
+       }
+
+       # Load the language file.
+
+       my ($xestiascan_languagefilehandle, @lang_data);
+
+       open($xestiascan_languagefilehandle, "lang/" . $main::xestiascan_config{"system_language"} . ".lang");
+       @lang_data = <$xestiascan_languagefilehandle>;
+       %main::xestiascan_lang = xestiascan_processconfig(@lang_data);
+       close($xestiascan_languagefilehandle);
+
+       # Check if the presentation module does exist before loading it and return an critical error
+       # if the presentation module does not exist.
+
+       my $xestiascan_config_presmodule_fileexists = xestiascan_fileexists("Modules/Presentation/" . $main::xestiascan_config{"system_presmodule"} . ".pm");
+
+       if ($xestiascan_config_presmodule_fileexists eq 1){
+
+               # Presentation module does not exist so return an critical error.
+
+               xestiascan_critical("presmodulemissing");
+
+       }
+
+       # Check if the presentation module does have the valid permission settings and return a
+       # critical error if the presentation module contains invalid permission settings.
+
+       my $xestiascan_config_presmodule_permissions = xestiascan_filepermissions("Modules/Presentation/" . $main::xestiascan_config{"system_presmodule"} . ".pm", 1, 0);
+
+       if ($xestiascan_config_presmodule_permissions eq 1){
+
+               # Presentation module contains invalid permissions so return an critical error.
+
+               xestiascan_critical("presmoduleinvalidpermissions");
+
+       }
+
+       # Check if the database module does exist before loading it and return an critical error
+       # if the database module does not exist.
+
+       my $xestiascan_config_authmodule_fileexists = xestiascan_fileexists("Modules/Auth/" . $main::xestiascan_config{"system_authmodule"} . ".pm");
+
+       if ($xestiascan_config_authmodule_fileexists eq 1){
+
+               # Database module does not exist so return an critical error.
+
+               xestiascan_critical("authmodulemissing");
+
+       }
+
+       # Check if the database module does have the valid permission settings and return an
+       # critical error if the database module contains invalid permission settings.
+
+       my $xestiascan_config_authmodule_permissions = xestiascan_filepermissions("Modules/Auth/" . $main::xestiascan_config{"system_authmodule"} . ".pm", 1, 0);
+
+       if ($xestiascan_config_authmodule_permissions eq 1){
+
+               # Presentation module contains invalid permissions so return an critical error.
+
+               xestiascan_critical("authmoduleinvalidpermissions");
+
+       }
+
+       # Include the Modules directory.
+
+       use lib "Modules/";
+
+       # Load the presentation module.
+
+       my $presmodulename = "Presentation::" . $main::xestiascan_config{"system_presmodule"};
+       ($presmodulename) = $presmodulename =~ m/^(.*)$/g; # CHECK THIS!!
+       eval "use " . $presmodulename;
+       $presmodulename = "Modules::Presentation::" . $main::xestiascan_config{"system_presmodule"};
+       $main::xestiascan_presmodule = $presmodulename->new();
+       $main::xestiascan_presmodule->clear(); 
+
+       # Load the database module.
+       my $dbmodulename = "Auth::" . $main::xestiascan_config{"system_authmodule"};
+       ($dbmodulename) = $dbmodulename =~ m/^(.*)$/g; # CHECK THIS!!
+       eval "use " . $dbmodulename;
+       $dbmodulename = "Modules::Auth::" . $main::xestiascan_config{"system_authmodule"};
+       $main::xestiascan_authmodule = $dbmodulename->new();
+
+       # Load the following settings to the database module.
+
+       $main::xestiascan_authmodule->loadsettings({ DateTime => $main::xestiascan_config{"system_datetime"}, Server => $main::xestiascan_config{"database_server"}, Port => $main::xestiascan_config{"database_port"}, Protocol => $main::xestiascan_config{"database_protocol"}, Database => $main::xestiascan_config{"database_sqldatabase"}, Username => $main::xestiascan_config{"database_username"}, Password => $main::xestiascan_config{"database_password"}, TablePrefix => $main::xestiascan_config{"database_tableprefix"} });
+
+       return;
+
+}
+
+sub xestiascan_language{
+#################################################################################
+# xestiascan_language: Process language strings that needs certain text                #
+#                      inserted.                                               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_language(string, [text, text, ...]);                              #
+#                                                                              #
+# string       Specifies the string to process.                                #
+# text         Specifies the text to pass to the string (can be repeated many  #
+#              times).                                                         #
+#################################################################################
+
+        my $string = shift;
+        my $item;
+
+        foreach $item (@_){
+
+                $string =~ s/%s/$item/;
+
+        }
+
+        return $string;
+
+}
+
+sub xestiascan_error{
+#################################################################################
+# xestiascan_error: Prints out an error message.                               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_error(errortype, errorext);                                       #
+#                                                                              #
+# errortype    Specifies the type of error that occured.                       #
+# errorext     Specifies the extended error information.                       #
+#################################################################################
+
+       # Get the error type from the subroutine.
+
+       my ($error_type, $error_extended) = @_;
+
+       # Disconnect from the database server.
+
+       if ($main::xestiascan_authmodule){
+               $main::xestiascan_authmodule->disconnect();
+       }
+
+       # Load the list of error messages.
+
+       my @xestiascan_error = (
+
+               # Catch all error message.
+               "generic", 
+
+               # Standard error messages.
+               "blankfilename", "blankvariable", "fileexists", "internalerror", "invalidoption", "invalidaction", "invalidfilename", "invalidmode", "invalidutf8", "invalidvariable", "variabletoolong",
+
+               # Specific error messages.
+               "authconnectionerror", "autherror", "authmoduleblank", "authmoduleinvalid", "authmodulemissing",
+               "blankdatetimeformat", "blankdirectory", "blankpictureid", "bottomrightx",
+               "bottomrightxinvalidnumber", "bottomrighty", "bottomrightyinvalidnumber", "brightnessblank",
+               "brightnessinvalidnumber", "colourblank", "colourinvalidoption", "invaliddatetimeformat",
+               "invaliddirectory", "invalidpictureid", "languagefilenamemissing", "moduleinvalid",
+               "nametoolong", "notpermitted", "outputmoduleblank", "outputmoduleinvalid",
+               "passwordblank", "passwordsdonotmatch", "passwordtoolong", "permissiontypeblank", "presmoduleblank",
+               "presmoduleinvalid", "presmodulemissing", "resolutionblank", "resolutioninvalidnumber",
+               "rotateblank", "rotateinvalidoption", "scannererror", "serverdatabasenameinvalid",
+               "serverdatabasenametoolong", "serverdatabasepasswordtoolong", "serverdatabasetableprefixinvalid", "serverdatabasetableprefixtoolong",
+               "serverdatabaseusernameinvalid", "serverdatabaseusernametoolong", "servernameinvalid", "servernametoolong",
+               "serverportnumberinvalid", "serverportnumberinvalidcharacters", "serverportnumbertoolong", "serverprotocolinvalid",
+               "serverprotocolnametoolong", "topleftxblank", "topleftxinvalidnumber", "topleftyblank", "topleftyinvalidnumber",
+               "userexists", "usernameblank", "usernametoolong", "variabletoolong"
+       
+       );
+
+       # Check if the error message name is a valid error message name
+       # and return the generic error message if it isn't.
+
+       my $error_string = "";
+
+       if (grep /^$error_type$/, @xestiascan_error){
+
+               # The error type is valid so get the error language string
+               # associated with this error messsage name.
+
+               $error_string = $main::xestiascan_lang{error}{$error_type};
+
+       } else {
+
+               # The error type is invalid so set the error language
+               # string using the generic error message name.
+
+               $error_string = $main::xestiascan_lang{error}{generic};
+
+       }
+
+       $main::xestiascan_presmodule->clear();
+
+       $main::xestiascan_presmodule->startbox("errorbox");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error}, { Style => "errorheader" });
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($error_string, { Style => "errortext" });
+
+       # Check to see if extended error information was passed.
+
+       if ($error_extended){
+
+               # Write the extended error information.
+
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{extendederror});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->startbox("datalist");
+               $main::xestiascan_presmodule->addtext($error_extended);
+               $main::xestiascan_presmodule->endbox();
+
+       }
+
+       $main::xestiascan_presmodule->endbox();
+
+       my $menulist = "";
+       
+       if ($main::successful_auth eq 1){
+               
+               $menulist = "standard";
+               
+       } else {
+       
+               $menulist = "none";
+               
+       }
+       
+       &xestiascan_output_header;
+       xestiascan_output_page($main::xestiascan_lang{error}{error}, $main::xestiascan_presmodule->grab(), $menulist);
+
+       exit;
+
+}
+
+sub xestiascan_fileexists{
+#################################################################################
+# xestiascan_fileexists: Check if a file exists and returns a value depending on #
+# if the file exists or not.                                                   #
+#                                                                              # 
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_fileexists(filename);                                             #
+#                                                                              #
+# filename     Specifies the file name to check if it exists or not.           #
+#################################################################################
+
+       # Get the value that was passed to the subroutine.
+
+       my ($filename) = @_;
+
+       # Check if the filename exists, if it does, return a value of 0, else
+       # return a value of 1, meaning that the file was not found.
+
+       if (-e $filename){
+
+               # Specified file does exist so return a value of 0.
+
+               return 0;
+
+       } else {
+
+               # Specified file does not exist so return a value of 1.
+
+               return 1;
+
+       }
+
+}
+
+sub xestiascan_filepermissions{
+#################################################################################
+# xestiascan_filepermissions: Check if the file permissions of a file and return #
+# either a 1 saying that the permissions are valid or return a 0 saying that   #
+# the permissions are invalid.                                                 #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_filepermissions(filename, [read], [write], [filemissingskip]);    #
+#                                                                              #
+# filename             Specifies the filename to check for permissions.        #
+# read                 Preform check that the file is readable.                #
+# write                        Preform check that the file is writeable.               #
+# filemissingskip      Skip the check of seeing if it can read or write if the #
+#                      file is missing.                                        #
+#################################################################################
+
+       # Get the values that was passed to the subroutine.
+
+       my ($filename, $readpermission, $writepermission, $ignorechecks) = @_;
+
+       # Check to make sure that the read permission and write permission values
+       # are only 1 character long.
+
+       xestiascan_variablecheck($readpermission, "maxlength", 1, 0);
+       xestiascan_variablecheck($writepermission, "maxlength", 1, 0);
+       xestiascan_variablecheck($ignorechecks, "maxlength", 1, 0);
+
+       my $ignorechecks_result = 0;
+
+       # Check if the file should be ignored for read and write checking if 
+       # it doesn't exist.
+
+       if ($ignorechecks){
+
+               if (-e $filename){
+
+                       # The file exists so the checks are to be done.
+
+                       $ignorechecks_result = 0;
+
+               } else {
+
+                       # The file does not exist so the checks don't need to
+                       # be done to prevent false positives.
+
+                       $ignorechecks_result = 1;
+
+               }
+
+       } else {
+
+               $ignorechecks_result = 0;
+
+       }
+
+       # Check if the file should be checked to see if it can be read.
+
+       if ($readpermission && $ignorechecks_result eq 0){
+
+               # The file should be checked to see if it does contain read permissions
+               # and return a 0 if it is invalid.
+
+               if (-r $filename){
+
+                       # The file is readable, so do nothing.
+
+               } else {
+
+                       # The file is not readable, so return 1.
+
+                       return 1;
+
+               }
+
+       }
+
+       # Check if the file should be checked to see if it can be written.
+
+       if ($writepermission && $ignorechecks_result eq 0){
+
+               # The file should be checked to see if it does contain write permissions
+               # and return a 0 if it is invalid.
+
+               if (-w $filename){
+
+                       # The file is writeable, so do nothing.
+
+               } else {
+
+                       # The file is not writeable, so return 1.
+
+                       return 1;
+
+               }
+
+       }
+
+       # No problems have occured, so return 0.
+
+       return 0;
+
+}
+
+sub xestiascan_utf8convert{
+#################################################################################
+# xestiascan_utf8convert: Properly converts values into UTF-8 values.          #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# utfstring    # The UTF-8 string to convert.                                  #
+#################################################################################
+
+       # Get the values passed to the subroutine.
+
+       my ($utfstring) = @_;
+
+       # Load the Encode perl module.
+
+       use Encode qw(decode_utf8 encode_utf8);
+
+       # Convert the string.
+
+       my $finalutf8 = Encode::decode_utf8( $utfstring );
+
+       return $finalutf8;
+       #return $utfstring;
+
+}
+
+sub xestiascan_critical{
+#################################################################################
+# xestiascan_critical: Displays an critical error message that cannot be               #
+# normally by the xestiascan_error subroutine.                                 #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# errortype    Specifies the type of critical error that has occured.          #
+#################################################################################
+
+       # Get the value that was passed to the subroutine.
+
+       my ($error_type) = @_;
+
+       my %error_list;
+
+       # Get the error type from the errortype string.
+
+       %error_list = (
+
+               # Generic critical error message.
+
+               "generic"                       => "A critical error has occured but the error is not known to Xestia Scanner Server.",
+
+               # Specific critical error messages.
+
+               "configfilemissing"             => "The Xestia Scanner Server configuration file is missing! Running the installer script for Xestia Scanner Server is recommended.",
+               "configfileinvalidpermissions"  => "The Xestia Scanner Server configuration file has invalid permission settings set! Please set the valid permission settings for the configuration file.",
+               "authmoduleblank"               => "The authentication module name is blank! Running the installer script for Xestia Scanner Server is recommended.",
+               "authmodulemissing"             => "The authentication module is missing! Running the installer script for Xestia Scanner Server is recommended.",
+               "authmoduleinvalidpermissions"  => "The authentication module cannot be used as it has invalid permission settings set! Please set the valid permission settings for the configuration file.",
+               "authmoduleinvalid"             => "The authentication module name given is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "invalidvalue"                  => "An invalid value was passed.",
+               "languagefilenameblank"         => "The language filename given is blank! Running the installer script for Xestia Scanner Server is recommended.",
+               "languagefilenameinvalid"       => "The language filename given is invalid! Running the installer script for Xestia Scanner Server is recommended.",
+               "languagefilemissing"   => "The language filename given does not exist. Running the installer script for Xestia Scanner Server is recommended.",
+               "languagefilenameinvalidpermissions"    => "The language file with the filename given has invalid permissions set. Please set the valid permission settings for the language file.",
+               "presmodulemissing"             => "The presentation module is missing! Running the installer script for Xestia Scanner Server is recommended.",
+               "presmoduleinvalidpermissions"  => "The presentation module cannot be used as it has invalid permission settings set! Please set the valid permission settings for the presentation module.",
+               "presmoduleinvalid"             => "The presentation module name given is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "textarearowblank"              => "The text area row value given is blank. Running the installer script for Xestia Scanner Server is recommended.",
+               "textarearowtoolong"            => "The text area row value is too long. Running the installer script for Xestia Scanner Server is recommended.",
+               "textarearowinvalid"            => "The text area row value is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "textareacolblank"              => "The text area row value given is blank. Running the installer script for Xestia Scanner Server is recommended.",
+               "textareacoltoolong"            => "The text area column value is too long. Running the installer script for Xestia Scanner Server is recommended.",
+               "textareacolinvalid"            => "The text area column value is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "pagecountblank"                => "The page count value is blank. Running the installer script for Xestia Scanner Server is recommended.",
+               "templatecountblank"            => "The template count value is blank. Running the installer script for Xestia Scanner Server is recommended.",
+               "filtercountblank"              => "The filter count value is blank. Running the installer script for Xestia Scanner Server is recommended.",
+               "pagecounttoolong"              => "The page count value is too long. Running the installer script for Xestia Scanner Server is recommended.",
+               "templatecounttoolong"          => "The template count value is too long. Running the installer script for Xestia Scanner Server is recommended.",
+               "filtercounttoolong"            => "The filter count value is too long. Running the installer script for Xestia Scanner Server is recommended.",
+               "pagecountinvalid"              => "The page count value is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "templatecountinvalid"          => "The template count value is invalid. Running the installer script for Xestia Scanner Server is recommended.",
+               "filtercountinvalid"            => "The filter count is invalid. Running the installer script for Xestia Scanner Server is recommended."
+
+       );
+
+       if (!$error_list{$error_type}){
+
+               $error_type = "generic";
+
+       }
+
+       print "Content-Type: text/html; charset=utf-8;\r\n";
+       print "Expires: Sun, 01 Jan 2008 00:00:00 GMT\r\n\r\n";
+       print "Critical Error: " . $error_list{$error_type};
+       exit;
+
+}
+
+sub xestiascan_variablecheck{
+#################################################################################
+# xestiascan_variablecheck: Checks the variables for any invalid characters.   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_variablecheck(variable, type, length, noerror);                   #
+#                                                                              #
+# variable     Specifies the variable to be checked.                           #
+# type         Specifies what type the variable is.                            #
+# option       Specifies the maximum/minimum length of the variable            #
+#              (if minlength/maxlength is used) or if the filename should be   #
+#              checked to see if it is blank.                                  #
+# noerror      Specifies if Xestia Scanner Server should return an error       #
+#              or not on certain values.                                       #
+#################################################################################
+
+       # Get the values that were passed to the subroutine.
+
+       my ($variable_data, $variable_type, $variable_option, $variable_noerror) = @_;
+
+       if (!$variable_data){
+               $variable_data = "";
+       }
+
+       if (!$variable_type){
+               $variable_type = "";
+       }
+
+       if ($variable_type eq "numbers"){
+
+               # Check for numbers and return an error if there is anything else than numebrs.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated.
+               $variable_data_validated =~ tr/0-9//d;          # Take away all of the numbers and from the variable. 
+                                                               # If it only contains numbers then it should be blank.
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "decimal"){
+               
+               # Check for numbers and decimal and return an error if there is anything else than numebrs.
+               
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated.
+               $variable_data_validated =~ tr/0-9.//d;         # Take away all of the numbers and from the variable. 
+               # If it only contains numbers then it should be blank.
+               
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+                       
+                       if ($variable_noerror eq 1){
+                               
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+                               
+                               return 1;
+                               
+                       } elsif ($variable_noerror eq 0) {
+                               
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+                               
+                               xestiascan_error("invalidvariable");
+                               
+                       } else {
+                               
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+                               
+                               xestiascan_error("invalidvariable");
+                               
+                       }
+                       
+               }
+               
+               return 0;
+               
+       } elsif ($variable_type eq "lettersnumbers"){
+
+               # Check for letters and numbers and return an error if there is anything else other
+               # than letters and numbers.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated
+               $variable_data_validated =~ tr/a-zA-Z0-9.//d;
+               $variable_data_validated =~ s/\s//g;
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "maxlength"){
+               # Check for the length of the variable, return an error if it is longer than the length specified.
+
+               # Check if the variable_data string is blank, if it is then set the variable_data_length
+               # to '0'.
+
+               my $variable_data_length = 0;
+
+               if (!$variable_data){
+
+                       # Set variable_data_length to '0'.
+                       $variable_data_length = 0;
+
+               } else {
+
+                       # Get the length of the variable recieved.
+                       $variable_data_length = length($variable_data);
+
+               }
+
+
+
+               if ($variable_data_length > $variable_option){
+
+                       # The variable length is longer than it should be so check if
+                       # the no error value is set 1.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1, so return an
+                               # value of 1 (meaning tha the variable is
+                               # too long to be used).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0, so return
+                               # an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       }
+
+               } else {
+
+                       # The variable length is exactly or shorter than specified, so continue to end of this section where
+                       # the return function should be.
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "blank"){
+               # Check if the variable is blank and if it is blank, then return an error.
+
+               if (!$variable_data){
+
+                       # The variable data really is blank, so check what
+                       # the no error value is set.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1, so return
+                               # a value of 1 (saying that the variable was
+                               # blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0, so return
+                               # an error.
+
+                               xestiascan_error("blankvariable");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "filename"){
+               # Check for letters and numbers, if anything else than letters and numbers is there (including spaces) return
+               # an error.
+
+               # Check if the filename passed is blank, if it is then return with an error.
+
+               if ($variable_data eq ""){
+
+                       # The filename specified is blank, so check what the
+                       # noerror value is set.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the filename
+                               # was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankfilename");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               } else {
+
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9\.//d;
+
+               # Check if the validated data variable is blank, if it is 
+               # then continue to the end of this section where the return 
+               # function should be, otherwise return an error.
+
+               if ($variable_data_validated eq ""){
+
+                       # The validated data variable is blank, meaning that 
+                       # it only contained letters and numbers.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the filename
+                               # is invalid).
+
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("invalidfilename");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "filenameindir"){
+               # Check if the filename is in the directory and return an
+               # error if it isn't.
+
+               if ($variable_data eq ""){
+
+                       # The filename specified is blank, so check what the
+                       # noerror value is set.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the filename
+                               # was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankfilename");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               } else {
+
+
+               }
+
+               # Set the following variables for later on.
+
+               my $variable_data_length = 0;
+               my $variable_data_char = "";
+               my $variable_data_validated = "";
+               my $variable_data_seek = 0;
+               my $variable_database_list = "";
+               my $variable_database_listcurrent = "";
+               my $variable_data_firstlevel = 1;
+
+               # Get the length of the variable recieved.
+
+               $variable_data_length = length($variable_data);
+
+               # Check if the database filename contains the directory command
+               # for up a directory level and if it is, return an error
+               # or return with a number.
+
+               do {
+
+                       # Get a character from the filename passed to this subroutine.
+
+                       $variable_data_char = substr($variable_data, $variable_data_seek, 1);
+
+                       # Check if the current character is the forward slash character.
+
+                       if ($variable_data_char eq "/"){
+
+                               # Check if the current directory is blank (and on the first level), or if the
+                               # current directory contains two dots or one dot, if it does return an error.
+
+                               if ($variable_database_listcurrent eq "" && $variable_data_firstlevel eq 1 || $variable_database_listcurrent eq ".." || $variable_database_listcurrent eq "."){
+
+                                       # Check if the noerror value is set to 1, if it is return an
+                                       # number, else return an proper error.
+
+                                       if ($variable_noerror eq 1){
+
+                                               # Page filename contains invalid characters and
+                                               # the no error value is set to 1 so return a 
+                                               # value of 2 (meaning that the page filename
+                                               # is invalid).
+
+                                               return 2;
+
+                                       } elsif ($variable_noerror eq 0) {
+
+                                               # Page filename contains invalid characters and
+                                               # the no error value is set to 0 so return an
+                                               # error.
+
+                                               xestiascan_error("invalidfilename");
+
+                                       } else {
+
+                                               # The no error value is something else other
+                                               # than 0 or 1 so return an error.
+
+                                               xestiascan_error("invalidvariable");
+
+                                       }
+
+                               }
+
+                               # Append the forward slash, clear the current directory name and set
+                               # the first directory level value to 0.
+
+                               $variable_database_list = $variable_database_list . $variable_data_char;
+                               $variable_database_listcurrent = "";
+                               $variable_data_firstlevel = 0;
+
+                       } else {
+
+                               # Append the current character to the directory name and to the current
+                               # directory name.
+
+                               $variable_database_list = $variable_database_list . $variable_data_char;
+                               $variable_database_listcurrent = $variable_database_listcurrent . $variable_data_char;
+
+                       }
+
+                       # Increment the seek counter.
+
+                       $variable_data_seek++;
+
+               } until ($variable_data_seek eq $variable_data_length);
+
+               return 0;
+
+       } elsif ($variable_type eq "datetime"){
+               # Check if the date and time setting format is valid.
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the date and
+                               # time format was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankdatetimeformat");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr|dDmMyYhms/():[ ]||d;
+
+               if ($variable_data_validated eq ""){
+
+                       # The date and time format is valid. So
+                       # skip this bit.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the date and
+                               # time format was invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("invaliddatetimeformat");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "directory"){
+               # Check if the directory only contains letters and numbers and
+               # return an error if anything else appears.
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the directory
+                               # name was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankdirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               if ($variable_data_validated eq ""){
+
+                       # The validated data variable is blank, meaning that
+                       # it only contains letters and numbers.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the directory
+                               # name is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("invaliddirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "language_filename"){
+
+               # The variable type is a language filename type.
+               # Check if the language file name is blank and 
+               # if it is then return an error (or value).
+
+               if ($variable_data eq ""){
+
+                       # The language filename is blank so check the
+                       # no error value and return an error (or value).
+
+                       if ($variable_noerror eq 1){
+
+                               # Language filename is blank and the no error value
+                               # is set as 1, so return a value of 1 (saying that
+                               # the language filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Language filename is blank and the no error value
+                               # is not set as 1, so return an error.
+
+                               xestiascan_critical("languagefilenameblank");
+
+                       } else {
+
+                               # The noerror value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               # Set the following variables for later on.
+
+               my $variable_data_length = 0;
+               my $variable_data_char = "";
+               my $variable_data_seek = 0;
+
+               # Get the length of the language file name.
+
+               $variable_data_length = length($variable_data);
+
+               do {
+
+                       # Get a character from the language filename passed to this 
+                       # subroutine and the character the seek counter value is set
+                       # to.
+
+                       $variable_data_char = substr($variable_data, $variable_data_seek, 1);
+
+                       # Check if the language filename contains a forward slash or a dot, 
+                       # if the selected character is a forward slash then return an error
+                       # (or value).
+
+                       if ($variable_data_char eq "/" || $variable_data_char eq "."){
+
+                               # The language filename contains a forward slash or
+                               # a dot so depending on the no error value, return
+                               # an error or a value.
+
+                               if ($variable_noerror eq 1){
+
+                                       # Language filename contains a forward slash or a dot
+                                       # and the no error value has been set to 1, so return 
+                                       # an value of 2 (saying that the language file name is 
+                                       # invalid).
+
+                                       return 2;
+
+                               } elsif ($variable_noerror eq 0) {
+
+                                       # Language filename contains a forward slash and the no
+                                       # error value has not been set to 1, so return an error.
+
+                                       xestiascan_critical("languagefilenameinvalid");
+
+                               } else {
+
+                                       # The noerror value is something else other than
+                                       # 1 or 0 so return an error.
+
+                                       xestiascan_error("invalidvariable");
+
+                               }
+
+                       }
+
+                       # Increment the seek counter.
+
+                       $variable_data_seek++;
+
+               } until ($variable_data_seek eq $variable_data_length);
+
+               return 0;
+
+       } elsif ($variable_type eq "module"){
+
+               # The variable type is a presentation module filename.
+
+               # Check if the variable_data is blank and if it is
+               # return an error.
+
+               if ($variable_data eq ""){
+
+                       # The presentation module is blank so check if an error
+                       # value should be returned or a number should be
+                       # returned.
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name is blank and the no error value 
+                               # is set to 1 so return a value of 2 (meaning 
+                               # that the page filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains is blank and the no error 
+                               # value is set to 0 so return an error.
+
+                               xestiascan_critical("moduleblank");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_critical("invalidvalue");
+
+                       }
+
+               } else {
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data_validated eq ""){
+
+               } else {
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 1 so return a 
+                               # value of 2 (meaning that the page filename
+                               # is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 0 so return an
+                               # error.
+
+                               xestiascan_critical("moduleinvalid");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvalue");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "utf8"){
+
+               # The variable type is a UTF8 string.
+
+               if (!$variable_data){
+
+                       $variable_data = "";
+
+               }
+
+               my $chunk = 0;
+               my $process = 8192;
+               my $length = 0;
+               my $chunkdata = "";
+
+               while ($chunk < $length){
+
+                       $chunkdata = substr($variable_data, $chunk, $process);
+
+                       if ($chunkdata =~ m/\A(
+                               [\x09\x0A\x0D\x20-\x7E]            # ASCII
+                               | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
+                               |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
+                               | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
+                               |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
+                               |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
+                               | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
+                               |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
+                       )*\z/x){
+
+                               # The UTF-8 string is valid.
+       
+                       } else {
+       
+                               # The UTF-8 string is not valid, check if the no error
+                               # value is set to 1 and return an error if it isn't.
+       
+                               if ($variable_noerror eq 1){
+       
+                                       # The no error value has been set to 1, so return
+                                       # a value of 1 (meaning that the UTF-8 string is
+                                       # invalid).
+       
+                                       return 1; 
+       
+                               } elsif ($variable_noerror eq 0) {
+       
+                                       # The no error value has been set to 0, so return
+                                       # an error.
+       
+                                       xestiascan_error("invalidutf8");
+       
+                               } else {
+       
+                                       # The no error value is something else other than 0
+                                       # or 1, so return an error.
+       
+                                       xestiascan_error("invalidoption");
+       
+                               }
+       
+                       }
+
+
+                       $chunk = $chunk + $process;
+
+               }
+
+#              # Check if the string is a valid UTF8 string.
+# 
+#              if ($variable_data =~ m/^(
+#                      [\x09\x0A\x0D\x20-\x7E]              # ASCII
+#                      | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
+#                      |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
+#                      | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
+#                      |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
+#                      |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
+#                      | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
+#                      |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
+#              )*$/x){
+# 
+#                      # The UTF-8 string is valid.
+# 
+#              } else {
+# 
+#                      # The UTF-8 string is not valid, check if the no error
+#                      # value is set to 1 and return an error if it isn't.
+# 
+#                      if ($variable_noerror eq 1){
+# 
+#                              # The no error value has been set to 1, so return
+#                              # a value of 1 (meaning that the UTF-8 string is
+#                              # invalid).
+# 
+#                              return 1; 
+# 
+#                      } elsif ($variable_noerror eq 0) {
+# 
+#                              # The no error value has been set to 0, so return
+#                              # an error.
+# 
+#                              xestiascan_error("invalidutf8");
+# 
+#                      } else {
+# 
+#                              # The no error value is something else other than 0
+#                              # or 1, so return an error.
+# 
+#                              xestiascan_error("invalidoption");
+# 
+#                      }
+# 
+#              }
+
+               return 0;
+
+       } elsif ($variable_type eq "serverprotocol"){
+
+               # Check if the server protocol is TCP or UDP and return
+               # an error if it isn't.
+
+               if ($variable_data ne "tcp" && $variable_data ne "udp"){
+
+                       # The protocol given is not valid, check if the no
+                       # error value is set to 1 and return an error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the server protocol is
+                               # invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverprotocolinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "port"){
+
+               # Check if the port number given is less than 0 or more than 65535
+               # and return an error if it is.
+
+               if ($variable_data < 0 || $variable_data > 65535){
+
+                       # The port number is less than 0 and more than 65535 so
+                       # check if the no error value is set to 1 and return an
+                       # error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the port number is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverportnumberinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       }
+
+       # Another type than the valid ones above has been specified so return an error specifying an invalid option.
+       xestiascan_error("invalidoption");
+
+}
+
+sub xestiascan_output_header{
+#################################################################################
+# xestiascan_output_header: Outputs the header to the browser/stdout/console.  #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_output_header(username, seed, expires);                           #
+#################################################################################
+
+       my $headertype = shift;
+       
+       # Print a header saying that the page expires immediately since the
+       # date is set in the past.
+       
+       $headertype = "none" if !$headertype;
+       
+       if ($headertype eq "cookie"){
+       
+               my $username = shift;
+               my $seed = shift;
+               my $expires = shift;
+       
+               if (!$expires){
+               
+                       $expires = 0;
+                       
+               }
+               
+               # Get the date and time information.
+               
+               my ($exp_sec, $exp_min, $exp_hour, $exp_mday, $exp_mon, $exp_year, $exp_wday, $exp_yday, $exp_isdst) = localtime(time + $expires);
+               
+               my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+               my @weekday = qw(Sun Mon Tue Wed Thu Fri Sat);
+       
+               $exp_sec        = "0" . $exp_sec if $exp_sec < 10;
+               $exp_min        = "0" . $exp_min if $exp_min < 10;
+               $exp_hour       = "0" . $exp_hour if $exp_hour < 10;
+               $exp_mday       = "0" . $exp_mday if $exp_mday < 10;
+               $exp_mon        = "0" . $exp_mon if $exp_mon < 10;
+
+               my $expires_time = $weekday[$exp_wday] . ", " . $exp_mday . "-" . $month[$exp_mon]  . "-" . ($exp_year + 1900) . " " . $exp_hour . ":" . $exp_min . ":" . $exp_sec . " GMT";
+               
+               # Print out the cookies.
+               
+               print "Set-Cookie: " . $main::xestiascan_config{'database_tableprefix'} . "_auth_seed=" . $seed . "; expires="  . $expires_time ."\r\n";
+               print "Set-Cookie: " . $main::xestiascan_config{'database_tableprefix'} . "_auth_username=" . encode_base64url($username) . "; expires="  . $expires_time ."\r\n";              
+               
+       } elsif ($headertype eq "cookie_logout") {
+
+               # Get the date and time information.
+               
+               my ($exp_sec, $exp_min, $exp_hour, $exp_mday, $exp_mon, $exp_year, $exp_wday, $exp_yday, $exp_isdst) = localtime(time - 100);
+               
+               my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+               my @weekday = qw(Sun Mon Tue Wed Thu Fri Sat);
+               
+               $exp_sec        = "0" . $exp_sec if $exp_sec < 10;
+               $exp_min        = "0" . $exp_min if $exp_min < 10;
+               $exp_hour       = "0" . $exp_hour if $exp_hour < 10;
+               $exp_mday       = "0" . $exp_mday if $exp_mday < 10;
+               $exp_mon        = "0" . $exp_mon if $exp_mon < 10;
+               
+               my $expires_time = $weekday[$exp_wday] . ", " . $exp_mday . "-" . $month[$exp_mon]  . "-" . ($exp_year + 1900) . " " . $exp_hour . ":" . $exp_min . ":" . $exp_sec . " GMT";
+               
+               print "Set-Cookie: " . $main::xestiascan_config{'database_tableprefix'} . "_auth_seed=; expires="  . $expires_time ."\r\n";
+               print "Set-Cookie: " . $main::xestiascan_config{'database_tableprefix'} . "_auth_username=; expires="  . $expires_time ."\r\n";                         
+               
+       }
+
+       #print "Set-Cookie: seed=$seed:username=" . $username . "; expires=" . $weekday[$exp_wday] . " " . $exp_mday . "-" . $month[$exp_mon] . "-" . ($exp_year + 1900) . " " . $exp_hour . ":" . $exp_min . ":" . $exp_sec . " GMT\r\n";
+
+       print "Content-Type: text/html; charset=utf-8\r\n";
+       print "Expires: Sun, 01 Jan 2007 00:00:00 GMT\r\n\r\n";
+       
+       return;
+       
+}
+
+sub xestiascan_processfilename{
+#################################################################################
+# xestiascan_processfilename: Processes a name and turns it into a filename that#
+# can be used by Xestia Scanner Server.                                                #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_processfilename(text);                                            #
+#                                                                              #
+# text         Specifies the text to be used in the process for creating a new #
+#              filename.                                                       #
+#################################################################################
+
+       # Get the values that have been passed to the subroutine.
+
+       my ($process_text) = @_;
+
+       # Define some variables that will be used later on.
+
+       my $processed_stageone  = "";
+       my $processed_stagetwo  = "";
+       my $processed_length    = "";
+       my $processed_char      = "";
+       my $processed_seek      = 0;
+       my $processed_filename  = "";
+
+       # Set the first stage value of the processed filename to the
+       # process filename and then filter it out to only contain
+       # numbers and letters (no spaces) and then convert the
+       # capitals to small letters.
+
+       $processed_stageone = $process_text;
+       $processed_stageone =~ tr#a-zA-Z0-9##cd;
+       $processed_stageone =~ tr/A-Z/a-z/;
+
+       # Now set the second stage value of the processed filename
+       # to the first stage value of the processed filename and
+       # then limit the filename down to 32 characters.
+
+       $processed_stagetwo = $processed_stageone;
+       $processed_length = length($processed_stagetwo);
+
+       # Process the second stage filename into the final 
+       # filename and do so until the seek counter is 32
+       # or reaches the length of the second stage filename.
+
+       do {
+
+               # Get the character that is the seek counter
+               # is set at.
+
+               $processed_char = substr($processed_stagetwo, $processed_seek, 1);
+
+               # Append to the final processed filename.
+
+               $processed_filename = $processed_filename . $processed_char;
+
+               # Increment the seek counter.
+
+               $processed_seek++;
+
+       } until ($processed_seek eq 32 || $processed_seek eq $processed_length);
+
+       return $processed_filename;
+
+}
+
+
+sub xestiascan_processconfig{
+#################################################################################
+# xestiascan_processconfig: Processes an INI style configuration file.         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_processconfig(data);                                              #
+#                                                                              #
+# data Specifies the data to process.                                          #
+#################################################################################
+
+       my (@settings) = @_;
+
+       my ($settings_line, %settings, $settings, $sectionname, $setting_name, $setting_value);
+
+       foreach $settings_line (@settings){
+
+               next if !$settings_line;
+
+               # Check if the first character is a bracket.
+
+               if (substr($settings_line, 0, 1) eq "["){
+                       $settings_line =~ s/\[//;
+                       $settings_line =~ s/\](.*)//;
+                       $settings_line =~ s/\n//;
+                       $sectionname = $settings_line;
+                       next;
+               }
+
+               $setting_name  = $settings_line;
+               $setting_value = $settings_line;
+               $setting_name  =~ s/\=(.*)//;
+               $setting_name  =~ s/\n//;
+               $setting_value =~ s/(.*)\=//;
+               $setting_value =~ s/\n//;
+
+               # Remove the spacing before and after the '=' sign.
+
+               $setting_name =~ s/\s+$//;
+               $setting_value =~ s/^\s+//;
+               $setting_value =~ s/\r//;
+
+               $settings{$sectionname}{$setting_name} = $setting_value;
+
+       }
+
+       return %settings;
+
+}
+
+sub xestiascan_output_page{
+#################################################################################
+# xestiascan_output_page: Outputs the page to the browser/stdout/console.      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_output_page(pagetitle, pagedata, menutype);                       #
+#                                                                              #
+# pagetitle    Specifies the page title.                                       #
+# pagedata     Specifies the page data.                                        #
+# menutype     Prints out which menu to use.                                   #
+#################################################################################
+
+       my ($pagetitle, $pagedata, $menutype) = @_;
+
+       # Open the script page template and load it into the scriptpage variable,
+       # while declaring the variable.
+
+       open (my $filehandle_scriptpage, "<:utf8", 'page.html');
+       my @scriptpage = <$filehandle_scriptpage>;
+       binmode $filehandle_scriptpage, ':utf8';
+       close ($filehandle_scriptpage);
+
+       my $query_lite = new CGI::Lite;
+       my $form_data = $query_lite->parse_form_data;   
+
+       # Define the variables required.
+
+       my $scriptpageline = "";
+       my $pageoutput = "";
+
+       $main::xestiascan_presmodule->clear();
+
+       # Print out the main menu for Xestia Scanner Server.
+
+       if ($menutype ne "none"){
+       
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{'script_filename'} . "?mode=scan", { Text => $main::xestiascan_lang{menu}{scanconfig} });
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{'script_filename'} . "?mode=users", { Text => $main::xestiascan_lang{menu}{userconfig} });
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{'script_filename'} . "?mode=settings", { Text => $main::xestiascan_lang{menu}{settingsconfig} });
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{'script_filename'} . "?mode=logout", { Text => $main::xestiascan_lang{menu}{logout} });
+
+               $main::xestiascan_presmodule->addlinebreak();
+               
+       }
+
+       my $menuoutput = $main::xestiascan_presmodule->grab();
+
+       # Find <xestiascan> tages and replace with the apporiate variables.
+
+       foreach $scriptpageline (@scriptpage){
+
+               $scriptpageline =~ s/<xestiascan:menu>/$menuoutput/g;
+               $scriptpageline =~ s/<xestiascan:imagespath>/$main::xestiascan_config{"directory_noncgi_images"}/g;
+               $scriptpageline =~ s/<xestiascan:pagedata>/$pagedata/g;
+
+               # Check if page title specified is blank, otherwise add a page title
+               # to the title.
+
+               if (!$pagetitle || $pagetitle eq ""){
+                       $scriptpageline =~ s/<xestiascan:title>//g;
+               } else {
+                       $scriptpageline =~ s/<xestiascan:title>/ ($pagetitle)/g;
+               }
+
+               
+
+               # Append processed line to the pageoutput variable.
+
+               $pageoutput = $pageoutput . $scriptpageline;
+
+       }
+
+       print $pageoutput;
+
+       return;
+
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/System/Scan.pm b/cgi-files/Modules/System/Scan.pm
new file mode 100644 (file)
index 0000000..92a5259
--- /dev/null
@@ -0,0 +1,1828 @@
+#################################################################################
+# Xestia Scanner Server - Scan System Module                                   #
+# Version 0.1.0                                                                        #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+package Modules::System::Scan;
+
+use Modules::System::Common;
+use strict;
+use warnings;
+use Exporter;
+use Tie::IxHash;
+use Hash::Search;
+use Sane;
+use Image::Magick;
+use CGI::Lite;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(xestiascan_scan_preview xestiascan_scan_final xestiascan_scan_getpreviewimage xestiascan_scan_getoutputmodules xestiascan_scan_getexportmodules);
+our $scan_device;
+
+sub xestiascan_scan_getoutputmodules{
+#################################################################################
+# xestiascan_scan_getoutputmodules: Gets the list of available output modules. #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# @outputmodules = xestiascan_scan_getoutputmodules;                           #
+#################################################################################
+
+       my (@outputmoduleslist, @outputmoduleslist_final);
+       my $outputmodulefile;
+
+       opendir(OUTPUTMODULEDIR, "Modules/Output");
+       @outputmoduleslist = grep /m*\.pm$/, sort(readdir(OUTPUTMODULEDIR));
+       closedir(OUTPUTMODULEDIR);
+
+       foreach $outputmodulefile (@outputmoduleslist){
+               next if $outputmodulefile =~ m/^\./;
+               next if $outputmodulefile !~ m/.pm$/;
+               $outputmodulefile =~ s/.pm$//;
+               push(@outputmoduleslist_final, $outputmodulefile);
+       }
+
+       return @outputmoduleslist_final;
+       
+}
+
+sub xestiascan_scan_getexportmodules{
+#################################################################################
+# xestiascan_scan_getexportmodules: Gets the list of available export modules. #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# @exportmodules = xestiascan_scan_getexportmodules;                           #
+#################################################################################
+
+       my (@exportmoduleslist, @exportmoduleslist_final);
+       my $exportmodulefile;
+
+       opendir(EXPORTMODULEDIR, "Modules/Export");
+       @exportmoduleslist = grep /m*\.pm$/, sort(readdir(EXPORTMODULEDIR));
+       closedir(EXPORTMODULEDIR);
+
+       foreach $exportmodulefile (@exportmoduleslist){
+               next if $exportmodulefile =~ m/^\./;
+               next if $exportmodulefile !~ m/.pm$/;
+               $exportmodulefile =~ s/.pm$//;
+               push(@exportmoduleslist_final, $exportmodulefile);
+       }
+
+       return @exportmoduleslist_final;
+       
+}
+
+sub xestiascan_scan_preview{
+#################################################################################
+# xestiascan_scan_preview: Previews a scanning.                                        #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_preview(previewdocument, previewoptions);                    #
+#                                                                              #
+# previewdocument      Specifies a preview of the document should be made.     #
+# previewoptions       Specifies the options for the document preview.         #
+#################################################################################
+
+       # Get the values passed to this subroutine.
+       
+       my $previewdocument = shift;
+       
+       if (!$previewdocument){
+       
+               $previewdocument = "off";
+               
+       }
+       
+       # Setup some variables for later.
+       
+       my $scan_settings = 0;
+       
+       my $picture_resolution = "75";
+       my $picture_brightness = "100";
+       my $picture_contrast = "100";
+       my $picture_topleftx = 0;
+       my $picture_toplefty = 0;
+       my $picture_bottomrightx = 0;
+       my $picture_bottomrighty = 0;
+       
+       # Check if the preview document checkbox is selected and if it is then
+       # scan the image and preview it.
+       
+       my $randomhex = int(0);
+       my %previewoptions;
+       
+       my $scannerpermission;
+       
+       if ($previewdocument eq "on"){
+               
+               (%previewoptions) = @_;
+               
+               # Check the parameters passed to the subroutine.
+               
+               # Brightness.
+               
+               xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
+               my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
+               xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
+               
+               # Rotate. (Should be either 0, 90, 180, 270 degrees).
+               
+               xestiascan_error("rotateblank") if !$previewoptions{Rotate};
+               if ($previewoptions{Rotate} eq "0deg" || $previewoptions{Rotate} eq "90deg" || $previewoptions{Rotate} eq "180deg" || $previewoptions{Rotate} eq "270deg"){
+                       
+               } else {
+               
+                       xestiascan_error("rotateinvalidoption");
+               
+               }
+               
+               # Colour.
+               
+               xestiascan_error("colourblank") if !$previewoptions{Colour};
+               if ($previewoptions{Colour} eq "rgb" || $previewoptions{Colour} eq "grey" ){
+                       
+               } else {
+               
+                       xestiascan_error("colourinvalidoption");
+                       
+               }
+               
+               # Resolution.
+               
+               xestiascan_error("resolutionblank") if !defined($previewoptions{Resolution});
+               my $resolution_numberscheck = xestiascan_variablecheck($previewoptions{Resolution}, "numbers", 0, 1);
+               xestiascan_error("resolutioninvalidnumber") if $resolution_numberscheck eq 1;
+               
+               # Top Left X (Pointy figure);
+               
+               xestiascan_error("topleftxblank") if !defined($previewoptions{TopLeftX});
+               my $topleftx_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftX}, "decimal", 0, 1);
+               xestiascan_error("topleftxinvalidnumber") if $topleftx_decimalcheck eq 1;
+               
+               # Top Left Y (Pointy figure).
+               
+               xestiascan_error("topleftyblank") if !defined($previewoptions{TopLeftY});
+               my $toplefty_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftY}, "decimal", 0, 1);
+               xestiascan_error("topleftyinvalidnumber") if $toplefty_decimalcheck eq 1;               
+               
+               # Bottom Right X (Pointy figure).
+               
+               xestiascan_error("bottomrightx") if !defined($previewoptions{BottomRightX});
+               my $bottomrightx_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightX}, "decimal", 0, 1);
+               xestiascan_error("bottomrightxinvalidnumber") if $bottomrightx_decimalcheck eq 1;
+               
+               # Bottom Right Y (Pointy figure).
+               
+               xestiascan_error("bottomrighty") if !defined($previewoptions{BottomRightY});
+               my $bottomrighty_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightY}, "decimal", 0, 1);
+               xestiascan_error("bottomrightyinvalidnumber") if $bottomrighty_decimalcheck eq 1;
+               
+               # Check to see if the user has permission to use the scanner.
+               
+               $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $previewoptions{ScannerID} });
+               
+               xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+               xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+               
+               if ($scannerpermission eq 1){
+                       
+                       # User has permission to use the scanner so start scanning.
+                       
+                       # Generate a random hex value and use this to write a temporary file.
+                       
+                       $randomhex = hex(int(rand(16777216)));
+                       
+                       # Set variables for scanner and return an error if they were
+                       # not set correctly.
+                       
+                       $scan_device = Sane::Device->open($previewoptions{ScannerID});
+                       xestiascan_error("scannererror", $Sane::STATUS) if $Sane::STATUS;
+                       
+                       xestiascan_scan_setscannervalue(SANE_NAME_SCAN_RESOLUTION, $previewoptions{Resolution});
+                       xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedpictureresolution}, $Sane::STATUS)) if $Sane::STATUS;
+                       
+                       xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_X, $previewoptions{TopLeftX});
+                       xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedtopleftx}, $Sane::STATUS)) if $Sane::STATUS;
+                       
+                       xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_Y, $previewoptions{TopLeftY});
+                       xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedtoplefty}, $Sane::STATUS)) if $Sane::STATUS;
+                       
+                       xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_X, $previewoptions{BottomRightX});
+                       xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedbottomrightx}, $Sane::STATUS)) if $Sane::STATUS;
+                       
+                       xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_Y, $previewoptions{BottomRightY});
+                       xestiascan_error("scannererror", xestiascan_language($main::xestiascan_lang{scan}{causedbottomrighty}, $Sane::STATUS)) if $Sane::STATUS;
+                       
+                       # Get Sane to scan based on what has been passed (scanner name).
+                       
+                       if ($Sane::STATUS == SANE_STATUS_GOOD){
+                               $scan_device->start;
+                       } else {
+                       
+                               # An error occured whilst trying to use the scanner
+                               # so return an error.
+                               
+                               xestiascan_error("scannererror", $Sane::STATUS);
+                               
+                       }
+                       
+                       my $param = $scan_device->get_parameters;
+                       my $fh;
+                       open ($fh, '>', "/tmp/xestiascanserver-" . $randomhex . ".pnm") or xestiascan_error("filepermissionerror", $!);
+                       $scan_device->write_pnm_header($fh, $param->{format}, 
+                       $param->{pixels_per_line},
+                       $param->{lines}, $param->{depth});
+                       my ($data, $len);
+                       do{ 
+                               ($data, $len) = $scan_device->read ($param->{bytes_per_line});
+                               print $fh $data if $data;
+                       } until ($Sane::STATUS == SANE_STATUS_EOF);
+                       close ($fh);
+                       
+                       # Get the current scanner values.
+                       
+                       $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
+                       $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
+                       $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
+                       $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
+                       $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
+                       
+                       $scan_settings = 1;
+                       
+                       $picture_topleftx = int(0) if $picture_topleftx eq 0;
+                       
+                       # Convert the PNM based image into PNG format.
+                       
+                       my $im = new Image::Magick;
+                       $im->Read("/tmp/xestiascanserver-" . $randomhex . ".pnm");
+                       
+                       # Rotate the document if needed.
+                       
+                       my $rotate = $previewoptions{Rotate};
+                       my $numrotate = 0;
+                       my $numrotateseek = 0;
+                       
+                       if ($previewoptions{Rotate} ne "0deg" ){
+                               $numrotate = 1 if $rotate eq "90deg";
+                               $numrotate = 2 if $rotate eq "180deg";
+                               $numrotate = 3 if $rotate eq "270deg";
+                               #$im->Rotate({ degrees => "180" }) if $rotate eq "180deg";
+                               #$im->Rotate({ degrees => "270" }) if $rotate eq "270deg";
+                               
+                               do {
+                                       $im->Rotate();
+                                       $numrotateseek++;
+                               } until ($numrotateseek eq $numrotate || $numrotateseek > $numrotate);
+                               
+                       }
+                       
+                       # Change the colour type of the document if needed.
+                       
+                       if ($previewoptions{Colour} eq "rgb"){
+                               
+                               # Set the document to colour.
+                               
+                               $im->Quantize(colorspace => 'RGB');
+                               
+                       } elsif ($previewoptions{Colour} eq "grey"){
+                               
+                               # Set the document to greyscale.
+                               
+                               $im->Quantize(colorspace =>'gray');
+                               
+                       }
+               
+                       # Adjust the brightness.
+                       
+                       xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
+                       
+                       my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
+                       xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
+                       
+                       $picture_brightness = $previewoptions{Brightness};
+                       $im->Modulate(brightness=> $picture_brightness);
+                       
+                       $im->Minify;            # As it is a preview, Minify it.
+                       
+                       $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".png");
+                       
+                       # Delete the PNM file.
+                       
+                       unlink("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
+                       
+               }
+               
+       }
+       
+       my $selectedscandevice;
+       
+       if (@_){
+               
+               (%previewoptions) = @_;
+               
+               $selectedscandevice = $previewoptions{ScannerID};
+               
+       }
+       
+       $selectedscandevice = "" if !$selectedscandevice;
+       
+       # Get the list of available scanners and process the list.
+       
+       my %scanners;
+       tie(%scanners, "Tie::IxHash");
+       %scanners = xestiascan_scan_getscannerlist();
+       
+       # Print out the form.
+       
+       $main::xestiascan_presmodule->startform("xsdss.cgi", "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "scan");
+       $main::xestiascan_presmodule->addhiddendata("action", "scan");
+       $main::xestiascan_presmodule->startbox("scannermenu");
+       
+       if (!%scanners){
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noscanners});
+               $main::xestiascan_presmodule->endbox();
+               return $main::xestiascan_presmodule->grab();
+               
+       }
+       
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{scanner});
+       $main::xestiascan_presmodule->addselectbox("scanner");
+       
+       my $scannername;
+       my $scandevice;
+       my $notfirstscanner = 0;
+       
+       foreach $scandevice (keys %scanners){
+       
+               # Check if scanner matches the name of the selected
+               # scan device.
+               
+               if ($scanners{$scandevice}{name} eq $selectedscandevice){
+                       
+                       $main::xestiascan_presmodule->addoption($scanners{$scandevice}{vendor} . ": ". $scanners{$scandevice}{model}, {Value => $scanners{$scandevice}{name}, Selected => 1});
+                       
+               } else {
+               
+                       $main::xestiascan_presmodule->addoption($scanners{$scandevice}{vendor} . ": ". $scanners{$scandevice}{model}, {Value => $scanners{$scandevice}{name}});
+               
+               }
+               
+               if ($notfirstscanner ne 1){
+               
+                       $scannername = $scanners{$scandevice}{name};
+                       $notfirstscanner = 1;
+                       
+               }
+               
+       }
+       
+       $main::xestiascan_presmodule->endselectbox();
+       
+       # Check to see if the user has permission to use this scanner.
+       # Otherwise return an error message.
+       
+       $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $scannername });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       $scannerpermission = 0 if !$scannerpermission;
+       
+       if ($scannerpermission eq 1){
+       
+               # The user has permission to use this scanner.
+               
+               if (!$previewoptions{ScannerID}){
+                       
+                       $scan_device = Sane::Device->open($scannername);
+                       
+                       xestiascan_error("scannererror", $Sane::STATUS) if $Sane::STATUS;
+                       
+                       $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
+                       $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
+                       $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
+                       $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
+                       $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);           
+
+               } else {
+                       
+                       $scan_device = Sane::Device->open($previewoptions{ScannerID}) if !$scan_device;
+                       
+                       $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
+                       $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
+                       $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
+                       $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
+                       $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
+                       
+               }
+                       
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addbutton("switch", { Value => "switched", Description => $main::xestiascan_lang{scan}{switchscanner} });
+               
+               $main::xestiascan_presmodule->addtext(" | ");
+               
+               if ($previewdocument eq "on"){
+                       $main::xestiascan_presmodule->addcheckbox("previewdocument", { OptionDescription => $main::xestiascan_lang{scan}{previewdocument}, Checked => 1 });
+               } else {
+                       $main::xestiascan_presmodule->addcheckbox("previewdocument", { OptionDescription => $main::xestiascan_lang{scan}{previewdocument} });
+               }
+               
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{scan}{startscanning});
+               $main::xestiascan_presmodule->endbox();
+               
+               if ($previewdocument eq "on"){
+                       
+                       $main::xestiascan_presmodule->startbox("sectionbox");
+                       $main::xestiascan_presmodule->startbox("sectiontitle");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{documentpreview});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("secondbox");
+                       $main::xestiascan_presmodule->addimage("xsdss.cgi?mode=scan&action=getpreviewimage&pictureid=" . $randomhex);
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       
+               }
+               
+               $main::xestiascan_presmodule->startbox("sectionbox");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{documentsettings});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox");
+               
+               $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{scan}{picturedimensions});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{topleftx});
+               $main::xestiascan_presmodule->addinputbox("topleftx", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_topleftx });
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
+               $main::xestiascan_presmodule->addlinebreak();
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{toplefty});
+               $main::xestiascan_presmodule->addinputbox("toplefty", { MaxLength => "5", Size => "5", ZeroInteger => 1,  Value => $picture_toplefty });
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
+               $main::xestiascan_presmodule->addlinebreak();
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{bottomrightx});
+               $main::xestiascan_presmodule->addinputbox("bottomrightx", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_bottomrightx });
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
+               $main::xestiascan_presmodule->addlinebreak();
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{bottomrighty});
+               $main::xestiascan_presmodule->addinputbox("bottomrighty", { MaxLength => "5", Size => "5", ZeroInteger => 1, Value => $picture_bottomrighty });
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{mm});
+               $main::xestiascan_presmodule->addlinebreak();
+               
+               $main::xestiascan_presmodule->addhorizontalline();
+               
+               $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{scan}{picturesettings});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{pictureresolution});
+               $main::xestiascan_presmodule->addinputbox("imagedpi", { MaxLength => "4", Size => "4", Value => $picture_resolution});
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{dpi});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{rotate});
+               $main::xestiascan_presmodule->addselectbox("rotate");
+               
+               if ($previewoptions{Rotate}){
+                       
+                       # If the value matches with one of these in the list then
+                       # set that as the selected value.
+                       
+                       if ($previewoptions{Rotate} eq "0deg"){
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg", Selected => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg" });
+                               
+                       }
+                       
+                       if ($previewoptions{Rotate} eq "90deg"){
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg", Selected => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg" });
+                               
+                       }
+                       
+                       if ($previewoptions{Rotate} eq "180deg"){
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg", Selected => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg" });
+                               
+                       }
+                       
+                       if ($previewoptions{Rotate} eq "270deg"){
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg", Selected => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg" });
+                               
+                       }
+                       
+                       
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r0deg}, { Value => "0deg", Selected => 1 });
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r90deg}, { Value => "90deg" });
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r180deg}, { Value => "180deg" });
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{r270deg}, { Value => "270deg" });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endselectbox();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{brightness});
+               $main::xestiascan_presmodule->addinputbox("brightness", { MaxLength => "3", Size => "3", Value => $picture_brightness });
+               $main::xestiascan_presmodule->addtext("%");
+               $main::xestiascan_presmodule->addlinebreak();
+               #$main::xestiascan_presmodule->addtext("Contrast: ");
+               #$main::xestiascan_presmodule->addinputbox("contrast", { MaxLength => "3", Size => "3", Value => $picture_contrast })#;
+               #$main::xestiascan_presmodule->addtext("%");
+               #$main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{colour});
+               $main::xestiascan_presmodule->addselectbox("colourtype");
+               
+               if (!$previewoptions{Colour} || $previewoptions{Colour} eq "rgb"){
+                       
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{colourrgb}, { Value => "rgb", Selected => 1 });
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{colourrgb}, { Value => "rgb" });
+                       
+               }
+               
+               if ($previewoptions{Colour} && $previewoptions{Colour} eq "grey"){
+                       
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{grey}, { Value => "grey", Selected => 1 });
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addoption($main::xestiascan_lang{scan}{grey}, { Value => "grey" });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endselectbox();
+               
+               
+               $main::xestiascan_presmodule->addlinebreak();
+               
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+               $main::xestiascan_presmodule->endform();
+               
+       } else {
+       
+               # The user does not have permission to use this scanner.
+               
+               $main::xestiascan_presmodule->addtext(" | ");
+               $main::xestiascan_presmodule->addbutton("switch", { Value => "switched", Description => $main::xestiascan_lang{scan}{switchscanner} });
+               $main::xestiascan_presmodule->endbox();
+               
+               $main::xestiascan_presmodule->startbox("errorsectionbox");
+               $main::xestiascan_presmodule->startbox("errorboxheader");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("errorbox");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{scannerpermissioninvalid});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+       }
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
+
+sub xestiascan_scan_final{
+#################################################################################
+# xestiascan_scan_final: Get the final image and present a list of available   #
+#                       options.                                               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_final(confirm, pageoptions);                                 #
+#                                                                              #
+# confirm              Specifies to confirm the processing of the page.        #
+# pageoptions          Specifies the options for the page.                     #
+#################################################################################
+       
+       # Get the variables passed to the subroutine.
+       
+       my $confirm     = shift;
+       
+       if (!$confirm){
+       
+               # The confirm value is not set so set it to 0.
+               
+               $confirm = 0;
+       
+       }
+       
+       my (%previewoptions) = @_;
+       
+       # Check if the user has permission to use the scanner
+       # and return an error if this is not the case.
+       
+       my $scannerpermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Scanner", PermissionName => $previewoptions{ScannerID} });
+       
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       $scannerpermission = 0 if !$scannerpermission;
+       
+       if ($scannerpermission ne 1 && !$previewoptions{OutputFormat}){
+       
+               # The user does not have permission to use this scanner,
+               # so return an error message.
+               
+               $main::xestiascan_presmodule->startbox("errorsectionbox");
+               $main::xestiascan_presmodule->startbox("errorboxheader");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("errorbox");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{scannerpermissioninvalid});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+               return $main::xestiascan_presmodule->grab();
+               
+       }
+       
+       if ($confirm eq 1){
+       
+               # The action to process the page has been confirmed so process the image.
+               
+               # Convert the PNM image into the correct format.
+               
+               my $outputmodule = $previewoptions{OutputFormat};
+               my $hexnumber = int($previewoptions{ImageHex});
+               
+               # Check if the output module has a valid name.
+               
+               my $outputmodulevalid = xestiascan_variablecheck($previewoptions{OutputFormat}, "module", 0, 1);
+               
+               if ($outputmodulevalid eq 1){
+               
+                       # The output module is missing so write a message saying
+                       # the name is invalid.
+                       
+                       $main::xestiascan_presmodule->startbox("errorsectionbox");
+                       $main::xestiascan_presmodule->startbox("errorboxheader");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("errorbox");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidname});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       
+                       return $main::xestiascan_presmodule->grab();
+                       
+               }
+               
+               # Check if the module exists.
+               
+               my $outputmoduleexists = xestiascan_fileexists("Modules/Output/" . $previewoptions{OutputFormat} . ".pm");
+               
+               if ($outputmoduleexists eq 1){
+               
+                       # The output module is missing so write a message saying
+                       # it does not exist.
+                       
+                       $main::xestiascan_presmodule->startbox("errorsectionbox");
+                       $main::xestiascan_presmodule->startbox("errorboxheader");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("errorbox");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodulemissing});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();                 
+                       
+                       return $main::xestiascan_presmodule->grab();
+                       
+               }
+               
+               # Check if the module has valid file permissions.
+               
+               my $outputmodulefilepermission = xestiascan_filepermissions("Modules/Output/" . $previewoptions{OutputFormat} . ".pm", 1, 0, 0);
+               
+               if ($outputmodulefilepermission eq 1){
+               
+                       # The output module has invalid file permissions so
+                       # write a message.
+                       
+                       $main::xestiascan_presmodule->startbox("errorsectionbox");
+                       $main::xestiascan_presmodule->startbox("errorboxheader");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("errorbox");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidfilepermissions});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();                 
+                       
+                       return $main::xestiascan_presmodule->grab();                    
+                       
+               }
+               
+               # Check to see if the user has permission to use the output module and return an error if not.
+               
+               my $outputmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "OutputModule", PermissionName => $outputmodule });
+
+               xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+               xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+               
+               $outputmodulepermission = 0 if !$outputmodulepermission;
+               
+               if ($outputmodulepermission eq 0){
+               
+                       # The user does not have permission so write an error message
+                       # saying the user does not have permission.
+                       
+                       $main::xestiascan_presmodule->startbox("errorsectionbox");
+                       $main::xestiascan_presmodule->startbox("errorboxheader");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{error});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("errorbox");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvaliddbpermissions});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();                 
+                       
+                       return $main::xestiascan_presmodule->grab();
+                       
+               }
+               
+               my $outputmodulename = "Modules::Output::" . $outputmodule;
+               eval "use " . $outputmodulename;
+               my $xestiascan_outputmodule = $outputmodulename->new();
+               my ($outputmodule_options, %outputmodule_options);
+               tie(%outputmodule_options, "Tie::IxHash");
+               $xestiascan_outputmodule->initialise();
+               $xestiascan_outputmodule->loadsettings($main::xestiascan_config{"system_language"});
+               %outputmodule_options = $xestiascan_outputmodule->getoptions();
+               my $option_name;
+               my $outputmodule_selected = 0;
+               my $outputmodule_readonly = 0;
+               my $combobox_count = 0;
+               my @outputmodule_comboboxnames;
+               my @outputmodule_comboboxvalues;
+               my $outputmodule_comboboxname;
+               my $outputmodule_comboboxvalue;
+               
+               # Setup the original filename.
+               
+               my $original_filename = "";
+               my $processed_filename = "";
+               
+               # Get the output module settings.
+               
+               my ($outputmodule_passedoptions, %outputmodule_passedoptions);
+               my %outputmodulesettings;
+               my %outputmodulesettings_final;
+               tie(%outputmodule_passedoptions, "Tie::IxHash");
+               
+               my $hs = new Hash::Search;
+               my $cgilite = new CGI::Lite;
+               my %form_data = $cgilite->parse_form_data;
+               
+               $hs->hash_search("^outputmodule_", %form_data);
+               %outputmodulesettings = $hs->hash_search_resultdata;
+               
+               # Strip the outputmodule_ prefix.
+               
+               my $outputmodule_settings_unprocessed;
+               my $outputmodule_settings_regex;
+               
+               foreach $outputmodule_settings_unprocessed (keys %outputmodulesettings){
+               
+                       $outputmodule_settings_regex = "^outputmodule_";
+                       $outputmodule_settings_unprocessed =~ s/^$outputmodule_settings_regex//;
+                       
+                       $outputmodulesettings_final{$outputmodule_settings_unprocessed} = $outputmodulesettings{"outputmodule_" . $outputmodule_settings_unprocessed};
+                       
+               }
+               
+               # Proceed with the output module processing.
+               
+               $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleresults});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox");
+               
+               $main::xestiascan_presmodule->startbox("outputmoduletitle");
+               $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{resultsuffix}, $outputmodule));
+               $main::xestiascan_presmodule->endbox();
+
+               $processed_filename = $xestiascan_outputmodule->processimage($hexnumber, %outputmodulesettings_final);
+               
+               $main::xestiascan_presmodule->startbox("outputmoduleoptions");
+
+               if ($xestiascan_outputmodule->errorflag ne 0){
+                       
+                       # An error occurred so stop processing and end the script.
+                       
+                       $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{outputmodulefailed}, $xestiascan_outputmodule->errormessage));
+                       $main::xestiascan_presmodule->addlinebreak();
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleunable});
+                       $main::xestiascan_presmodule->endbox();
+                       
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       
+                       return $main::xestiascan_presmodule->grab();
+                       
+               } else {
+               
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodulecomplete});
+                       
+               }
+               
+               $main::xestiascan_presmodule->endbox();
+               
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+               # Process the selected export modules.
+               
+               $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleresults});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox");
+               
+               # Check the list of selected export modules.
+               
+               my (%selectedmodules, $selectedmodules);
+               
+               my (%exportmodulesettings, $exportmodulesettings);
+               my (%exportmodulesettings_final);
+               
+               $hs->hash_search("^module_", %form_data);
+               %selectedmodules = $hs->hash_search_resultdata;
+               
+               my $exportmodule_count = 0;
+               my $exportmodule_name = "";
+               my $exportmodule_unprocessed = "";
+               
+               my $exportmodule_settings_unprocessed = "";
+               my $exportmodule_settings_regex = "";
+               
+               my @activemodules;
+               
+               foreach $exportmodule_unprocessed (keys %selectedmodules){
+               
+                       # Skip if the module wasn't selected in the first place.
+                       
+                       next if $selectedmodules{$exportmodule_unprocessed} ne "on";
+                       
+                       # Add the module to the selected modules list.
+                       
+                       $exportmodule_unprocessed =~ s/^module_//;
+                       push(@activemodules, $exportmodule_unprocessed);
+                       $exportmodule_count++;
+                       
+               }
+               
+               @activemodules = sort(@activemodules);
+               
+               # Process the export modules.
+               
+               foreach $exportmodule_name (@activemodules){
+
+                       # Write the beginning part of the box for the results of the module.
+                       
+                       $main::xestiascan_presmodule->startbox("exportmoduletitle");
+                       $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{resultsuffix}, $exportmodule_name));
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("exportmoduleoptions");
+                       
+                       # Check to see if the export module exists and process the next
+                       # one if this is not the case.
+                       
+                       my $exportmodulecheck = xestiascan_variablecheck($exportmodule_name, "module", 0, 1);
+                       
+                       if ($exportmodulecheck eq 1){
+                       
+                               # The export module name given is invalid. Skip and
+                               # process the next one.
+                               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmoduleinvalidname});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;
+                               
+                       }
+                       
+                       my $exportmoduleexists = xestiascan_fileexists("Modules/Export/" . $exportmodule_name . ".pm");
+                       
+                       if ($exportmoduleexists eq 1){
+                               
+                               # The export moudle with the name given is missing.
+                               # Skip and process the next one.
+                               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmodulemissing});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;
+                               
+                               
+                       }
+                       
+                       my $exportmodulefilepermission = xestiascan_filepermissions("Modules/Export/" . $exportmodule_name . ".pm");
+                       
+                       if ($exportmodulefilepermission eq 1){
+                       
+                               # The export module with the name given has invalid
+                               # file permissions.
+                               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmodulemissing});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;                           
+                               
+                       }
+                       
+                       # Check if the user has permission to use this export
+                       # module and write a message if not.
+                       
+                       my $exportmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "ExportModule", PermissionName => $exportmodule_name });
+
+                       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+                       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+                       
+                       $exportmodulepermission = 0 if !$exportmodulepermission;
+                       
+                       if ($exportmodulepermission eq 0){
+                       
+                               # The user does not have permission to use this export
+                               # module so write a message.
+                               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{error}{exportmoduleinvaliddbpermissions});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;
+                               
+                       }
+                       
+                       # Get the module settings.
+                       
+                       my ($exportmodule_options, %exportmodule_options);
+                       tie(%exportmodule_options, "Tie::IxHash");
+                       
+                       $hs->hash_search("^exportmodule_" . $exportmodule_name . "_", %form_data);
+                       %exportmodulesettings = $hs->hash_search_resultdata;
+                       
+                       # Strip the module settings.
+                       
+                       foreach $exportmodule_settings_unprocessed (keys %exportmodulesettings){
+                               
+                               $exportmodule_settings_regex = "^exportmodule_" . $exportmodule_name . "_";
+                               $exportmodule_settings_unprocessed =~ s/^$exportmodule_settings_regex//;
+                               
+                               $exportmodule_options{$exportmodule_settings_unprocessed} = $exportmodulesettings{"exportmodule_" . $exportmodule_name . "_" . $exportmodule_settings_unprocessed};
+                               
+                       }
+                       
+                       # Load the export module.
+                       
+                       my $exportmodulename = "Modules::Export::" . $exportmodule_name;
+                       eval "use " . $exportmodulename;
+                       my $xestiascan_exportmodule = $exportmodulename->new();
+                       
+                       $xestiascan_exportmodule->initialise();
+                       $xestiascan_exportmodule->loadsettings($main::xestiascan_config{"system_language"});
+                       
+                       # Process the outputted file.
+                       
+                       $xestiascan_exportmodule->exportimage($processed_filename, $main::xestiascan_config{"directory_noncgi_scans"}, $main::xestiascan_config{"directory_fs_scans"}, %exportmodule_options);
+                       
+                       # Check if an error occured.
+                       
+                       $main::xestiascan_presmodule->addhorizontalline();
+                       
+                       if ($xestiascan_exportmodule->errorflag ne 0){
+                               
+                               $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{scan}{exportmodulefailed}, $xestiascan_exportmodule->errormessage));
+                               
+                       } else {
+               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmodulecomplete});
+                               
+                       }
+                       
+                       # Delete the export module.
+                       
+                       undef($xestiascan_exportmodule);
+                       
+                       # Finish the results box for this export module.
+                       
+                       $main::xestiascan_presmodule->endbox();
+               
+               }
+               
+               if (!@activemodules){
+               
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmoduleselected});
+                       
+               }
+               
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();         
+               
+       } else {
+       
+               my $randomhex = 0;
+               
+               if ($previewoptions{Switched} eq "no"){
+               
+                       # Get the image, generate a random number, write the file as PNM and display
+                       # some options for the scanned image.
+                       
+                       # Brightness.
+                       
+                       xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
+                       my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
+                       xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
+                       
+                       # Rotate. (Should be either 0, 90, 180, 270 degrees).
+                       
+                       xestiascan_error("rotateblank") if !$previewoptions{Rotate};
+                       if ($previewoptions{Rotate} eq "0deg" || $previewoptions{Rotate} eq "90deg" || $previewoptions{Rotate} eq "180deg" || $previewoptions{Rotate} eq "270deg"){
+                               
+                       } else {
+                               
+                               xestiascan_error("rotateinvalidoption");
+                               
+                       }
+                       
+                       # Colour.
+                       
+                       xestiascan_error("colourblank") if !$previewoptions{Colour};
+                       if ($previewoptions{Colour} eq "rgb" || $previewoptions{Colour} eq "grey" ){
+                               
+                       } else {
+                               
+                               xestiascan_error("colourinvalidoption");
+                               
+                       }
+                       
+                       # Resolution.
+                       
+                       xestiascan_error("resolutionblank") if !defined($previewoptions{Resolution});
+                       my $resolution_numberscheck = xestiascan_variablecheck($previewoptions{Resolution}, "numbers", 0, 1);
+                       xestiascan_error("resolutioninvalidnumber") if $resolution_numberscheck eq 1;
+                       
+                       # Top Left X (Pointy figure);
+                       
+                       xestiascan_error("topleftxblank") if !defined($previewoptions{TopLeftX});
+                       my $topleftx_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftX}, "decimal", 0, 1);
+                       xestiascan_error("topleftxinvalidnumber") if $topleftx_decimalcheck eq 1;
+                       
+                       # Top Left Y (Pointy figure).
+                       
+                       xestiascan_error("topleftyblank") if !defined($previewoptions{TopLeftY});
+                       my $toplefty_decimalcheck = xestiascan_variablecheck($previewoptions{TopLeftY}, "decimal", 0, 1);
+                       xestiascan_error("topleftyinvalidnumber") if $toplefty_decimalcheck eq 1;               
+                       
+                       # Bottom Right X (Pointy figure).
+                       
+                       xestiascan_error("bottomrightx") if !defined($previewoptions{BottomRightX});
+                       my $bottomrightx_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightX}, "decimal", 0, 1);
+                       xestiascan_error("bottomrightxinvalidnumber") if $bottomrightx_decimalcheck eq 1;
+                       
+                       # Bottom Right Y (Pointy figure).
+                       
+                       xestiascan_error("bottomrighty") if !defined($previewoptions{BottomRightY});
+                       my $bottomrighty_decimalcheck = xestiascan_variablecheck($previewoptions{BottomRightY}, "decimal", 0, 1);
+                       xestiascan_error("bottomrightyinvalidnumber") if $bottomrighty_decimalcheck eq 1;
+                       
+                       # Generate a random hex value and use this to write a temporary file.
+                       
+                       $randomhex = 0;
+                       
+                       if (!$previewoptions{ImageHex}){
+                       
+                               $randomhex = hex(int(rand(16777216)));
+                       
+                               # Set variables for scanner.
+                       
+                               $scan_device = Sane::Device->open($previewoptions{ScannerID});
+                       
+                               xestiascan_scan_setscannervalue(SANE_NAME_SCAN_RESOLUTION, $previewoptions{Resolution});
+                               xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_X, $previewoptions{TopLeftX});
+                               xestiascan_scan_setscannervalue(SANE_NAME_SCAN_TL_Y, $previewoptions{TopLeftY});
+                               xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_X, $previewoptions{BottomRightX});
+                               xestiascan_scan_setscannervalue(SANE_NAME_SCAN_BR_Y, $previewoptions{BottomRightY});
+                       
+                               # Get Sane to scan based on what has been passed (scanner name).
+                       
+                               if ($Sane::STATUS == SANE_STATUS_GOOD){
+                                       $scan_device->start;
+                               }
+                       
+                               my $param = $scan_device->get_parameters;
+                               my $fh;
+                               open ($fh, '>', "/tmp/xestiascanserver-preview-" . $randomhex . ".pnm") or die("error: $!");
+                               $scan_device->write_pnm_header($fh, $param->{format}, 
+                               $param->{pixels_per_line},
+                               $param->{lines}, $param->{depth});
+                               my ($data, $len);
+                               do{ 
+                                       ($data, $len) = $scan_device->read ($param->{bytes_per_line});
+                                       print $fh $data if $data;
+                               } until ($Sane::STATUS == SANE_STATUS_EOF);
+                               close ($fh);
+                       
+                               # Get the current scanner values.
+                               
+                               my $picture_resolution = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_RESOLUTION);
+                               my $picture_topleftx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_X);
+                               my $picture_toplefty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_TL_Y);
+                               my $picture_bottomrightx = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_X);
+                               my $picture_bottomrighty = xestiascan_scan_getscannervalue(SANE_NAME_SCAN_BR_Y);
+                               
+                               $picture_topleftx = int(0) if $picture_topleftx eq 0;
+                               
+                               # Convert the PNM based image into PNG format.
+                               
+                               my $im = new Image::Magick;
+                               $im->Read("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
+                               
+                               # Rotate the document if needed.
+                               
+                               my $rotate = $previewoptions{Rotate};
+                               my $numrotate = 0;
+                               my $numrotateseek = 0;
+                               
+                               if ($previewoptions{Rotate} ne "0deg" ){
+                                       $numrotate = 1 if $rotate eq "90deg";
+                                       $numrotate = 2 if $rotate eq "180deg";
+                                       $numrotate = 3 if $rotate eq "270deg";
+                                       
+                                       do {
+                                               $im->Rotate();
+                                               $numrotateseek++;
+                                       } until ($numrotateseek eq $numrotate || $numrotateseek > $numrotate);
+                                       
+                               }
+                               
+                               # Change the colour type of the document if needed.
+                               
+                               if ($previewoptions{Colour} eq "rgb"){
+                                       
+                                       # Set the document to colour.
+                                       
+                                       $im->Quantize(colorspace => 'RGB');
+                                       
+                               } elsif ($previewoptions{Colour} eq "grey"){
+                                       
+                                       # Set the document to greyscale.
+                                       
+                                       $im->Quantize(colorspace =>'gray');
+                                       
+                               }
+                               
+                               # Adjust the brightness.
+                               
+                               xestiascan_error("brightnessblank") if !$previewoptions{Brightness};
+                               
+                               my $brightness_numberscheck = xestiascan_variablecheck($previewoptions{Brightness}, "numbers", 0, 1);
+                               xestiascan_error("brightnessinvalidnumber") if $brightness_numberscheck eq 1;
+                               
+                               my $picture_brightness = $previewoptions{Brightness};
+                               $im->Modulate( brightness=> $picture_brightness );
+                               
+                               $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".pnm");
+                               
+                               $im->Minify;
+                               
+                               $im->Write("/tmp/xestiascanserver-preview-" . $randomhex . ".png");
+
+                       } else {
+                       
+                               $randomhex = $previewoptions{ImageHex};
+                               
+                       }
+                       
+               } else {
+                       
+                       $randomhex = $previewoptions{ImageHex};
+                       
+               }
+               
+               my ($outputmodule, $outputmodulesname, $exportmodule);
+               
+               # Get the output modules.
+               
+               my @outputmodules = xestiascan_scan_getoutputmodules;
+               $outputmodule = $previewoptions{OutputFormat} if $previewoptions{OutputFormat};
+               
+               # Get the export modules.
+               
+               my @exportmodules = xestiascan_scan_getexportmodules;
+               
+               $main::xestiascan_presmodule->startform("xsdss.cgi", "GET");
+               $main::xestiascan_presmodule->addhiddendata("mode", "scan");
+               $main::xestiascan_presmodule->addhiddendata("action", "scan");
+               $main::xestiascan_presmodule->addhiddendata("confirm", "1");
+               $main::xestiascan_presmodule->addhiddendata("imagehex", $randomhex);
+               
+               $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{imagepreview});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox, previewimage");
+               
+               # Get a preview of the image.
+               
+               $main::xestiascan_presmodule->addimage("xsdss.cgi?mode=scan&action=getpreviewimage&dontclear=1&pictureid=" . $randomhex);
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+
+               $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputformatsettings});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox");
+               
+               $main::xestiascan_presmodule->startbox("outputmoduletitle");
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmodule});
+               
+               $outputmodule = $main::xestiascan_config{"system_outputmodule"} if !$outputmodule;
+               
+               if (!@outputmodules){
+               
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noneavailable});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->startbox("outputmoduleoptions");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{nooutputmodulesavail});
+                       $main::xestiascan_presmodule->endbox();
+                       return $main::xestiascan_presmodule->grab();
+                       
+               } else {
+               
+                       $main::xestiascan_presmodule->addselectbox("outputformat");
+                       
+                       foreach $outputmodulesname (@outputmodules){
+                               if ($outputmodule eq $outputmodulesname){
+                                       $main::xestiascan_presmodule->addoption($outputmodulesname, { Value => $outputmodulesname, Selected => 1 });
+                               } else {
+                                       $main::xestiascan_presmodule->addoption($outputmodulesname, { Value => $outputmodulesname });
+                               }
+                       }
+                       
+                       $main::xestiascan_presmodule->endselectbox();
+                       $main::xestiascan_presmodule->addbutton("formatswitch", { Value => "yes", Description => "Switch Module" });
+                       
+               }
+                       
+               $main::xestiascan_presmodule->endbox();
+               
+               $outputmodule = $outputmodules[0] if !$outputmodule;
+               
+               # Check to see if the user has permission to use this
+               # output module.
+               
+               my $outputmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "OutputModule", PermissionName => $outputmodule });
+
+               xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+               xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+               
+               $outputmodulepermission = 0 if !$outputmodulepermission;
+               
+               # Get the settings for the active output module.
+               
+               my $option_name;
+               my $combobox_count = 0;
+               
+               my $outputmodulefilepermissions = xestiascan_filepermissions("Modules/Output/" . $outputmodule . ".pm", 1, 0, 0);
+               
+               if ($outputmodulepermission eq 1 && $outputmodulefilepermissions eq 0){
+                       
+                       # Load the output module.
+                       
+                       my $outputmodulename = "Modules::Output::" . $outputmodule;
+                       eval "use " . $outputmodulename;
+                       my $xestiascan_outputmodule = $outputmodulename->new();
+                       my ($outputmodule_options, %outputmodule_options);
+                       tie(%outputmodule_options, "Tie::IxHash");
+                       $xestiascan_outputmodule->initialise();
+                       $xestiascan_outputmodule->loadsettings($main::xestiascan_config{"system_language"});
+                       %outputmodule_options = $xestiascan_outputmodule->getoptions();
+                       my $outputmodule_selected = 0;
+                       my $outputmodule_readonly = 0;
+                       my @outputmodule_comboboxnames;
+                       my @outputmodule_comboboxvalues;
+                       my $outputmodule_comboboxname;
+                       my $outputmodule_comboboxvalue;
+                       
+                       $main::xestiascan_presmodule->startbox("outputmoduleoptions");          
+                       
+                       foreach $option_name (keys %outputmodule_options){
+                               
+                               # Check if the option is a checkbox option.
+                               
+                               if ($outputmodule_options{$option_name}{type} eq "checkbox"){
+                                       
+                                       $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $option_name, { Checked => $outputmodule_options{$option_name}{checked}, OptionDescription => $outputmodule_options{$option_name}{string}, ReadOnly => $outputmodule_readonly });
+                                       
+                               }
+                               
+                               # Check if the option is a string option.
+                               
+                               if ($outputmodule_options{$option_name}{type} eq "textbox"){
+                                       
+                                       if (!$outputmodule_options{$option_name}{password}){
+                                               $outputmodule_options{$option_name}{password} = 0;
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->addtext($outputmodule_options{$option_name}{string} . " ");
+                                       $main::xestiascan_presmodule->addinputbox("outputmodule_" . $option_name, { Size => $outputmodule_options{$option_name}{size}, MaxLength => $outputmodule_options->{$option_name}{maxlength}, Value => $outputmodule_options{$option_name}{value}, Password => $outputmodule_options{$option_name}{password}, ReadOnly => $outputmodule_readonly });
+                                       
+                               }
+                               
+                               # Check if the option is a combobox option.
+                               
+                               if ($outputmodule_options{$option_name}{type} eq "combobox"){
+                                       
+                                       $combobox_count         = 0;
+                                       
+                                       @outputmodule_comboboxnames = split(/\|/, $outputmodule_options{$option_name}{optionnames});
+                                       @outputmodule_comboboxvalues = split(/\|/, $outputmodule_options{$option_name}{optionvalues});
+                                       
+                                       $main::xestiascan_presmodule->addtext($outputmodule_options{$option_name}{string} . " ");
+                                       $main::xestiascan_presmodule->addselectbox("outputmodule_" . $option_name);
+                                       
+                                       foreach $outputmodule_comboboxname (@outputmodule_comboboxnames){
+                                               
+                                               $main::xestiascan_presmodule->addoption($outputmodule_comboboxname, { Value => $outputmodule_comboboxvalues[$combobox_count], ReadOnly => $outputmodule_readonly });
+                                               $combobox_count++;
+                                               
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->endselectbox;
+                                       
+                               }
+                               
+                               # Check if the option is a radio option.
+                               
+                               if ($outputmodule_options{$option_name}{type} eq "radio"){
+                                       
+                                       # Check if the selected value is blank and if it is then
+                                       # set it to 0.
+                                       
+                                       if (!$outputmodule_options{$option_name}{selected}){
+                                               $outputmodule_selected = 0;
+                                       } else {
+                                               $outputmodule_selected = 1;
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->addradiobox("outputmodule_" . $outputmodule_options{$option_name}{name}, { Description => $outputmodule_options{$option_name}{string}, Value => $outputmodule_options{$option_name}{value}, Selected => $outputmodule_selected, ReadOnly => $outputmodule_readonly });
+                                       
+                               }
+                               
+                               $main::xestiascan_presmodule->addlinebreak();
+                               
+                       }
+
+                       # If there are no options available then write a message
+                       # to say no options are available for this module.
+                       
+                       if (!%outputmodule_options){
+                       
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{nooutputmoduleopts});
+                               
+                       }
+                       
+               } elsif ($outputmodulefilepermissions eq 1) {
+                       
+                       $main::xestiascan_presmodule->startbox("outputmoduleoptions");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvalidfilepermissions});                        
+                       
+               } else {
+               
+                       $main::xestiascan_presmodule->startbox("outputmoduleoptions");
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{outputmoduleinvaliddbpermissions});
+                       
+               }
+               
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+               $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+               $main::xestiascan_presmodule->startbox("sectiontitle");
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportformatsettings});
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->startbox("secondbox");
+               
+               # Process the list of export modules.
+               
+               my $exportmodulename;
+               my $xestiascan_exportmodule;
+               my ($exportmodule_options, %exportmodule_options);
+               my $exportmodule_readonly = 0;
+               my $exportmodule_selected = 0;
+               my @exportmodule_comboboxnames;
+               my @exportmodule_comboboxvalues;
+               my $exportmodule_comboboxname;
+               my $exportmodule_comboboxvalue;
+               
+               if (!@exportmodules){
+               
+                       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmodulesavail});
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       $main::xestiascan_presmodule->endbox();
+                       return $main::xestiascan_presmodule->grab();
+                       
+               }
+               
+               my $exportmodulepermission;
+               my $exportmodulefilepermission;
+               
+               foreach $exportmodule (@exportmodules){
+                       
+                       # Check to see if the user has permission to use the export
+                       # module and return an error if this is not the case.
+                       
+                       $exportmodulepermission = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "ExportModule", PermissionName => $exportmodule });
+
+                       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+                       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+                       
+                       $exportmodulepermission = 0 if !$exportmodulepermission;
+                       
+                       # Check the file permissions for the export module
+                       # has been set correctly.
+                       
+                       $exportmodulefilepermission = xestiascan_filepermissions("Modules/Export/" . $exportmodule . ".pm", 1, 0, 0);
+                       
+                       if ($exportmodulepermission eq 0){
+                       
+                               # We don't have permission so write an error message.
+                               
+                               $main::xestiascan_presmodule->startbox("exportmoduletitle");
+                               $main::xestiascan_presmodule->addtext($exportmodule);
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               $main::xestiascan_presmodule->startbox("exportmoduleoptions");
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleinvalidfilepermissions});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;
+                               
+                       }
+                       
+                       if ($exportmodulefilepermission ne 0){
+                       
+                               # The file permissions are invalid so write an error message.
+                               
+                               $main::xestiascan_presmodule->startbox("exportmoduletitle");
+                               $main::xestiascan_presmodule->addtext($exportmodule);
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               $main::xestiascan_presmodule->startbox("exportmoduleoptions");
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{exportmoduleinvaliddbpermissions});
+                               $main::xestiascan_presmodule->endbox();
+                               
+                               next;
+                               
+                       }
+                       
+                       # Load the export module.
+                       
+                       $exportmodulename = "Modules::Export::" . $exportmodule;
+                       eval "use " . $exportmodulename;
+                       $xestiascan_exportmodule = $exportmodulename->new();
+                       tie(%exportmodule_options, "Tie::IxHash");
+                       $xestiascan_exportmodule->initialise();
+                       $xestiascan_exportmodule->loadsettings($main::xestiascan_config{"system_language"});
+                       %exportmodule_options = $xestiascan_exportmodule->getoptions();
+                       
+                       $main::xestiascan_presmodule->startbox("exportmoduletitle");
+                       $main::xestiascan_presmodule->addcheckbox("module_" . $exportmodule, { OptionDescription => "" });
+                       $main::xestiascan_presmodule->addtext($exportmodule);
+                       $main::xestiascan_presmodule->endbox();
+                       
+                       $main::xestiascan_presmodule->startbox("exportmoduleoptions");
+                       foreach $option_name (keys %exportmodule_options){
+                               
+                               # Check if the option is a checkbox option.
+                               
+                               if ($exportmodule_options{$option_name}{type} eq "checkbox"){
+                                        
+                                       $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodule . "_" . $option_name, { Checked => $exportmodule_options{$option_name}{checked}, OptionDescription => $exportmodule_options{$option_name}{string}, ReadOnly => $exportmodule_readonly });
+                                       
+                               }
+                               
+                               # Check if the option is a string option.
+                               
+                               if ($exportmodule_options{$option_name}{type} eq "textbox"){
+                                       
+                                       if (!$exportmodule_options{$option_name}{password}){
+                                               $exportmodule_options{$option_name}{password} = 0;
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->addtext($exportmodule_options{$option_name}{string} . " ");
+                                       $main::xestiascan_presmodule->addinputbox("exportmodule_" . $exportmodule . "_" . $option_name, { Size => $exportmodule_options{$option_name}{size}, MaxLength => $exportmodule_options->{$option_name}{maxlength}, Value => $exportmodule_options{$option_name}{value}, Password => $exportmodule_options{$option_name}{password}, ReadOnly => $exportmodule_readonly });
+                                       
+                               }
+                               
+                               # Check if the option is a combobox option.
+                               
+                               if ($exportmodule_options{$option_name}{type} eq "combobox"){
+                                       
+                                       $combobox_count         = 0;
+                                       
+                                       @exportmodule_comboboxnames = split(/\|/, $exportmodule_options{$option_name}{optionnames});
+                                       @exportmodule_comboboxvalues = split(/\|/, $exportmodule_options{$option_name}{optionvalues});
+                                       
+                                       $main::xestiascan_presmodule->addtext($exportmodule_options{$option_name}{string} . " ");
+                                       $main::xestiascan_presmodule->addselectbox("exportmodule_" . $exportmodule . "_" . $option_name);
+                                       
+                                       foreach $exportmodule_comboboxname (@exportmodule_comboboxnames){
+                                               
+                                               $main::xestiascan_presmodule->addoption($exportmodule_comboboxname, { Value => $exportmodule_comboboxvalues[$combobox_count], ReadOnly => $exportmodule_readonly });
+                                               $combobox_count++;
+                                               
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->endselectbox;
+                                       
+                               }
+                               
+                               # Check if the option is a radio option.
+                               
+                               if ($exportmodule_options{$option_name}{type} eq "radio"){
+                                       
+                                       # Check if the selected value is blank and if it is then
+                                       # set it to 0.
+                                       
+                                       if (!$exportmodule_options{$option_name}{selected}){
+                                               $exportmodule_selected = 0;
+                                       } else {
+                                               $exportmodule_selected = 1;
+                                       }
+                                       
+                                       $main::xestiascan_presmodule->addradiobox("exportmodule_" . $exportmodule . "_" . $exportmodule_options{$option_name}{name}, { Description => $exportmodule_options{$option_name}{string}, Value => $exportmodule_options{$option_name}{value}, Selected => $exportmodule_selected, ReadOnly => $exportmodule_readonly });
+                                       
+                               }
+                               
+                               $main::xestiascan_presmodule->addlinebreak();
+                               
+                       }                       
+                       $main::xestiascan_presmodule->endbox();
+                       
+                       if (!%exportmodule_options){
+                               
+                               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{scan}{noexportmoduleopts});
+                               
+                       }
+                       
+                       # Delete (free) the export module.
+                       
+                       undef($xestiascan_exportmodule);
+                       
+               }
+               
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               $main::xestiascan_presmodule->endbox();
+               
+               $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{scan}{process});
+               $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{restoredefault});
+               
+               $main::xestiascan_presmodule->endform();
+               
+       }
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
+
+
+sub xestiascan_scan_getpreviewimage{
+#################################################################################
+# xestiascan_scan_getpreviewimage: Get the preview image.                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_getpreviewimage(previewid);                                  #
+#                                                                              #
+# previewid            Specifies the picture ID.                               #
+#################################################################################
+       
+       # Get the values from the subroutine.
+       
+       my $pictureid = shift;
+       my $dontclear = shift;
+       
+       if (!$dontclear){
+       
+               $dontclear = 0;
+               
+       }
+       
+       # Return an error message if picture ID is blank.
+       
+       if (!$pictureid){
+       
+               xestiascan_error("blankpictureid");
+               
+       }
+       
+       xestiascan_error("invalidpictureid") if xestiascan_variablecheck($pictureid, "numbers", 0, 1) eq 1;
+       
+       print "Content-Type: image/png\r\n\r\n";
+       
+       binmode(STDOUT, ":bytes");
+       
+       my $imgfh;
+       open($imgfh, "/tmp/xestiascanserver-preview-" . $pictureid . ".png");
+       my @lines = <$imgfh>;
+       print @lines;
+       close ($imgfh);
+       
+       unlink("/tmp/xestiascanserver-preview-" . $pictureid . ".png") if $dontclear < 1;
+       
+}      
+
+sub xestiascan_scan_getscannerlist{
+#################################################################################
+# xestiascan_scan_getscannerlist: Gets the list of available scanners.         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_getscannerlist;                                              #
+#################################################################################      
+       
+       my %scannerlist;
+       my $scanner;
+       
+       tie(%scannerlist, 'Tie::IxHash');
+       
+       foreach $scanner (Sane->get_devices){
+               $scannerlist{$scanner->{'name'}}{name}          = $scanner->{'name'};
+               $scannerlist{$scanner->{'name'}}{model}         = $scanner->{'model'};
+               $scannerlist{$scanner->{'name'}}{vendor}        = $scanner->{'vendor'};
+               #       if ($scanner->{'name'} eq $http_scannerdevice){
+               #               print "<option value=\"" . $scanner->{'name'}  . "\" 
+               #selected=selected>" . $scanner->{'vendor'} . ": " . $scanner->{'model'} . "</option>";
+               #       } else {
+               #               print "<option value=\"" . $scanner->{'name'}  . "\">" . 
+               #$scanner->{'vendor'} . ": " . $scanner->{'model'} . "</option>";
+               #       }
+       }
+       
+       return %scannerlist;
+       
+}
+
+sub xestiascan_scan_getscannervalue{
+#################################################################################
+# xestiascan_scan_getscannervalue: Gets a specific option value.               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_getscannervalue(name);                                       #
+#                                                                              #
+# name                 Specifies the name of option.                           #
+#################################################################################
+       
+       my $option_name = shift;
+       
+       my $option_value;
+       my $option_found = 0;
+       my $value = 0;
+       
+       my $option_total = $scan_device->get_option(0);
+       my $option_seek = 0;
+       
+       my $option;
+       
+       do {
+               
+               $option = $scan_device->get_option_descriptor($option_seek);
+               
+               if (!$option->{name}){
+                       
+               } else {
+                       
+                       if ($option_name eq $option->{name}){
+                               
+                               if ($option->{type} eq SANE_TYPE_FIXED){
+                                       $value = $scan_device->get_option($option_seek);
+                                       $value = int(0) if !$value;
+                               } else {
+                                       $value = $scan_device->get_option($option_seek);
+                               }
+                               $option_found = 1;
+                               
+                       }
+                       
+               }
+               
+               $option_seek++;
+               
+       } until ($option_seek > $option_total || $option_found eq 1);
+
+       return $value;
+       
+}
+
+sub xestiascan_scan_setscannervalue{
+#################################################################################
+# xestiascan_scan_setscannervalue: Gets a specific option value.               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_scan_setscannervalue(name, value);                                        #
+#                                                                              #
+# name                 Specifies the name of the option.                       #
+# value                        Specifies the value of the option.                      #
+#################################################################################
+       
+       my $option_name         = shift;
+       my $option_value        = shift;
+       
+       my $option_total = $scan_device->get_option(0);
+       my $option_seek = 0;
+       
+       my $option_found = 0;
+       
+       my $option_final_value;
+       
+       my $option;
+       
+       do {
+               
+               $option = $scan_device->get_option_descriptor($option_seek);
+               
+               if ($option_name eq $option->{name}){
+                       
+                       if ($option->{type} eq SANE_TYPE_FIXED){
+
+                               $scan_device->set_option($option_seek, $option_value) or return;
+                               
+                       } else {
+                       
+                               $scan_device->set_option($option_seek, $option_value) or return;
+                               
+                       }
+                       
+                       $option_found = 1;
+                       
+               }
+               
+               $option_seek++;
+               
+       } until ($option_seek > $option_total || $option_found eq 1);
+       
+       return 1;       # Setting set successfully.
+       
+}
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/System/Settings.pm b/cgi-files/Modules/System/Settings.pm
new file mode 100644 (file)
index 0000000..5d2ea52
--- /dev/null
@@ -0,0 +1,1372 @@
+#################################################################################
+# Xestia Scanner Server - Settings System Module                               #
+# Version 0.1.0                                                                        #
+#                                                                              #
+# Copyright (C) 2010-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+package Modules::System::Settings;
+
+use Modules::System::Common;
+use Modules::System::Scan;
+use strict;
+use warnings;
+use Exporter;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(xestiascan_settings_view xestiascan_settings_edit xestiascan_output_config); 
+
+sub xestiascan_settings_getauthmodules{
+#################################################################################
+# xestiascan_settings_getauthmodules: Gets the list of available authentication        #
+#                                    modules.                                  #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# @authmodules = xestiascan_settings_getauthmodules;                           #
+#################################################################################
+       
+       my (@authmoduleslist, @authmoduleslist_final);
+       my $authmodulefile;
+       
+       opendir(AUTHMODULEDIR, "Modules/Auth");
+       @authmoduleslist = grep /m*\.pm$/, sort(readdir(AUTHMODULEDIR));
+       closedir(AUTHMODULEDIR);
+       
+       foreach $authmodulefile (@authmoduleslist){
+               next if $authmodulefile =~ m/^\./;
+               next if $authmodulefile !~ m/.pm$/;
+               $authmodulefile =~ s/.pm$//;
+               push(@authmoduleslist_final, $authmodulefile);
+       }
+       
+       return @authmoduleslist_final;
+       
+}
+
+sub xestiascan_settings_getpresmodules{
+#################################################################################
+# xestiascan_settings_getpresmodules: Gets the list of available presentation  #
+#                                    modules.                                  #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# @presmodules = xestiascan_settings_getpresmodules;                           #
+#################################################################################
+       
+       my (@presmoduleslist, @presmoduleslist_final);
+       my $presmodulefile;
+       
+       opendir(PRESMODULEDIR, "Modules/Presentation");
+       @presmoduleslist = grep /m*\.pm$/, sort(readdir(PRESMODULEDIR));
+       closedir(PRESMODULEDIR);
+       
+       foreach $presmodulefile (@presmoduleslist){
+               next if $presmodulefile =~ m/^\./;
+               next if $presmodulefile !~ m/.pm$/;
+               $presmodulefile =~ s/.pm$//;
+               push(@presmoduleslist_final, $presmodulefile);
+       }
+       
+       return @presmoduleslist_final;
+       
+}
+
+sub xestiascan_settings_getlanguages{
+#################################################################################
+# xestiascan_settings_getlanguages: Gets the list of available languages.      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# @languages = xestiascan_settings_getlanguages;                               #
+#################################################################################
+       
+       my (@langmoduleslist, @langmoduleslist_final);
+       my $langmodulefile;
+       
+       opendir(LANGUAGESDIR, "lang");
+       @langmoduleslist = grep /m*\.lang$/, sort(readdir(LANGUAGESDIR));
+       closedir(LANGUAGESDIR);
+       
+       foreach $langmodulefile (@langmoduleslist){
+               next if $langmodulefile =~ m/^\./;
+               next if $langmodulefile !~ m/.lang$/;
+               $langmodulefile =~ s/.lang$//;
+               push(@langmoduleslist_final, $langmodulefile);
+       }
+       
+       return @langmoduleslist_final;
+       
+}
+
+sub xestiascan_settings_view{
+#################################################################################
+# xestiascan_options_view: Writes out the list of options and variables.               #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_settings_view();                                                  #
+#################################################################################
+       
+       # Connect to the database server.
+       
+       $main::xestiascan_authmodule->connect();
+       
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       my $access_viewsettings = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+       
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       if ($access_viewsettings ne 1){
+               
+               # User not allowed to perform this action so return an error.
+               xestiascan_error("notpermitted");
+               
+       }
+       
+       # Disconnect from the database server.
+       
+       $main::xestiascan_authmodule->disconnect();
+       
+       # Get the settings.
+
+       my $settings_noncgi_images              = $main::xestiascan_config{"directory_noncgi_images"};
+       my $settings_noncgi_scans               = $main::xestiascan_config{"directory_noncgi_scans"};
+       my $settings_fs_scans                   = $main::xestiascan_config{"directory_fs_scans"};
+       my $settings_system_datetime            = $main::xestiascan_config{"system_datetime"};
+       my $settings_system_language            = $main::xestiascan_config{"system_language"};
+       my $settings_system_presentation        = $main::xestiascan_config{"system_presmodule"};
+       my $settings_system_auth                = $main::xestiascan_config{"system_authmodule"};
+       my $settings_system_output              = $main::xestiascan_config{"system_outputmodule"};
+
+       $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{viewsettings});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");    
+
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "settings");
+       $main::xestiascan_presmodule->addbutton("action", { Value => "edit", Description => $main::xestiascan_lang{setting}{editsettings} });
+       $main::xestiascan_presmodule->endform();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{currentsettings});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->starttable("", { CellPadding => 5, CellSpacing => 0 });
+
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{setting}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{value}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{directories});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{imagesuripath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_noncgi_images);
+       $main::xestiascan_presmodule->endcell();
+       $main::main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{scansuripath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_noncgi_scans);
+       $main::xestiascan_presmodule->endcell();
+       $main::main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{scansfspath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_fs_scans);
+       $main::xestiascan_presmodule->endcell();
+       $main::main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{date});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{dateformat});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_system_datetime);
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{language});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{systemlanguage});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_system_language);
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{modules});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{presentationmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_system_presentation);
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{outputmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_system_output);
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{authmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($settings_system_auth);
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->endtable();
+
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{altersettings});
+
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       
+       return $main::xestiascan_presmodule->grab();
+
+}
+
+sub xestiascan_settings_edit{
+#################################################################################
+# xestiascan_settings_edit: Edits the options.                                 #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_settings_edit(options);                                           #
+#                                                                              #
+# options              Specifies the following options in any order.           #
+#                                                                              #
+# ScansURIPath         Specifies the new URI path for scanned images.          #
+# ScansFSPath          Specifies the new filesystem path for scanned images.   #
+# DateTimeFormat       Specifies the new date and time format to use.          #
+# ImagesURIPath                Specifies the new URI path for images.                  #
+# DateTimeFormat       Specifies the new date and time format.                 #
+# SystemLanguage       Specifies the new language to use for Xestia Scanner    #
+#                      Server.                                                 #
+# PrsentationModule    Specifies the new presentation module to use for        #
+#                      Xestia Scanner Server.                                  #
+# AuthModule           Specifies the new authentication module to use for      #
+#                      Xestia Scanner Server.                                  #
+# OutputModule         Specifies the new output module to use for Xestia       #
+#                      Scanner Server.                                         #
+#                                                                              #
+# Options for server-based authentication modules.                             #
+#                                                                              #
+# DatabaseServer       Specifies the database server to use.                   #
+# DaravasePort         Specifies the port the database server is running on.   #
+# DatabaseProtocol     Specifies the protocol the database server is using.    #
+# DatabaseSQLDatabase  Specifies the SQL database name to use.                 #
+# DatabaseUsername     Specifies the database server username.                 #
+# DatabasePasswordKeep Keeps the current password in the configuration file.   #
+# DatabasePassword     Specifies the password for the database server username.#
+# DatabaseTablePrefix  Specifies the prefix used for tables.                   #
+#################################################################################
+
+       # Get the values that have been passed to the subroutine.
+
+       my ($passedoptions) = @_;
+
+       # Get the values from the hash.
+
+       my $settings_imagesuri                  = $passedoptions->{"ImagesURIPath"};
+       my $settings_scansuri                   = $passedoptions->{"ScansURIPath"};
+       my $settings_scansfs                    = $passedoptions->{"ScansFSPath"};
+       my $settings_datetimeformat             = $passedoptions->{"DateTimeFormat"};
+       my $settings_languagesystem             = $passedoptions->{"SystemLanguage"};
+       my $settings_presmodule                 = $passedoptions->{"PresentationModule"};
+       my $settings_outputmodule               = $passedoptions->{"OutputModule"};
+       my $settings_authmodule                 = $passedoptions->{"AuthModule"};
+
+       my $settings_database_server            = $passedoptions->{"DatabaseServer"};
+       my $settings_database_port              = $passedoptions->{"DatabasePort"};
+       my $settings_database_protocol          = $passedoptions->{"DatabaseProtocol"};
+       my $settings_database_sqldatabase       = $passedoptions->{"DatabaseSQLDatabase"};
+       my $settings_database_username          = $passedoptions->{"DatabaseUsername"};
+       my $settings_database_passwordkeep      = $passedoptions->{"DatabasePasswordKeep"};
+       my $settings_database_password          = $passedoptions->{"DatabasePassword"};
+       my $settings_database_tableprefix       = $passedoptions->{"DatabaseTablePrefix"};
+
+       my $confirm                             = $passedoptions->{"Confirm"};
+
+       # Connect to the database server.
+       
+       $main::xestiascan_authmodule->connect();
+       
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       my $access_editsettings = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+       
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       if ($access_editsettings ne 1){
+               
+               # User not allowed to perform this action so return an error.
+               xestiascan_error("notpermitted");
+               
+       }
+       
+       # Disconnect from the database server.
+       
+       $main::xestiascan_authmodule->disconnect();
+       
+       if (!$confirm){
+
+               # If the confirm value is blank, then set the confirm
+               # value to 0.
+
+               $confirm = 0;
+
+       }
+
+       if ($confirm eq "1"){
+
+               # The action to edit the settings has been confirmed.
+               # Start by checking each variable about to be placed
+               # in the settings file is valid.
+
+               # Deinfe some variables for later.
+
+               my @xestiascan_new_settings;
+
+               # Check the length of the directory names.
+
+               xestiascan_variablecheck($settings_imagesuri, "maxlength", 512, 0);
+               xestiascan_variablecheck($settings_scansuri, "maxlength", 512, 0);
+               xestiascan_variablecheck($settings_scansfs, "maxlength", 4096, 0);
+               xestiascan_variablecheck($settings_datetimeformat, "maxlength", 32, 0);
+
+               xestiascan_variablecheck($settings_languagesystem, "language_filename", "", 0);
+
+               # Check the module names to see if they're valid.
+
+               my $xestiascan_presmodule_modulename_check      = xestiascan_variablecheck($settings_presmodule, "module", 0, 1);
+               my $xestiascan_authmodule_modulename_check              = xestiascan_variablecheck($settings_authmodule, "module", 0, 1);
+               my $xestiascan_outputmodule_modulename_check    = xestiascan_variablecheck($settings_outputmodule, "module", 0, 1);
+
+               if ($xestiascan_presmodule_modulename_check eq 1){
+
+                       # The presentation module name is blank, so return
+                       # an error.
+
+                       xestiascan_error("presmoduleblank");
+
+               }
+
+               if ($xestiascan_presmodule_modulename_check eq 2){
+
+                       # The presentation module name is invalid, so return
+                       # an error.
+
+                       xestiascan_error("presmoduleinvalid");
+
+               }
+
+               if ($xestiascan_authmodule_modulename_check eq 1){
+
+                       # The database module name is blank, so return
+                       # an error.
+
+                       xestiascan_error("authmoduleblank");
+
+               }
+
+               if ($xestiascan_authmodule_modulename_check eq 2){
+
+                       # The database module name is invalid, so return
+                       # an error.
+
+                       xestiascan_error("authmoduleinvalid");
+
+               }
+
+               if ($xestiascan_outputmodule_modulename_check eq 1){
+
+                       # The output module name is blank, so return
+                       # an error.
+
+                       xestiascan_error("outputmoduleblank");
+
+               }
+
+               if ($xestiascan_outputmodule_modulename_check eq 2){
+
+                       # The output module name is invalid, so return
+                       # an error.
+
+                       xestiascan_error("outputmoduleinvalid");
+
+               }
+
+               # Check if the directory names only contain letters and numbers and
+               # return a specific error if they don't.
+
+               xestiascan_variablecheck($settings_datetimeformat, "datetime", 0, 0);
+
+               # Check if the presentation module with the filename given exists.
+
+               my $presmodule_exists = xestiascan_fileexists("Modules/Presentation/" . $settings_presmodule . ".pm");
+
+               if ($presmodule_exists eq 1){
+
+                       # The presentation module does not exist so return an error.
+
+                       xestiascan_error("presmodulemissing");
+
+               }
+
+               # Check if the database module with the filename given exists.
+
+               my $authmodule_exists = xestiascan_fileexists("Modules/Auth/" . $settings_authmodule . ".pm");
+
+               if ($authmodule_exists eq 1){
+
+                       # The database module does not exist so return an error.
+
+                       xestiascan_error("dbmodulemissing");
+
+               }
+
+               # Check if the language filename given exists.
+
+               my $languagefile_exists = xestiascan_fileexists("lang/" . $settings_languagesystem . ".lang");
+
+               if ($languagefile_exists eq 1){
+
+                       # The language filename given does not exist so return an error.
+
+                       xestiascan_error("languagefilenamemissing");            
+
+               }
+
+               # Check the database server options to see if they are valid.
+
+               my $xestiascan_databaseserver_length_check              = xestiascan_variablecheck($settings_database_server, "maxlength", 128, 1);
+               my $xestiascan_databaseserver_lettersnumbers_check      = xestiascan_variablecheck($settings_database_server, "lettersnumbers", 0, 1);
+               my $xestiascan_databaseport_length_check                        = xestiascan_variablecheck($settings_database_port, "maxlength", 5, 1);
+               my $xestiascan_databaseport_numbers_check               = xestiascan_variablecheck($settings_database_port, "numbers", 0, 1);
+               my $xestiascan_databaseport_port_check                  = xestiascan_variablecheck($settings_database_port, "port", 0, 1);
+               my $xestiascan_databaseprotocol_length_check            = xestiascan_variablecheck($settings_database_protocol, "maxlength", 5, 1);
+               my $xestiascan_databaseprotocol_protocol_check          = xestiascan_variablecheck($settings_database_protocol, "serverprotocol", 0, 1);
+               my $xestiascan_databasename_length_check                        = xestiascan_variablecheck($settings_database_sqldatabase, "maxlength", 32, 1);
+               my $xestiascan_databasename_lettersnumbers_check                = xestiascan_variablecheck($settings_database_sqldatabase, "lettersnumbers", 0, 1);
+               my $xestiascan_databaseusername_length_check            = xestiascan_variablecheck($settings_database_username, "maxlength", 16, 1);
+               my $xestiascan_databaseusername_lettersnumbers_check    = xestiascan_variablecheck($settings_database_username, "lettersnumbers", 0, 1);
+               my $xestiascan_databasepassword_length_check            = xestiascan_variablecheck($settings_database_password, "maxlength", 64, 1);
+               my $xestiascan_databasetableprefix_length_check         = xestiascan_variablecheck($settings_database_tableprefix, "maxlength", 16, 1);
+               my $xestiascan_databasetableprefix_lettersnumbers_check = xestiascan_variablecheck($settings_database_tableprefix, "lettersnumbers", 0, 1);
+
+               if ($xestiascan_databaseserver_length_check eq 1){
+
+                       # The length of the database server name is too long so
+                       # return an error.
+
+                       xestiascan_error("servernametoolong");
+
+               }
+
+               if ($xestiascan_databaseserver_lettersnumbers_check eq 1){
+
+                       # The database server name contains characters other
+                       # than letters and numbers, so return an error.
+
+                       xestiascan_error("servernameinvalid");
+
+               }
+
+               if ($xestiascan_databaseport_length_check eq 1){
+
+                       # The database port number length is too long so return
+                       # an error.
+
+                       xestiascan_error("serverportnumbertoolong");
+
+               }
+
+               if ($xestiascan_databaseport_numbers_check eq 1){
+
+                       # The database port number contains characters other
+                       # than numbers so return an error.
+
+                       xestiascan_error("serverportnumberinvalidcharacters");
+
+               }
+
+               if ($xestiascan_databaseport_port_check eq 1){
+
+                       # The database port number given is invalid so return
+                       # an error.
+
+                       xestiascan_error("serverportnumberinvalid");
+
+               }
+
+               if ($xestiascan_databaseprotocol_length_check eq 1){
+
+                       # The database protocol name given is too long so
+                       # return an error.
+
+                       xestiascan_error("serverprotocolnametoolong");
+
+               }
+
+               if ($xestiascan_databaseprotocol_protocol_check eq 1){
+
+                       # The server protcol given is invalid so return
+                       # an error.
+
+                       xestiascan_error("serverprotocolinvalid");
+
+               }
+
+               if ($xestiascan_databasename_length_check eq 1){
+
+                       # The SQL database name is too long so return
+                       # an error.
+
+                       xestiascan_error("serverdatabasenametoolong");
+
+               }
+
+               if ($xestiascan_databasename_lettersnumbers_check eq 1){
+
+                       # The database name contains invalid characters
+                       # so return an error.
+
+                       xestiascan_error("serverdatabasenameinvalid");
+
+               }
+
+               if ($xestiascan_databaseusername_length_check eq 1){
+
+                       # The database username given is too long so
+                       # return an error.
+
+                       xestiascan_error("serverdatabaseusernametoolong");
+
+               }
+
+               if ($xestiascan_databaseusername_lettersnumbers_check eq 1){
+
+                       # The database username contains invalid characters
+                       # so return an error.
+
+                       xestiascan_error("serverdatabaseusernameinvalid");
+
+               }
+
+               if ($xestiascan_databasepassword_length_check eq 1){
+
+                       # The database password given is too long so return
+                       # an error.
+
+                       xestiascan_error("serverdatabasepasswordtoolong");
+
+               }
+
+               if ($xestiascan_databasetableprefix_length_check eq 1){
+
+                       # The database table prefix given is too long so
+                       # return an error.
+
+                       xestiascan_error("serverdatabasetableprefixtoolong");
+
+               }
+
+               if ($xestiascan_databasetableprefix_lettersnumbers_check eq 1){
+
+                       # The database table prefix given contains invalid
+                       # characters so return an error.
+
+                       xestiascan_error("serverdatabasetableprefixinvalid");
+
+               }
+
+               # Check if the current password should be kept.
+
+               if ($settings_database_passwordkeep eq "on"){
+
+                       # The current password in the configuration file should be used.
+
+                       $settings_database_password     = $main::xestiascan_config{"database_password"};
+
+               }
+
+               # Write the new settings to the configuration file.
+
+               xestiascan_output_config({ ImagesURIPath => $settings_imagesuri,
+                       ScansURIPath => $settings_scansuri,
+                       ScansFSPath => $settings_scansfs,
+                       DateTimeFormat => $settings_datetimeformat, 
+                       SystemLanguage => $settings_languagesystem, 
+                       PresentationModule => $settings_presmodule, 
+                       OutputModule => $settings_outputmodule, 
+                       AuthModule => $settings_authmodule, 
+                       DatabaseServer => $settings_database_server, 
+                       DatabasePort => $settings_database_port, 
+                       DatabaseProtocol => $settings_database_protocol, 
+                       DatabaseSQLDatabase => $settings_database_sqldatabase, 
+                       DatabaseUsername => $settings_database_username, 
+                       DatabasePassword => $settings_database_password, 
+                       DatabaseTablePrefix => $settings_database_tableprefix 
+               });
+
+               # Write a confirmation message.
+
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{settingsedited}, { Style => "pageheader" });
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{settingseditedmessage});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"} . "?mode=settings", { Text => $main::xestiascan_lang{setting}{returnsettingslist} });
+
+               return $main::xestiascan_presmodule->grab();
+
+       }
+
+       # Get the list of languages available.
+
+       my %language_list;
+       my @language_directory          = "";
+       my $language;
+       my ($language_file, %language_file);
+       my $language_filename           = "";
+       my $language_file_localname     = "";
+       my $language_file_count         = 0;
+       my $language_config             = $main::xestiascan_config{"system_language"};
+       my @lang_data;
+       my $xestiascan_languagefilehandle;
+
+       tie(%language_list, 'Tie::IxHash');
+
+       @language_directory = xestiascan_settings_getlanguages;
+       
+       # Process each language by loading the language file
+       # used for each language and then get the System name and 
+       # the local name of the language.
+       
+       foreach $language_filename (@language_directory){
+               
+               # Load the language file currently selected.
+               
+               open($xestiascan_languagefilehandle, "lang/" . $language_filename . ".lang");
+               @lang_data = <$xestiascan_languagefilehandle>;
+               %language_file = xestiascan_processconfig(@lang_data);
+               close($xestiascan_languagefilehandle);
+
+               # Get the system name and the local name of the language.
+
+               $language_file_localname = $language_file{about}{name};
+
+               # Check if either the system name or the local name of the language
+               # is blank and if it is, then don't add the language to the list.
+
+               if (!$language_file_localname){
+
+                       # The system name or the local name is blank so don't add
+                       # the language to the list.
+               
+               } else {
+
+                       # Append the language to the available languages list.
+
+                       $language_list{$language_file_count}{Filename} = $language_filename;
+                       $language_list{$language_file_count}{Name} = $language_file_localname;
+                       $language_file_count++;
+
+               }
+
+               undef $language_file;
+
+       }
+
+       # Get the list of presentation modules available.
+
+       my %presmodule_list;
+       my @presmodule_directory;
+       my $presmodule;
+       my $presmodule_file             = "";
+       my $presmodule_count            = 0;
+       my $presmodule_config           = $main::xestiascan_config{"system_presmodule"};
+
+       # Open and get the list of presentation modules (perl modules) by getting
+       # only files which end in .pm.
+
+       @presmodule_directory = xestiascan_settings_getpresmodules;
+
+       foreach $presmodule_file (@presmodule_directory){
+               
+               $presmodule_list{$presmodule_count}{Filename} = $presmodule_file;
+               $presmodule_count++;
+
+       }
+
+       # Get the list of database modules available.
+
+       my %authmodule_list;
+       my @authmodule_directory;
+       my $authmodule;
+       my $authmodule_file             = "";
+       my $authmodule_count            = 0;
+       my $authmodule_config           = $main::xestiascan_config{"system_authmodule"};
+
+       # Open and get the list of database modules (perl modules) by getting
+       # only files which end in .pm.
+
+       @authmodule_directory = xestiascan_settings_getauthmodules;
+
+       foreach $authmodule_file (@authmodule_directory){
+
+               $authmodule_list{$authmodule_count}{Filename} = $authmodule_file;
+               $authmodule_count++;
+
+       }
+
+       my %outputmodule_list;
+       my @outputmodule_directory;
+       my $outputmodule;
+       my $outputmodule_file           = "";
+       my $outputmodule_count          = 0;
+       my $outputmodule_config         = $main::xestiascan_config{"system_outputmodule"};
+
+       # Open and get the list of output modules (perl modules) by getting
+       # only files which end in .pm.
+
+       @outputmodule_directory = xestiascan_scan_getoutputmodules;
+
+       foreach $outputmodule_file (@outputmodule_directory){
+
+               $outputmodule_list{$outputmodule_count}{Filename} = $outputmodule_file;
+               $outputmodule_count++;
+
+       }
+
+       # Get the directory settings.
+
+       my $directory_settings_imagesuri        = $main::xestiascan_config{"directory_noncgi_images"};
+       my $directory_settings_scansuri         = $main::xestiascan_config{"directory_noncgi_scans"};
+       my $directory_settings_scansfs          = $main::xestiascan_config{"directory_fs_scans"};
+       my $datetime_setting                    = $main::xestiascan_config{"system_datetime"};
+
+       my $database_server                     = $main::xestiascan_config{"database_server"};
+       my $database_port                       = $main::xestiascan_config{"database_port"};
+       my $database_protocol                   = $main::xestiascan_config{"database_protocol"};
+       my $database_sqldatabase                = $main::xestiascan_config{"database_sqldatabase"};
+       my $database_username                   = $main::xestiascan_config{"database_username"};
+       my $database_passwordhash               = $main::xestiascan_config{"database_passwordhash"};
+       my $database_password                   = $main::xestiascan_config{"database_password"};
+       my $database_prefix                     = $main::xestiascan_config{"database_tableprefix"};
+
+       # Print out a form for editing the settings.
+
+       $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{editsettings});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{setting}{warning});
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{warningmessage});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->startbox();
+       $main::xestiascan_presmodule->addhiddendata("mode", "settings");
+       $main::xestiascan_presmodule->addhiddendata("action", "edit");
+       $main::xestiascan_presmodule->addhiddendata("confirm", 1);
+
+       $main::xestiascan_presmodule->starttable("", { CellPadding => 5, CellSpacing => 0 });
+
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{setting}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{value}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{directories});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{imagesuripath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("imagesuripath", { Size => 32, MaxLength => 512, Value => $directory_settings_imagesuri });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{scansuripath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("scansuripath", { Size => 32, MaxLength => 512, Value => $directory_settings_scansuri });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{scansfspath});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("scansfspath", { Size => 64, MaxLength => 4096, Value => $directory_settings_scansfs });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{date});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{dateformat});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("datetime", { Size => 32, MaxLength => 64, Value => $datetime_setting });
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->startbox("datalist");
+
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singleday});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doubleday});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singlemonth});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doublemonth});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singleyear});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doubleyear});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singlehour});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doublehour});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singleminute});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doubleminute});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{singlesecond});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{doublesecond});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{othercharacters});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{language});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{systemlanguage});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+
+       $main::xestiascan_presmodule->addselectbox("language");
+
+       # Process the list of available languages.
+
+       foreach $language (keys %language_list){
+
+               # Check if the language filename matches the filename in the configuration
+               # file.
+
+               if ($language_list{$language}{Filename} eq $language_config){
+
+                       $main::xestiascan_presmodule->addoption($language_list{$language}{Name}, { Value => $language_list{$language}{Filename} , Selected => 1 });
+
+               } else {
+
+                       $main::xestiascan_presmodule->addoption($language_list{$language}{Name}, { Value => $language_list{$language}{Filename} });
+
+               }
+
+       }
+
+       $main::xestiascan_presmodule->endselectbox();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{modules});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecellheader");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{presentationmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+
+       $main::xestiascan_presmodule->addselectbox("presmodule");
+
+       # Process the list of available presentation modules.
+
+       foreach $presmodule (keys %presmodule_list){
+
+               # Check if the presentation module fileanme matches the filename in the 
+               # configuration file.
+
+               if ($presmodule_list{$presmodule}{Filename} eq $presmodule_config){
+
+                       $main::xestiascan_presmodule->addoption($presmodule_list{$presmodule}{Filename}, { Value => $presmodule_list{$presmodule}{Filename} , Selected => 1 });
+
+               } else {
+
+                       $main::xestiascan_presmodule->addoption($presmodule_list{$presmodule}{Filename}, { Value => $presmodule_list{$presmodule}{Filename} });
+
+               }
+
+       }
+
+       $main::xestiascan_presmodule->endselectbox();
+
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{outputmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+
+       # Process the list of available output modules.
+
+       $main::xestiascan_presmodule->addselectbox("outputmodule");
+
+       foreach $outputmodule (keys %outputmodule_list){
+
+               # Check if the output module fileanme matches the filename in the 
+               # configuration file.
+
+               if ($outputmodule_list{$outputmodule}{Filename} eq $outputmodule_config){
+
+                       $main::xestiascan_presmodule->addoption($outputmodule_list{$outputmodule}{Filename}, { Value => $outputmodule_list{$outputmodule}{Filename} , Selected => 1 });
+
+               } else {
+
+                       $main::xestiascan_presmodule->addoption($outputmodule_list{$outputmodule}{Filename}, { Value => $outputmodule_list{$outputmodule}{Filename} });
+
+               }
+
+
+       }
+
+       $main::xestiascan_presmodule->endselectbox();
+
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{authmodule});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+
+       # Process the list of available database modules.
+
+       $main::xestiascan_presmodule->addselectbox("authmodule");
+
+       foreach $authmodule (keys %authmodule_list){
+
+               # Check if the database module fileanme matches the filename in the 
+               # configuration file.
+
+               if ($authmodule_list{$authmodule}{Filename} eq $authmodule_config){
+
+                       $main::xestiascan_presmodule->addoption($authmodule_list{$authmodule}{Filename}, { Value => $authmodule_list{$authmodule}{Filename} , Selected => 1 });
+
+               } else {
+
+                       $main::xestiascan_presmodule->addoption($authmodule_list{$authmodule}{Filename}, { Value => $authmodule_list{$authmodule}{Filename} });
+
+               }
+
+
+       }
+
+       $main::xestiascan_presmodule->endselectbox();
+
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databaseserver});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_server", { Size => 32, MaxLength => 128, Value => $database_server });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databaseport});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_port", { Size => 5, MaxLength => 5, Value => $database_port });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databaseprotocol});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+
+       # Check if TCP is being used.
+
+       $main::xestiascan_presmodule->addselectbox("database_protocol");
+
+       if ($database_protocol eq "tcp"){
+
+               # The TCP protocol is selected so have the TCP option selected.
+
+               $main::xestiascan_presmodule->addoption("TCP", { Value => "tcp", Selected => 1});
+
+       } else {
+
+               # The TCP protocol is not selected.
+
+               $main::xestiascan_presmodule->addoption("TCP", { Value => "tcp"});
+
+       } 
+
+       # Check if UDP is being used.
+
+       if ($database_protocol eq "udp"){
+
+               # The UDP protocol is selected so have the UDP option selected.
+
+               $main::xestiascan_presmodule->addoption("UDP", { Value => "udp", Selected => 1});
+
+       } else {
+
+               # The UDP protocol is not selected.
+
+               $main::xestiascan_presmodule->addoption("UDP", { Value => "udp"});
+
+       }
+
+       $main::xestiascan_presmodule->endselectbox();
+
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databasename});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_sqldatabase", { Size => 32, MaxLength => 32, Value => $database_sqldatabase });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databaseusername});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_username", { Size => 16, MaxLength => 16, Value => $database_username });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{databasepassword});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_password", { Size => 16, MaxLength => 64, Password => 1 });
+       $main::xestiascan_presmodule->addtext(" ");
+       $main::xestiascan_presmodule->addcheckbox("database_password_keep", { OptionDescription => $main::xestiascan_lang{setting}{keepcurrentpassword}, Checked => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{setting}{tableprefix});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("database_tableprefix", { Size => 16, MaxLength => 16, Value => $database_prefix });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+
+       $main::xestiascan_presmodule->endtable();
+
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{setting}{changesettingsbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{restorecurrent});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"} . "?mode=settings", { Text => $main::xestiascan_lang{setting}->{returnsettingslist} });
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endform();
+
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       
+       return $main::xestiascan_presmodule->grab();
+
+} 
+
+sub xestiascan_output_config{
+#################################################################################
+# xestiascan_output_config: Outputs the configuration file.                    #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_output_config(settings);                                          #
+#                                                                              #
+# settings     Specifies the following settings in any order.                  #
+#                                                                              #
+# Settings for Xesita Scanner Server configuration files:                      #
+#                                                                              #
+# ImagesURIPath                Specifies the new URI path for images.                  #
+# ScansURIPath         Specifies the new URI path for scans.                   #
+# ScansFSPath          Specifies the new filesystem path for scans.            #
+# DateTimeFormat       Specifies the new date and time format.                 #
+# SystemLanguage       Specifies the new language to use for Xestia Scanner    #
+#                      Server.                                                 #
+# PrsentationModule    Specifies the new presentation module to use for        #
+#                      Xestia Scanner Server.                                  #
+# OutputModule         Specifies the new output module to use for Xestia       #
+#                      Scanner Server.                                         #
+# AuthModule           Specifies the new authentication module to use for      #
+#                      Xestia Scanner Server.                                  #
+# DatabaseServer       Specifies the database server to use.                   #
+# DaravasePort         Specifies the port the database server is running on.   #
+# DatabaseProtocol     Specifies the protocol the database server is using.    #
+# DatabaseSQLDatabase  Specifies the SQL database name to use.                 #
+# DatabaseUsername     Specifies the database server username.                 #
+# DatabasePassword     Specifies the password for the database server username.#
+# DatabaseTablePrefix  Specifies the table prefix to use.                      #
+#################################################################################
+
+       # Get the variables passed from the subroutine.
+
+       my ($passedsettings)    = @_;
+
+       # Get the data from the hash.
+
+       my $settings_imagesuri                  = $passedsettings->{"ImagesURIPath"};
+       my $settings_scansuri                   = $passedsettings->{"ScansURIPath"};
+       my $settings_scansfs                    = $passedsettings->{"ScansFSPath"};
+       my $settings_datetime                   = $passedsettings->{"DateTimeFormat"};
+       my $settings_systemlanguage             = $passedsettings->{"SystemLanguage"};
+       my $settings_presmodule                 = $passedsettings->{"PresentationModule"};
+       my $settings_outputmodule               = $passedsettings->{"OutputModule"};
+       my $settings_authmodule                 = $passedsettings->{"AuthModule"};
+
+       my $settings_database_server            = $passedsettings->{"DatabaseServer"};
+       my $settings_database_port              = $passedsettings->{"DatabasePort"};
+       my $settings_database_protocol          = $passedsettings->{"DatabaseProtocol"};
+       my $settings_database_sqldatabase       = $passedsettings->{"DatabaseSQLDatabase"};
+       my $settings_database_username          = $passedsettings->{"DatabaseUsername"};
+       my $settings_database_password          = $passedsettings->{"DatabasePassword"};
+       my $settings_database_tableprefix       = $passedsettings->{"DatabaseTablePrefix"};
+
+       # Convert the password to make sure it can be read properly.
+
+       if ($settings_database_password){
+
+               $settings_database_password =~ s/\0//g;
+               $settings_database_password =~ s/</&lt;/g;
+               $settings_database_password =~ s/>/&gt;/g;
+
+       }
+
+       # Convert the less than and greater than characters are there and
+       # convert them.
+
+       if ($settings_imagesuri){
+
+               $settings_imagesuri =~ s/</&lt;/g;
+               $settings_imagesuri =~ s/>/&gt;/g;
+               $settings_imagesuri =~ s/\r//g;
+               $settings_imagesuri =~ s/\n//g;
+
+       }
+
+       if ($settings_scansuri){
+               
+               $settings_scansuri =~ s/</&lt;/g;
+               $settings_scansuri =~ s/>/&gt;/g;
+               $settings_scansuri =~ s/\r//g;
+               $settings_scansuri =~ s/\n//g;
+               
+       }
+       
+       if ($settings_scansfs){
+               
+               $settings_scansfs =~ s/</&lt;/g;
+               $settings_scansfs =~ s/>/&gt;/g;
+               $settings_scansfs =~ s/\r//g;
+               $settings_scansfs =~ s/\n//g;
+               
+       }
+
+       # Check if the database password value is undefined and if it is then
+       # set it blank.
+
+       if (!$settings_database_password){
+
+               $settings_database_password = "";
+
+       }
+
+       # Create the Xestia Scanner Server configuration file layout.
+
+       my $configdata = "[config]\r\n";
+
+       $configdata = $configdata . "directory_noncgi_images = "  . $settings_imagesuri . "\r\n";
+       $configdata = $configdata . "directory_noncgi_scans = "  . $settings_scansuri . "\r\n";
+       $configdata = $configdata . "directory_fs_scans = "  . $settings_scansfs . "\r\n\r\n";
+
+       $configdata = $configdata . "system_language = "  . $settings_systemlanguage . "\r\n";
+       $configdata = $configdata . "system_presmodule = "  . $settings_presmodule . "\r\n";
+       $configdata = $configdata . "system_authmodule = "  . $settings_authmodule . "\r\n";
+       $configdata = $configdata . "system_outputmodule = "  . $settings_outputmodule . "\r\n";
+       $configdata = $configdata . "system_datetime = "  . $settings_datetime . "\r\n\r\n";
+
+       $configdata = $configdata . "database_server = "  . $settings_database_server . "\r\n";
+       $configdata = $configdata . "database_port = "  . $settings_database_port . "\r\n";
+       $configdata = $configdata . "database_protocol = "  . $settings_database_protocol . "\r\n";
+       $configdata = $configdata . "database_sqldatabase = "  . $settings_database_sqldatabase . "\r\n";
+       $configdata = $configdata . "database_username = "  . $settings_database_username . "\r\n";
+       $configdata = $configdata . "database_password = "  . $settings_database_password . "\r\n";
+       $configdata = $configdata . "database_tableprefix = "  . $settings_database_tableprefix . "\r\n\r\n";
+
+       # Open the Xestia Scanner Server configuration file, write the new 
+       # settings to the configuration file and make sure the file
+       # permissions are set to the correct value.
+
+       open(my $filehandle_config, "> ", "xsdss.cfg");
+       print $filehandle_config $configdata;
+       close($filehandle_config);
+       chmod(0660, "xsdss.cfg");
+       
+       return;
+
+};
+
+1;
\ No newline at end of file
diff --git a/cgi-files/Modules/System/Users.pm b/cgi-files/Modules/System/Users.pm
new file mode 100644 (file)
index 0000000..c8a1d70
--- /dev/null
@@ -0,0 +1,2017 @@
+#################################################################################
+# Xestia Scanner Server - Users System Module                                  #
+# Version 0.1.0                                                                        #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+package Modules::System::Users;
+
+use Modules::System::Common;
+use Modules::System::Scan;
+use strict;
+use warnings;
+use Exporter;
+use Sane;
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(xestiascan_users_list xestiascan_users_add xestiascan_users_edit xestiascan_users_delete xestiascan_users_flush);
+
+sub xestiascan_users_list{
+#################################################################################
+# xestiascan_users_list: Get the list of available users.                      #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_users_list(options);                                              #
+#                                                                              #
+# Specifies the following options as a hash (in any order).                    #
+#                                                                              #
+# HideDeactivatedUsers Hide deactivated users.                                 #
+#################################################################################
+
+       # Get the values that have been passed to the subroutine.
+
+       my ($options) = @_;
+
+       my $showdeactivated = 0;
+
+       if ($options->{"ShowDeactivatedUsers"} && $options->{"ShowDeactivatedUsers"} eq 1){
+
+               # Show deactivated users.
+
+               $showdeactivated = 1;
+
+       }
+
+       # Connect to the database server.
+
+       $main::xestiascan_authmodule->connect();
+
+       # Check if any errors occured while connecting to the database server.
+
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+
+               # A database connection error has occured so return
+               # an error.
+
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+
+       }
+
+       # Get the permissions for the user and check if the user is allowed to access this.
+       
+       my $access_userlist = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+    
+       if ($access_userlist ne 1){
+
+               # User not allowed to access the user list so return an error.
+               xestiascan_error("notpermitted");
+
+       }
+
+       my %user_list;
+       my $user_name;
+       my $cssstyle = 0;
+       my $cssname = "";
+
+       # Print the top menu.
+
+       $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{listusers});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");
+       
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "users");
+       
+       $main::xestiascan_presmodule->addbutton("action", { Value => "add", Description => $main::xestiascan_lang{users}{adduser} });
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addbutton("action", { Value => "flush", Description => $main::xestiascan_lang{users}{logoutallusers} });
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addcheckbox("showdeactivated", { OptionDescription => $main::xestiascan_lang{users}{showdeactivated}, Checked => $showdeactivated });
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{users}{update});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->endform();
+
+       # Get the list of users and return a message if the permissions system is
+       # unsupported by this database server type.
+
+       %user_list = $main::xestiascan_authmodule->getuserlist({ Reduced => 1, ShowDeactivated => $showdeactivated });
+
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+
+               # A database error has occured so return an error with
+               # the extended error information.
+
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+
+       }
+
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{username}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{name}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{options}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+
+       foreach $user_name (keys %user_list){
+
+               $main::xestiascan_presmodule->startrow();
+
+               if ($cssstyle eq 0){
+
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+
+               } else {
+
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+
+               }
+
+               $cssname = "tablecelldisabled" if $user_list{$user_name}{deactivated} eq 1;
+
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($user_list{$user_name}{username});
+               $main::xestiascan_presmodule->endcell();
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($user_list{$user_name}{name});
+               $main::xestiascan_presmodule->endcell();
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}  . "?mode=users&action=edit&user=" . $user_list{$user_name}{username}, { Text => $main::xestiascan_lang{options}{edit} });
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}  . "?mode=users&action=delete&user=" . $user_list{$user_name}{username}, { Text => $main::xestiascan_lang{options}{delete} });
+               $main::xestiascan_presmodule->endcell();
+
+               $main::xestiascan_presmodule->endrow();
+
+       }
+
+       $main::xestiascan_presmodule->endtable();
+
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       
+       # Disconnect from the database server.
+
+       $main::xestiascan_authmodule->disconnect();
+
+       return $main::xestiascan_presmodule->grab();
+
+}
+
+sub xestiascan_users_add{
+#################################################################################
+# xestiascan_users_add: Add a user to the user list.                           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_users_add(username, userinfo, scannerinfo, outputmoduleinfo,      #
+#                      exportmoduleinfo, confirm);                             #
+#                                                                              #
+# username             Specifies the username to add to the user list.         #
+# userinfo             Specifies the userinfo as a hashref.                    #
+# scannerinfo          Specifies the scanner permissions as a hashref.         #
+# outputmoduleinfo     Specifies the output module permissions as a hashref.   #
+# exportmoduleinfo     Specifies the export module permissions as a hashref.   #
+# confirm              Confirms the action to add a user to the user list.     #
+#################################################################################
+
+       my $username    = shift;
+       
+       my $passed_userinfo             = shift;
+       my $passed_scannerinfo          = shift;
+       my $passed_outputmoduleinfo     = shift;
+       my $passed_exportmoduleinfo     = shift;
+       
+       my $confirm = shift;
+       
+       $confirm = 0 if !$confirm;
+       
+       # Connect to the database server.
+
+       $main::xestiascan_authmodule->connect();
+
+       # Check if any errors occured while connecting to the database server.
+
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+
+               # A database connection error has occured so return
+               # an error.
+
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+
+       }
+
+       # Check to see if the user has permission to manage users.
+
+       my $access_userlist = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       if ($access_userlist ne 1){
+
+               # User not allowed to access the user list so return an error.
+               xestiascan_error("notpermitted");
+
+       }
+
+       # Check if there is a value in the username value and if there is then
+       # assume a user is being added.
+
+       if ($confirm eq 1){
+               
+               my %final_userinfo              = ();
+               my %final_scannerinfo           = ();
+               my %final_outputmoduleinfo      = ();
+               my %final_exportmoduleinfo      = ();
+               my $hashkey;
+               my $hashkey_short;
+               
+               # De-reference the user information hash.
+               
+               $hashkey = "";
+               
+               foreach $hashkey (keys %$passed_userinfo){
+                       
+                       $final_userinfo{$hashkey} = $$passed_userinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the scanner information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+               
+               foreach $hashkey (keys %$passed_scannerinfo){
+                       
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^scanner_//g;
+                       
+                       $final_scannerinfo{$hashkey_short} = $$passed_scannerinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the output module information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+               
+               foreach $hashkey (keys %$passed_outputmoduleinfo){
+                       
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^outputmodule_//g;
+                       
+                       $final_outputmoduleinfo{$hashkey_short} = $$passed_outputmoduleinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the export module information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+               
+               foreach $hashkey (keys %$passed_exportmoduleinfo){
+                       
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^exportmodule_//g;
+                       
+                       $final_exportmoduleinfo{$hashkey_short} = $$passed_exportmoduleinfo{$hashkey};
+                       
+               }
+               
+               # Check if the username and password are blank and if they are
+               # then return an error.
+               
+               if (!$username){
+                       
+                       xestiascan_error("usernameblank");
+                       
+               }
+               
+               if (!$final_userinfo{Password}){
+                       
+                       xestiascan_error("passwordblank");
+                       
+               }
+               
+               # Check if the password matches with the confirm password value
+               # and return an error if this is not the case.
+               
+               if ($final_userinfo{Password} ne $final_userinfo{ConfirmPassword}){
+               
+                       xestiascan_error("passwordsdonotmatch");
+                       
+               }
+               
+               # Check all the values being passed to this subroutine are UTF-8
+               # valid.
+               
+               xestiascan_variablecheck(xestiascan_utf8convert($username), "utf8", 0, 0);
+               xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Name}), "utf8", 0, 0);
+               xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Password}), "utf8", 0, 0);
+               
+               # Check the length of the username, name and password to make sure
+               # they are valid.
+               
+               my $username_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($username), "maxlength", 64, 1);
+               my $name_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Name}), "maxlength", 256, 1);
+               my $password_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Password}), "maxlength", 128, 1);
+               
+               if ($username_maxlength_check eq 1){
+                       
+                       # Username is too long so return an error.
+                       
+                       xestiascan_error("usernametoolong");
+                       
+               }
+               
+               if ($name_maxlength_check eq 1){
+                       
+                       # Name is too long so return an error.
+                       
+                       xestiascan_error("nametoolong");
+                       
+               }
+               
+               if ($password_maxlength_check eq 1){
+                       
+                       # Password is too long so return an error,
+                       
+                       xestiascan_error("passwordtoolong");
+                       
+               }
+               
+               my $final_scanner;
+               
+               foreach $final_scanner (keys %final_scannerinfo){
+               
+                       # Check to make sure that the scanner name and value
+                       # are both valid UTF8.
+                       
+                       xestiascan_variablecheck($final_scanner, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_scannerinfo{$final_scanner}, "utf8", 0, 0);
+                       
+               }
+               
+               # Check that the export and output modules contain valid UTF8
+               # and are valid filenames.
+               
+               my $final_module;
+               my $module_lettersnumbers_check;
+               
+               foreach $final_module (keys %final_outputmoduleinfo){
+                       
+                       xestiascan_variablecheck($final_module, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_outputmoduleinfo{$final_module}, "utf8", 0, 0);
+                       
+                       $module_lettersnumbers_check = xestiascan_variablecheck($final_module, "lettersnumbers", 0, 1);
+                       xestiascan_error("moduleinvalid", xestiascan_language($main::xestiascan_lang{scan}{nameofoutputmoduleerror}, $final_module)) if $module_lettersnumbers_check eq 1;
+                       
+               }
+               
+               $final_module = "";
+               $module_lettersnumbers_check = 0;
+               
+               foreach $final_module (keys %final_exportmoduleinfo){
+                       
+                       xestiascan_variablecheck($final_module, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_exportmoduleinfo{$final_module}, "utf8", 0, 0);
+                       
+                       $module_lettersnumbers_check = xestiascan_variablecheck($final_module, "lettersnumbers", 0, 1);
+                       xestiascan_error("moduleinvalid", xestiascan_language($main::xestiascan_lang{scan}{nameofexportmoduleerror}, $final_module)) if $module_lettersnumbers_check eq 1;
+                       
+               }
+               
+               # Add the user via adduser and pass the permissions to the 
+               # edituser subroutine for the authentication module.
+               
+               $main::xestiascan_authmodule->adduser($username, %final_userinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               if ($main::xestiascan_authmodule->geterror eq "UserExists"){
+                       
+                       xestiascan_error("userexists");
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "Scanner", %final_scannerinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "OutputModule", %final_outputmoduleinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "ExportModule", %final_exportmoduleinfo);
+               
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               # Disconnect from the database server.
+
+               $main::xestiascan_authmodule->disconnect();
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+
+                       # A database error has occured so return an error with
+                       # the extended error information.
+
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+
+               }       
+
+               # Write a message saying that the user has been added.
+
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{useradded}, { Style => "pageheader" });
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{users}{useraddedtolist}, xestiascan_utf8convert($username)));
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"} . "?mode=users", { Text => $main::xestiascan_lang{users}{returnuserlist} });
+               
+               
+               return $main::xestiascan_presmodule->grab();
+
+       }
+
+       # Disconnect from the database server.
+
+       $main::xestiascan_authmodule->disconnect();
+
+       # As there is no username value, print a form for adding a user.
+
+       # Get the list of available scanners.
+       
+       my %scannerlist;
+       my $scanner;
+       
+       tie(%scannerlist, 'Tie::IxHash');
+       
+       foreach $scanner (Sane->get_devices){
+               $scannerlist{$scanner->{'name'}}{name}          = $scanner->{'name'};
+               $scannerlist{$scanner->{'name'}}{model}         = $scanner->{'model'};
+               $scannerlist{$scanner->{'name'}}{vendor}        = $scanner->{'vendor'};
+       }
+       
+       # Get the list of available output modules.
+       
+       my @availableoutputmodules;
+       @availableoutputmodules = xestiascan_scan_getoutputmodules;
+       
+       # Get the list of available export modules.
+       
+       my @availableexportmodules;
+       @availableexportmodules = xestiascan_scan_getexportmodules;
+       
+       # Print out the form for editing the user.      
+       
+       $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{adduser});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");    
+       
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "users");
+       $main::xestiascan_presmodule->addhiddendata("action", "add");
+       $main::xestiascan_presmodule->addhiddendata("confirm", "1");
+
+       # Process the user information.
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{userdetails});
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{setting}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{value}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{username});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addinputbox("username", { MaxLength => "64", Size => "32"});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{name});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("name", { MaxLength => "128", Size => "32" });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{adminprivs});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addcheckbox("admin");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{accountenabled});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addcheckbox("enabled");
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{password});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addinputbox("password", { MaxLength => "256", Size => "32", Password => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{confirmpassword});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("confirmpassword", { MaxLength => "256", Size => "32", Password => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow(); 
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       # Process the list of available scanners.
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{scannerlist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{scannername}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $scannername;
+       my $cssname = "";
+       my $cssstyle = 0;
+       my @connectedscanners;
+       
+       # Process the list of connected scanners.
+       
+       foreach $scannername (keys %scannerlist){
+               
+               $main::xestiascan_presmodule->startrow();
+               
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               # Add the name of the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addboldtext($scannerlist{$scannername}{vendor} . " " . $scannerlist{$scannername}{model});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->additalictext($scannerlist{$scannername}{name});
+               $main::xestiascan_presmodule->endcell();
+               
+               # See if it has permissions (or not) to use the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+                       
+               $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 0 });
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               push(@connectedscanners, $scannername);
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{outputmodulelist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{modulename}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $outputmodulename;
+       my $outputmoduleavailable = 0;
+       my $outputmoduleavailname;
+       $cssstyle = 0;
+       
+       # Process the list of available user output modules.
+       
+       foreach $outputmodulename (@availableoutputmodules){
+               
+               # Check if the module is in the list of available
+               # output modules, otherwise mark as not available.
+               
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($outputmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+                       
+               $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 0 });
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{exportmodulelist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{modulename}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $exportmodulename;
+       my $exportmoduleavailable = 0;
+       my $exportmoduleavailname;
+       $cssstyle = 0;
+       
+       # Process the list of available user export modules.
+       
+       foreach $exportmodulename (@availableexportmodules){
+               
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($exportmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+                       
+               $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 0 });
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       $main::xestiascan_presmodule->addlinebreak();
+
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{users}{adduserbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{clearvalues});
+
+       $main::xestiascan_presmodule->endform();
+       
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+
+       return $main::xestiascan_presmodule->grab();
+
+}
+
+sub xestiascan_users_edit{
+#################################################################################
+# xestiascan_users_edit: Edit a user in the user list.                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_users_edit(username, userinfo, scannerinfo, outputmoduleinfo,     #
+#                      exportmoduleinfo, confirm);                             #
+#                                                                              #
+# username             Specifies the username to edit.                         #
+# userinfo             Specifies the user information as a hash.               #
+# scannerinfo          Specifies the scanner information as a hash.            #
+# outputmoduleinfo     Specifies the output module information as a hash.      #
+# exportmoduleinfo     Specifies the export module information as a hash.      #
+# confirm              Specifies if the action to edit has been confirmed.     #
+#################################################################################
+       
+       my $username    = shift;
+       
+       my $passed_userinfo             = shift;
+       my $passed_scannerinfo          = shift;
+       my $passed_outputmoduleinfo     = shift;
+       my $passed_exportmoduleinfo     = shift;
+       
+       my $confirm = shift;
+       
+       if (!$username){
+       
+               # Username is blank so return an error.
+               
+               xestiascan_error("usernameblank");
+               
+       }
+       
+       if (!$confirm){
+       
+               $confirm = 0;
+               
+       }
+       
+       # Check to see if the username is valid.
+       
+       xestiascan_variablecheck(xestiascan_utf8convert($username), "utf8", 0, 0);
+       
+       my $username_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($username), "maxlength", 64, 1);
+       
+       if ($username_maxlength_check eq 1){
+               
+               # Username is too long so return an error.
+               
+               xestiascan_error("usernametoolong");
+               
+       }       
+       
+       # Connect to the database server.
+       
+       $main::xestiascan_authmodule->connect();
+
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       # Check to see if the user has permission to manage users.
+       
+       my $access_userlist = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+       
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       if ($access_userlist ne 1){
+               
+               # User not allowed to access the user list so return an error.
+               xestiascan_error("notpermitted");
+               
+       }       
+       
+
+       # Check to see if the action to edit the user has been confirmed and
+       # if it has then edit the user.
+       
+       if ($confirm eq 1){
+               
+               my %final_userinfo              = ();
+               my %final_scannerinfo           = ();
+               my %final_outputmoduleinfo      = ();
+               my %final_exportmoduleinfo      = ();
+               my $hashkey;
+               my $hashkey_short;
+               
+               # De-reference the user information hash.
+               
+               $hashkey = "";
+               
+               foreach $hashkey (keys %$passed_userinfo){
+               
+                       $final_userinfo{$hashkey} = $$passed_userinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the scanner information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+
+               foreach $hashkey (keys %$passed_scannerinfo){
+                       
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^scanner_//g;
+                       
+                       $final_scannerinfo{$hashkey_short} = $$passed_scannerinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the output module information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+               
+               foreach $hashkey (keys %$passed_outputmoduleinfo){
+
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^outputmodule_//g;
+                       
+                       $final_outputmoduleinfo{$hashkey_short} = $$passed_outputmoduleinfo{$hashkey};
+                       
+               }
+               
+               # De-reference the export module information hash.
+               
+               $hashkey = "";
+               $hashkey_short = "";
+               
+               foreach $hashkey (keys %$passed_exportmoduleinfo){
+                       
+                       $hashkey_short = $hashkey;
+                       $hashkey_short =~ s/^exportmodule_//g;
+                       
+                       $final_exportmoduleinfo{$hashkey_short} = $$passed_exportmoduleinfo{$hashkey};
+                       
+               }               
+               
+               # Check if the username and password are blank and if they are
+               # then return an error.
+               
+               if (!$username){
+                       
+                       xestiascan_error("usernameblank");
+                       
+               }
+               
+               # Check if the password matches with the confirm password value
+               # and return an error if this is not the case.
+               
+               if ($final_userinfo{Password} ne $final_userinfo{ConfirmPassword}){
+                       
+                       xestiascan_error("passwordsdonotmatch");
+                       
+               }
+               
+               # Check all the values being passed to this subroutine are UTF-8
+               # valid.
+               
+               xestiascan_variablecheck(xestiascan_utf8convert($username), "utf8", 0, 0);
+               xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{NewUsername}), "utf8", 0, 0);
+               xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Name}), "utf8", 0, 0);
+               xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Password}), "utf8", 0, 0);
+               
+               # Check the length of the username, name and password to make sure
+               # they are valid.
+               
+               my $username_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($username), "maxlength", 64, 1);
+               my $newusername_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{NewUsername}), "maxlength", 32, 1);
+               my $name_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Name}), "maxlength", 256, 1);
+               my $password_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($final_userinfo{Password}), "maxlength", 128, 1);
+               
+               if ($username_maxlength_check eq 1){
+                       
+                       # Username is too long so return an error.
+                       
+                       xestiascan_error("usernametoolong");
+                       
+               }
+               
+               if ($name_maxlength_check eq 1){
+                       
+                       # Name is too long so return an error.
+                       
+                       xestiascan_error("nametoolong");
+                       
+               }
+               
+               if ($password_maxlength_check eq 1){
+                       
+                       # Password is too long so return an error,
+                       
+                       xestiascan_error("passwordtoolong");
+                       
+               }
+               
+               my $final_scanner;
+               
+               foreach $final_scanner (keys %final_scannerinfo){
+                       
+                       # Check to make sure that the scanner name and value
+                       # are both valid UTF8.
+                       
+                       xestiascan_variablecheck($final_scanner, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_scannerinfo{$final_scanner}, "utf8", 0, 0);
+                       
+               }
+               
+               # Check that the export and output modules contain valid UTF8
+               # and are valid filenames.
+               
+               my $final_module;
+               my $module_lettersnumbers_check;
+               
+               foreach $final_module (keys %final_outputmoduleinfo){
+                       
+                       xestiascan_variablecheck($final_module, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_outputmoduleinfo{$final_module}, "utf8", 0, 0);
+                       
+                       $module_lettersnumbers_check = xestiascan_variablecheck($final_module, "lettersnumbers", 0, 1);
+                       xestiascan_error("moduleinvalid", xestiascan_language($main::xestiascan_lang{scan}{nameofoutputmoduleerror}, $final_module)) if $module_lettersnumbers_check eq 1;
+                       
+               }
+               
+               $final_module = "";
+               $module_lettersnumbers_check = 0;
+               
+               foreach $final_module (keys %final_exportmoduleinfo){
+                       
+                       xestiascan_variablecheck($final_module, "utf8", 0, 0);
+                       xestiascan_variablecheck($final_exportmoduleinfo{$final_module}, "utf8", 0, 0);
+                       
+                       $module_lettersnumbers_check = xestiascan_variablecheck($final_module, "lettersnumbers", 0, 1);
+                       xestiascan_error("moduleinvalid", xestiascan_language($main::xestiascan_lang{scan}{nameofexportmoduleerror}, $final_module)) if $module_lettersnumbers_check eq 1;
+                       
+               }
+               
+               # Get the list of available scanners.
+               
+               my %scannerlist;
+               my $scanner;
+               
+               tie(%scannerlist, 'Tie::IxHash');
+               
+               foreach $scanner (Sane->get_devices){
+                       $scannerlist{$scanner->{'name'}}{name}          = $scanner->{'name'};
+                       $scannerlist{$scanner->{'name'}}{model}         = $scanner->{'model'};
+                       $scannerlist{$scanner->{'name'}}{vendor}        = $scanner->{'vendor'};
+               }
+               
+               # Get the list of available output modules.
+               
+               my @availableoutputmodules;
+               @availableoutputmodules = xestiascan_scan_getoutputmodules;
+               
+               # Get the list of available export modules.
+               
+               my @availableexportmodules;
+               @availableexportmodules = xestiascan_scan_getexportmodules;
+               
+               # Pass the permissions to the edituser subroutine
+               # for the authentication module.
+               
+               $main::xestiascan_authmodule->edituser($username, "User", %final_userinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "Scanner", %final_scannerinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "OutputModule", %final_outputmoduleinfo);
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_authmodule->edituser($username, "ExportModule", %final_exportmoduleinfo);
+               
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       xestiascan_error("userediterror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{useredited}, { Style => "pageheader" });
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{users}{usereditedsuccess}, xestiascan_utf8convert($username))) ;
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"} . "?mode=users", { Text => $main::xestiascan_lang{users}{returnuserlist} });
+               
+               return $main::xestiascan_presmodule->grab();
+               
+       }
+       
+       
+       # Get the general information about the user.
+       
+       my %userinfo;
+       
+       %userinfo = $main::xestiascan_authmodule->getpermissions({ Username => xestiascan_utf8convert($username), PermissionType => "UserInfo" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       # Get the list of scanners with permissions for the user.
+       
+       my %userscannerinfo;
+       
+       %userscannerinfo = $main::xestiascan_authmodule->getpermissions({ Username => xestiascan_utf8convert($username), PermissionType => "Scanner" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       # Get the list of output modules with permissions for the user.
+       
+       my %useroutputinfo;
+
+       %useroutputinfo = $main::xestiascan_authmodule->getpermissions({ Username => xestiascan_utf8convert($username), PermissionType => "OutputModule" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       # Get the list of export modules with permissions for the user.
+       
+       my %userexportinfo;
+       
+       %userexportinfo = $main::xestiascan_authmodule->getpermissions({ Username => xestiascan_utf8convert($username), PermissionType => "ExportModule" });
+
+       xestiascan_error("usernameblank") if ($main::xestiascan_authmodule->geterror eq "UsernameBlank");
+       xestiascan_error("permissiontypeblank") if ($main::xestiascan_authmodule->geterror eq "PermissionTypeBlank");
+       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1)) if ($main::xestiascan_authmodule->geterror eq "DatabaseError");
+       
+       # Get the list of available scanners.
+       
+       my %scannerlist;
+       my $scanner;
+       
+       tie(%scannerlist, 'Tie::IxHash');
+       
+       foreach $scanner (Sane->get_devices){
+               $scannerlist{$scanner->{'name'}}{name}          = $scanner->{'name'};
+               $scannerlist{$scanner->{'name'}}{model}         = $scanner->{'model'};
+               $scannerlist{$scanner->{'name'}}{vendor}        = $scanner->{'vendor'};
+       }
+       
+       # Get the list of available output modules.
+       
+       my @availableoutputmodules;
+       @availableoutputmodules = xestiascan_scan_getoutputmodules;
+       
+       # Get the list of available export modules.
+       
+       my @availableexportmodules;
+       @availableexportmodules = xestiascan_scan_getexportmodules;
+       
+       # Print out the form for editing the user.      
+       
+       $main::xestiascan_presmodule->startbox("sectionboxnofloat");
+       $main::xestiascan_presmodule->startbox("sectiontitle");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{edituser});
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->startbox("secondbox");    
+
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "users");
+       $main::xestiascan_presmodule->addhiddendata("action", "edit");
+       $main::xestiascan_presmodule->addhiddendata("confirm", "1");
+       $main::xestiascan_presmodule->addhiddendata("username_original", xestiascan_utf8convert($username));
+       
+       # Process the user information.
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{userdetails});
+
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{setting}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{common}{value}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{username});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addinputbox("username", { MaxLength => "64", Size => "32", Value => $userinfo{Username} });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{name});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("name", { MaxLength => "128", Size => "32", Value => $userinfo{Name} });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{adminprivs});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addcheckbox("admin", { Checked => $userinfo{Admin} });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{accountenabled});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addcheckbox("enabled", { Checked => $userinfo{Enabled} });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{newpassword});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell1");
+       $main::xestiascan_presmodule->addinputbox("password", { MaxLength => "256", Size => "32", Password => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow();
+       
+       $main::xestiascan_presmodule->startrow();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{confirmnewpassword});
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->addcell("tablecell2");
+       $main::xestiascan_presmodule->addinputbox("confirmpassword", { MaxLength => "256", Size => "32", Password => 1 });
+       $main::xestiascan_presmodule->endcell();
+       $main::xestiascan_presmodule->endrow(); 
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       # Process the list of available scanners.
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{scannerlist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{scannername}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{connected}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $scannername;
+       my $cssname = "";
+       my $cssstyle = 0;
+       my @connectedscanners;
+       
+       # Process the list of connected scanners.
+       
+       foreach $scannername (keys %scannerlist){
+       
+               $main::xestiascan_presmodule->startrow();
+
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               # Add the name of the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addboldtext($scannerlist{$scannername}{vendor} . " " . $scannerlist{$scannername}{model});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->additalictext($scannerlist{$scannername}{name});
+               $main::xestiascan_presmodule->endcell();
+               
+               # See if it has permissions (or not) to use the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($userscannerinfo{$scannername}){
+               
+                       if ($userscannerinfo{$scannername} eq 1){
+               
+                               $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 1 });
+                       
+                       } else {
+                       
+                               $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 0 });
+                               
+                       }
+               
+               } else {
+               
+                       $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+                       
+               # As we are dealing with the connected scanners first,
+               # Write 'Yes' for connected.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{devconnected});
+               $main::xestiascan_presmodule->endcell();                
+               
+               push(@connectedscanners, $scannername);
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       # Process the list of disconnected scanners.
+       
+       $scannername = "";
+       my $duplicatescannername;
+       my $duplicatescannerfound = 0;
+       
+       foreach $scannername (keys %userscannerinfo){
+       
+               # Check the list of connected scanners and skip
+               # this bit if the scanner name matches this list.
+               
+               $duplicatescannerfound = 0;
+               
+               foreach $duplicatescannername (@connectedscanners){
+               
+                       if ($duplicatescannername eq $scannername){
+                       
+                               $duplicatescannerfound = 1;
+                               
+                       }
+                       
+               }
+               
+               next if $duplicatescannerfound eq 1;
+
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               # Add the name of the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addboldtext($scannerlist{$scannername}{vendor} . " " . $scannerlist{$scannername}{model});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->additalictext($scannerlist{$scannername}{name});
+               $main::xestiascan_presmodule->endcell();
+               
+               # See if it has permissions (or not) to use the scanner.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($userscannerinfo{$scannername}){
+                       
+                       if ($userscannerinfo{$scannername} eq 1){
+                               
+                               $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 0 });
+                               
+                       }
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addcheckbox("scanner_" . $scannerlist{$scannername}{name}, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               # As we are dealing with the connected scanners first,
+               # Write 'Yes' for connected.
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{devdisconnected});
+               $main::xestiascan_presmodule->endcell();                
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{outputmodulelist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();   
+       
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{modulename}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{available}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $outputmodulename;
+       my $outputmoduleavailable = 0;
+       my $outputmoduleavailname;
+       $cssstyle = 0;
+       
+       # Process the list of available user output modules.
+       
+       foreach $outputmodulename (@availableoutputmodules){
+       
+               # Check if the module is in the list of available
+               # output modules, otherwise mark as not available.
+
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($outputmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($useroutputinfo{$outputmodulename}){
+                       
+                       if ($useroutputinfo{$outputmodulename} eq 1){
+                       
+                               $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 1 });
+                               
+                       } else {
+
+                               $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 0 });
+                               
+                       }
+                                       
+               } else {
+               
+                       $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{modavailable});
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       # Process the list of not available output modules.
+       
+       $outputmodulename = "";
+       my $duplicateoutputmodulename = "";
+       my $duplicateoutputmodulefound = 0;
+       
+       foreach $outputmodulename (keys %useroutputinfo){
+       
+               # Check the list of available output modules and skip
+               # this bit if the output module name matches this list.
+               
+               $duplicateoutputmodulefound = 0;
+               
+               foreach $duplicateoutputmodulename (@availableoutputmodules){
+                       
+                       if ($duplicateoutputmodulename eq $outputmodulename){
+                               
+                               $duplicateoutputmodulefound = 1;
+                               
+                       }
+                       
+               }
+               
+               next if $duplicateoutputmodulefound eq 1;               
+
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($outputmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($useroutputinfo{$outputmodulename}){
+                       
+                       if ($useroutputinfo{$outputmodulename} eq 1){
+                               
+                               $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 0 });
+                               
+                       }
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addcheckbox("outputmodule_" . $outputmodulename, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{modunavailable});
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+       
+       $main::xestiascan_presmodule->endtable();
+
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->addboldtext($main::xestiascan_lang{users}{exportmodulelist});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+
+       $main::xestiascan_presmodule->starttable("", { CellPadding => "5", CellSpacing => "0" });
+       $main::xestiascan_presmodule->startheader();
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{modulename}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{allowaccess}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->addheader($main::xestiascan_lang{users}{available}, { Style => "tablecellheader" });
+       $main::xestiascan_presmodule->endheader();
+       
+       my $exportmodulename;
+       my $exportmoduleavailable = 0;
+       my $exportmoduleavailname;
+       $cssstyle = 0;
+
+       # Process the list of available user export modules.
+       
+       foreach $exportmodulename (@availableexportmodules){
+               
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($exportmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($userexportinfo{$exportmodulename}){
+                       
+                       if ($userexportinfo{$exportmodulename} eq 1){
+                               
+                               $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 0 });
+                               
+                       }
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{modavailable});
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }
+
+       # Process the list of not available user export modules.
+       
+       $exportmodulename = "";
+       my $duplicateexportmodulename = "";
+       my $duplicateexportmodulefound = 0;
+       
+       foreach $exportmodulename (keys %userexportinfo){
+               
+               # Check the list of available output modules and skip
+               # this bit if the output module name matches this list.
+               
+               $duplicateexportmodulefound = 0;
+               
+               foreach $duplicateexportmodulename (@availableexportmodules){
+                       
+                       if ($duplicateexportmodulename eq $exportmodulename){
+                               
+                               $duplicateexportmodulefound = 1;
+                               
+                       }
+                       
+               }
+               
+               next if $duplicateexportmodulefound eq 1;               
+               
+               # Setup the styling for the row.
+               
+               if ($cssstyle eq 0){
+                       
+                       $cssname = "tablecell1";
+                       $cssstyle = 1;
+                       
+               } else {
+                       
+                       $cssname = "tablecell2";
+                       $cssstyle = 0;
+                       
+               }
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($exportmodulename);
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               
+               if ($userexportinfo{$outputmodulename}){
+                       
+                       if ($userexportinfo{$outputmodulename} eq 1){
+                               
+                               $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 1 });
+                               
+                       } else {
+                               
+                               $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 0 });
+                               
+                       }
+                       
+               } else {
+                       
+                       $main::xestiascan_presmodule->addcheckbox("exportmodule_" . $exportmodulename, { Checked => 0 });
+                       
+               }
+               
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->addcell($cssname);
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{modunavailable});
+               $main::xestiascan_presmodule->endcell();
+               
+               $main::xestiascan_presmodule->endrow();
+               
+       }       
+       
+       $main::xestiascan_presmodule->endtable();
+       
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       # User Information table.
+               
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{users}{edituserbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addreset($main::xestiascan_lang{common}{clearvalues});
+       
+       $main::xestiascan_presmodule->endform();        
+
+       $main::xestiascan_presmodule->endbox();
+       $main::xestiascan_presmodule->endbox();
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
+
+sub xestiascan_users_delete{
+#################################################################################
+# xestiascan_users_delete: Delete a user in the user list.                     #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_users_delete(username, confirm);                                  #
+#                                                                              #
+# username     Specifies the user to delete.                                   #
+# confirm      Confirms if the user should be deleted.                         #
+#################################################################################
+       
+       my $username = shift;
+       my $confirm = shift;
+       
+       if (!$confirm){
+       
+               $confirm = 0;
+               
+       }
+
+       if (!$username){
+               
+               # The username is blank so return an error.
+               
+               xestiascan_error("usernameblank");
+               
+       }
+       
+       # Connect to the database server.
+       
+       $main::xestiascan_authmodule->connect();
+       
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       # Check to see if the user has permission to manage users.
+       
+       my $access_userlist = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+       
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       if ($access_userlist ne 1){
+               
+               # User not allowed to access the user list so return an error.
+               xestiascan_error("notpermitted");
+               
+       }
+       
+       # Check the user name to see if it is valid.
+       
+       xestiascan_variablecheck($username, "utf8", 0, 0);
+       
+       my $username_maxlength_check = xestiascan_variablecheck(xestiascan_utf8convert($username), "maxlength", 32, 1);
+       
+       if ($username_maxlength_check eq 1){
+               
+               # Username is too long so return an error.
+               
+               xestiascan_error("usernametoolong");
+               
+       }
+       
+       # Check to see if the user exists.
+       
+       $main::xestiascan_authmodule->getpermissions({ Username => $username, PermissionType => "Enabled" });
+       
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+
+       
+       if ($main::xestiascan_authmodule->geterror eq "UserDoesNotExist"){
+               
+               xestiascan_error("usernameinvalid");
+               
+       }
+       
+       if ($confirm eq 1){
+       
+               # The action to delete the user has been confirmed.
+               
+               $main::xestiascan_authmodule->deleteuser($username);
+               
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       # A database error has occured so return an error with
+                       # the extended error information.
+                       
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               if ($main::xestiascan_authmodule->geterror eq "UserDoesNotExist"){
+                       
+                       xestiascan_error("usernameinvalid");
+                       
+               }
+               
+               # Disconnect from the database server.
+               
+               $main::xestiascan_authmodule->disconnect();
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{userdeleted}, { Style => "pageheader" });
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{users}{userdeletedsuccess}, xestiascan_utf8convert($username)));
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"} . "?mode=users", { Text => $main::xestiascan_lang{users}{returnuserlist} });             
+
+               return $main::xestiascan_presmodule->grab();
+               
+       }
+       
+       # Disconnect from the database server.
+       
+       $main::xestiascan_authmodule->disconnect();
+       
+       # The action to delete the user has not been confirmed so
+       # write out a form asking the user to confirm it.
+       
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{deleteuser}, { Style => "pageheader" });
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{users}{deleteuserareyousure}, xestiascan_utf8convert($username)));
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "users");
+       $main::xestiascan_presmodule->addhiddendata("action", "delete");
+       $main::xestiascan_presmodule->addhiddendata("confirm", "1");
+       $main::xestiascan_presmodule->addhiddendata("user", xestiascan_utf8convert($username));
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{users}{deleteuserbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}  . "?mode=users", { Text => $main::xestiascan_lang{users}{noreturnuserlist} });
+       $main::xestiascan_presmodule->endform();
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
+
+sub xestiascan_users_flush{
+#################################################################################
+# xestiascan_users_flush: Flush the users out of the sessions table.           #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_users_flush(confirm);                                             #
+#                                                                              #
+# confirm      Confirms the actions to flush the users out of the sessions     #
+#              table.                                                          #
+#################################################################################
+       
+       my $confirm = shift;
+       
+       if (!$confirm){
+               
+               $confirm = 0;
+               
+       }
+
+       # Connect to the database server.
+       
+       $main::xestiascan_authmodule->connect();
+       
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       # Check to see if the user has permission to manage users.
+       
+       my $access_userlist = $main::xestiascan_authmodule->getpermissions({ Username => $main::loggedin_user, PermissionType => "Admin" });
+       
+       if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       if ($access_userlist ne 1){
+               
+               # User not allowed to access the user list so return an error.
+               xestiascan_error("notpermitted");
+
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       # A database error has occured so return an error with
+                       # the extended error information.
+                       
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+       }
+       
+       # Check to see if the action to flush the users from session 
+       # table has been confirmed.
+       
+       if ($confirm eq 1){
+               
+               # Action confirmed, so flush the users table.
+               
+               $main::xestiascan_authmodule->flushusers();
+               
+               # Check to see if an error occured while flushing the users out of the session table.
+               
+               if ($main::xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+                       # A database error has occured so return an error with
+                       # the extended error information.
+                       
+                       xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+                       
+               }
+               
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallusers}, {Style => "pageheader" });
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallsuccess});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallloginagain});
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlinebreak();
+               $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}, { Text => $main::xestiascan_lang{users}{logoutallcontinue} });
+               
+               return $main::xestiascan_presmodule->grab();
+               
+       }
+
+       # Disconnect from server.
+       
+       $main::xestiascan_authmodule->disconnect();
+       
+       # The action to flush the users from the session tables has not
+       # been confirmed so write a message asking for confiramation.
+       
+       # $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{deleteuser}, { Style => "pageheader" });
+       # $main::xestiascan_presmodule->addlinebreak();
+       # $main::xestiascan_presmodule->addlinebreak();
+       # $main::xestiascan_presmodule->addtext(xestiascan_language($main::xestiascan_lang{users}{deleteuserareyousure}, $username));
+       # $main::xestiascan_presmodule->addlinebreak();
+       # $main::xestiascan_presmodule->addlinebreak();
+
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallusers}, {Style => "pageheader" });
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallquestion});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addtext($main::xestiascan_lang{users}{logoutallwarning});
+       $main::xestiascan_presmodule->addlinebreak();
+       $main::xestiascan_presmodule->addlinebreak();
+       
+       $main::xestiascan_presmodule->startform($main::xestiascan_env{"script_filename"}, "POST");
+       $main::xestiascan_presmodule->addhiddendata("mode", "users");
+       $main::xestiascan_presmodule->addhiddendata("action", "flush");
+       $main::xestiascan_presmodule->addhiddendata("confirm", "1");
+       $main::xestiascan_presmodule->addsubmit($main::xestiascan_lang{users}{logoutallbutton});
+       $main::xestiascan_presmodule->addtext(" | ");
+       $main::xestiascan_presmodule->addlink($main::xestiascan_env{"script_filename"}  . "?mode=users", { Text => $main::xestiascan_lang{users}{noreturnuserlist} });
+       $main::xestiascan_presmodule->endform();
+       
+       return $main::xestiascan_presmodule->grab();
+       
+}
\ No newline at end of file
diff --git a/cgi-files/install-multiuser.cgi b/cgi-files/install-multiuser.cgi
new file mode 100755 (executable)
index 0000000..892f0a6
--- /dev/null
@@ -0,0 +1,2216 @@
+#!/usr/bin/perl -Tw
+
+#################################################################################
+# Xestia Scanner Server Installer Script (install-multiuser.cgi)               #
+# Multiuser installation script for Xestia Scanner Server                      #
+#                                                                              #
+# Version: 0.1.0                                                               #
+#                                                                              #
+# Copyright (C) 2005-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+use strict;                            # Throw errors if there's something wrong.
+use warnings;                          # Write warnings to the HTTP Server Log file.
+
+use utf8;
+
+eval "use CGI::Lite";
+
+if ($@){
+       print "Content-type: text/html;\r\n\r\n";
+       print "The CGI::Lite Perl Module is not installed. Please install CGI::Lite and then run this installation script again. CGI::Lite can be installed through CPAN.";
+       exit;
+}
+
+my $modperlenabled = 0;
+my $installscriptname = "install-multiuser.cgi";
+my $originstallscriptname = "install.cgi";
+my $xestiascanscriptname = "xsdss.cgi";
+my $language_selected = "en-GB";
+
+my %xestiascan_config;
+
+my $cssstyle = "
+
+a {
+       color: #FFFFFF;
+}
+
+body {
+       margin: 0px; 
+       font-family: sans-serif; 
+       padding: 0px; 
+       font-size: 13px;
+       background-color: #402040;
+       color: #ffffff;
+       background-image: url('/images/xestiascan/pagebackground.png');
+       background-repeat: repeat-x;
+}
+
+select {
+       #font-size: 12px;
+       #padding: 3px;
+       #background-color: #408080;
+       #color: #FFFFFF;
+       #border-color: #102020;
+       #border-style: solid;
+       #border-width: 1px;
+       #padding: 3px;
+}
+
+td,table {
+       padding: 5px;
+       border-spacing: 0px;
+}
+
+.languagebar {
+       background-color: #204040;
+       vertical-align: top;
+}
+
+.languagebarselect {
+       text-align: right;
+       background-color: #204040;
+}
+
+.tablecellheader {
+       font-size: 12px;
+       background-color: #703570;      
+       font-weight: bold;
+       text-align: left;
+       background-image: url('/images/xestiascan/tabletop.png');
+       background-repeat: repeat-x;
+}
+
+.tabledata {
+       background-color: #603060;
+}
+
+.topbar {
+       padding: 3px;
+       background-color: #753575;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       border-bottom-color: #EE70EE;
+       text-align: right;
+       min-height: 17px;
+       background-image: url('/images/xestiascan/menutop.png');
+       background-repeat: repeat-x;
+}
+
+.title {
+       font-size: 16px;
+       font-weight: bold;
+       position: absolute;
+       text-align: left;
+       z-index: 0;
+       left: 0;
+       padding-left: 3px;
+}
+
+.pageheader {
+       font-size: 18px;
+       font-weight: bold;
+}
+
+.subheader {
+       font-size: 14px;
+       font-weight: bold;
+}
+
+.tablename {
+
+       background-color: #301530;
+
+}
+
+.pagespacing {
+
+       padding: 3px;
+
+}
+
+
+";
+
+# Default settings.
+
+my $default_dbmodule           = "PostgreSQL";
+my $default_server             = "localhost";
+my $default_port               = "5432";
+my $default_protocol           = "tcp";
+my $default_name               = "database";
+my $default_username           = "username";
+my $default_prefix             = "xestiascan";
+
+my $default_adminusername      = "Administrator";
+my $default_adminpassword      = "Password";
+
+my $query_lite = new CGI::Lite;
+my $form_data = $query_lite->parse_form_data;
+
+my ($xestiascan_lang, %xestiascan_lang);
+
+$xestiascan_lang{"en-GB"}{"languagename"}      = "English (British)";
+       $xestiascan_lang{"en-GB"}{"testpass"}           = "OK";
+       $xestiascan_lang{"en-GB"}{"testfail"}           = "Error";
+
+       $xestiascan_lang{"en-GB"}{"invalidconfigfile"}          = "An error occured whilst reading the configuration file. It may be in an invalid format, missings or that no permissions are set! You will need to enter these details manually below.";
+
+       $xestiascan_lang{"en-GB"}{"generic"}                    = "An error occured which is not known to the Xestia Scanner Server multiuser installer.";
+       $xestiascan_lang{"en-GB"}{"invalidvariable"}            = "The variable given was invalid.";
+       $xestiascan_lang{"en-GB"}{"invalidvalue"}               = "The value given was invalid.";
+       $xestiascan_lang{"en-GB"}{"invalidutf8"}                = "The value given has does not contain valid UTF8.";
+       $xestiascan_lang{"en-GB"}{"invalidoption"}              = "The option given was invalid.";
+       $xestiascan_lang{"en-GB"}{"variabletoolong"}            = "The variable given is too long.";
+       $xestiascan_lang{"en-GB"}{"blankdirectory"}             = "The directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"invaliddirectory"}           = "The directory name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"moduleblank"}                        = "The module filename given is blank.";
+       $xestiascan_lang{"en-GB"}{"moduleinvalid"}              = "The module filename given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"dbdirectorytoolong"}         = "The database directory name given is too long.";
+       $xestiascan_lang{"en-GB"}{"outputdirectorytoolong"}     = "The output directory name given is too long.";
+       $xestiascan_lang{"en-GB"}{"imagesuripathtoolong"}       = "The images URI path name given is too long.";
+       $xestiascan_lang{"en-GB"}{"dateformattoolong"}          = "The date format given is too long.";
+       $xestiascan_lang{"en-GB"}{"customdateformattoolong"}    = "The custom date format given is too long.";
+       $xestiascan_lang{"en-GB"}{"languagefilenametoolong"}    = "The language filename given is too long.";
+
+       $xestiascan_lang{"en-GB"}{"authmoduleinvalidpermissions"}       = "The authentication moudle has invalid file permissions set.";
+
+       $xestiascan_lang{"en-GB"}{"dateformatblank"}            = "The date format given was blank.";
+       $xestiascan_lang{"en-GB"}{"dateformatinvalid"}          = "The date format given is invalid.";
+       $xestiascan_lang{"en-GB"}{"languagefilenameinvalid"}    = "The language filename given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"dbdirectoryblank"}           = "The database directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"dbdirectoryinvalid"}         = "The database directory name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"outputdirectoryblank"}       = "The output directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"outputdirectoryinvalid"}     = "The output directory name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"textarearowblank"}           = "The text area row value given is blank.";
+       $xestiascan_lang{"en-GB"}{"textarearowtoolong"}         = "The text area row value given is too long.";
+       $xestiascan_lang{"en-GB"}{"textarearowinvalid"}         = "The text area row value given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"textareacolsblank"}          = "The text area columns value given is blank.";
+       $xestiascan_lang{"en-GB"}{"textareacolstoolong"}                = "The text area columns value given is too long.";
+       $xestiascan_lang{"en-GB"}{"textareacolsinvalid"}                = "The text area columns value given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"presmoduleblank"}            = "The presentation module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"presmoduleinvalid"}          = "The presentation module name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"authmoduleblank"}            = "The database module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"dbmoduleinvalid"}            = "The database module name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"outputmoduleblank"}          = "The output module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"outputmoduleinvalid"}                = "The output module name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"presmodulemissing"}          = "The presentation module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"outputmodulemissing"}                = "The output module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"authmodulemissing"}          = "The authentication module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"languagefilenamemissing"}    = "The language file with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"servernametoolong"}          = "The database server name given is too long.";
+       $xestiascan_lang{"en-GB"}{"servernameinvalid"}          = "The database server name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverportnumbertoolong"}    = "The database server port number given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverportnumberinvalidcharacters"}  = "The database server port number given contains invalid characters.";
+       $xestiascan_lang{"en-GB"}{"serverportnumberinvalid"}    = "The database server port number given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverprotocolnametoolong"}  = "The database server protocol name given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverprotocolinvalid"}              = "The database server protocol name is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasenametoolong"}  = "The database name given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasenameinvalid"}  = "The database name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabaseusernametoolong"}      = "The database server username given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabaseusernameinvalid"}      = "The database server username given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasepasswordtoolong"}      = "The database server password is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasetableprefixtoolong"}   = "The database server table prefix given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasetableprefixinvalid"}   = "The database server table prefix given is invalid.";
+       $xestiascan_lang{"en-GB"}{"createmodulestoolong"}       = "The create modules value given is too long.";
+       $xestiascan_lang{"en-GB"}{"createscannerstoolong"}      = "The create scanners value given is too long.";
+       $xestiascan_lang{"en-GB"}{"createsessionstoolong"}      = "The create sessions value given is too long.";
+       $xestiascan_lang{"en-GB"}{"createuserstoolong"}         = "The create users value given is too long.";
+       $xestiascan_lang{"en-GB"}{"forcerecreatetoolong"}       = "The force recreate value given is too long.";
+       $xestiascan_lang{"en-GB"}{"deleteinstalltoolong"}       = "The delete installer value given is too long.";
+       $xestiascan_lang{"en-GB"}{"deletemultiusertoolong"}     = "The delete multiuser installer value given is too long.";
+
+       $xestiascan_lang{"en-GB"}{"notmultiuser"}               = "The module given is not a multiuser module.";
+
+       $xestiascan_lang{"en-GB"}{"removeinstallscripttoolong"} = "The remove install script value given is too long.";
+       $xestiascan_lang{"en-GB"}{"cannotwriteconfigurationindirectory"}        = "The configuration file cannot be written because the directory the install script is running from has invalid permissions.";
+       $xestiascan_lang{"en-GB"}{"configurationfilereadpermissionsinvalid"}    = "The configuration that currently exists has invalid read permissions set.";
+       $xestiascan_lang{"en-GB"}{"configurationfilewritepermissionsinvalid"}   = "The configuration that currently exists has invalid write permissions set.";
+
+       $xestiascan_lang{"en-GB"}{"errormessagetext"}   = "Please press the back button on your browser or preform the command needed to return to the previous page.";
+
+       $xestiascan_lang{"en-GB"}{"switch"}             = "Switch";
+       $xestiascan_lang{"en-GB"}{"setting"}            = "Setting";
+       $xestiascan_lang{"en-GB"}{"value"}              = "Value";
+       $xestiascan_lang{"en-GB"}{"filename"}           = "Filename";
+       $xestiascan_lang{"en-GB"}{"module"}             = "Module";
+       $xestiascan_lang{"en-GB"}{"result"}             = "Result";
+       $xestiascan_lang{"en-GB"}{"error"}              = "Error!";
+       $xestiascan_lang{"en-GB"}{"criticalerror"}      = "Critical Error!";
+       $xestiascan_lang{"en-GB"}{"errormessage"}       = "Error: ";
+       $xestiascan_lang{"en-GB"}{"warningmessage"}     = "Warning: ";
+
+       $xestiascan_lang{"en-GB"}{"doesnotexist"}       = "Does not exist.";
+       $xestiascan_lang{"en-GB"}{"invalidpermissionsset"}      = "Invalid permissions set.";
+
+       $xestiascan_lang{"en-GB"}{"dependencyperlmodulesmissing"}       = "One or more Perl modules that are needed by Xestia Scanner Server are not installed or has problems. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"databaseperlmodulesmissing"} = "One or more Perl modules that are needed by the Xestia Scanner Server database modules are not installed or has problems. See the Xestia Scanner Server documentation for more information on this. There should however, be no problems with the database modules which use the Perl modules that have been found.";
+       $xestiascan_lang{"en-GB"}{"filepermissionsinvalid"}     = "One or more of the filenames checked does not exist or has invalid permissions set. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"dependencymodulesnotinstalled"}      = "One of the required Perl modules is not installed or has errors. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"databasemodulesnotinstalled"}        = "None of Perl modules that are used by the database modules are not installed. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"filepermissionerrors"}       = "One or more filenames checked has errors. See the Xestia Scanner Server documentation for more information on this.",
+
+       $xestiascan_lang{"en-GB"}{"installertitle"}     = "Xestia Scanner Server Multiuser Installer";
+       $xestiascan_lang{"en-GB"}{"installertext"}      = "This installer script will setup the user and session tables needed for your multiuser installation of Xestia Scanner Server. If you already have user or session tables then they will be skipped unless you have selected the recreate table checkbox.";
+       $xestiascan_lang{"en-GB"}{"modperlnotice"}      = "mod_perl has been detected. Please ensure that you have setup this script and the main Xestia Scanner Server script so that mod_perl can use Xestia Scanner Server properly. Please read the mod_perl specific part of Chapter 1: Installation in the Xestia Scanner Server documentation.";
+       $xestiascan_lang{"en-GB"}{"dependencytitle"}    = "Dependency and file testing results";
+       $xestiascan_lang{"en-GB"}{"requiredmodules"}    = "Required Modules";
+       $xestiascan_lang{"en-GB"}{"perlmodules"}                = "These Perl modules are used internally by Xestia Scanner Server.";
+       $xestiascan_lang{"en-GB"}{"databasemodules"}    = "Perl Database Modules";
+       $xestiascan_lang{"en-GB"}{"databasemodulestext"}        = "These Perl modules are used by the database modules.";
+       $xestiascan_lang{"en-GB"}{"filepermissions"}    = "File permissions";
+       $xestiascan_lang{"en-GB"}{"filepermissionstext"}        = "The file permissions are for file and directories that are critical to Xestia Scanner Server such as module and language directories.";
+       
+       $xestiascan_lang{"en-GB"}{"settingstitle"}      = "Xestia Scanner Server Settings";
+       $xestiascan_lang{"en-GB"}{"settingstext"}       = "The settings given here will be used by Xestia Scanner Server. Some default settings are given here. Certain database modules (like SQLite) do not need the database server settings and can be left alone.";
+       $xestiascan_lang{"en-GB"}{"directories"}                = "Directories";
+       $xestiascan_lang{"en-GB"}{"databasedirectory"}  = "Database Directory";
+       $xestiascan_lang{"en-GB"}{"outputdirectory"}    = "Output Directory";
+       $xestiascan_lang{"en-GB"}{"imagesuripath"}      = "Images (URI path)";
+       $xestiascan_lang{"en-GB"}{"display"}            = "Display";
+       $xestiascan_lang{"en-GB"}{"textareacols"}       = "Text Area Columns";
+       $xestiascan_lang{"en-GB"}{"textarearows"}       = "Text Area Rows";
+       $xestiascan_lang{"en-GB"}{"date"}               = "Date";
+       $xestiascan_lang{"en-GB"}{"dateformat"}         = "Date Format";
+       $xestiascan_lang{"en-GB"}{"language"}           = "Language";
+       $xestiascan_lang{"en-GB"}{"systemlanguage"}     = "System Language";
+       $xestiascan_lang{"en-GB"}{"modules"}            = "Modules";
+       $xestiascan_lang{"en-GB"}{"presentationmodule"} = "Presentation Module";
+       $xestiascan_lang{"en-GB"}{"outputmodule"}       = "Output Module";
+       $xestiascan_lang{"en-GB"}{"authsettings"}       = "Authentication Settings";
+       $xestiascan_lang{"en-GB"}{"authenticationmodule"}       = "Authentication Module";
+       $xestiascan_lang{"en-GB"}{"multiuseronly"}      = "Only multiuser-supported authentication modules are listed.";
+       $xestiascan_lang{"en-GB"}{"databaseserver"}     = "Database Server";
+       $xestiascan_lang{"en-GB"}{"databaseport"}       = "Database Port";
+       $xestiascan_lang{"en-GB"}{"databaseprotocol"}   = "Database Protocol";
+       $xestiascan_lang{"en-GB"}{"databasename"}       = "Database Name";
+       $xestiascan_lang{"en-GB"}{"databaseusername"}   = "Database Username";
+       $xestiascan_lang{"en-GB"}{"databasepassword"}   = "Database Password";
+       $xestiascan_lang{"en-GB"}{"databasetableprefix"}        = "Database Table Prefix";
+       $xestiascan_lang{"en-GB"}{"adminuseraccountsettings"}   = "Administrative User Account Settings";
+       $xestiascan_lang{"en-GB"}{"adminusername"}      = "Username:";
+       $xestiascan_lang{"en-GB"}{"adminpassword"}      = "Password:";
+       $xestiascan_lang{"en-GB"}{"installationoptions"}        = "Installation Options";
+       $xestiascan_lang{"en-GB"}{"installoptions"}     = "Install Options";
+       $xestiascan_lang{"en-GB"}{"installationoptions"}        = "Installation Options";
+       $xestiascan_lang{"en-GB"}{"createtables"} = "Create tables";
+       $xestiascan_lang{"en-GB"}{"createtablemodulepermissions"} = "Create the modules permissions table.";
+       $xestiascan_lang{"en-GB"}{"createtablescannerspermissions"} = "Create the scanners permissions table.";
+       $xestiascan_lang{"en-GB"}{"createtablesessions"} = "Create the sessions table.";
+       $xestiascan_lang{"en-GB"}{"createtableusers"} = "Create the users table.";
+       $xestiascan_lang{"en-GB"}{"forcerecreate"}      = "Force recreate";
+       $xestiascan_lang{"en-GB"}{"forcerecreatetables"}        = "Force recreation of the selected tables.";
+       $xestiascan_lang{"en-GB"}{"deleteinstallscripts"}       = "Delete install scripts";
+       $xestiascan_lang{"en-GB"}{"removeinstallscript"}        = "Delete the Xestia Scanner Server Installer script.";
+       $xestiascan_lang{"en-GB"}{"removemultiuserinstallscript"}       = "Delete the Xestia Scanner Server Multiuser Installer script.";
+       $xestiascan_lang{"en-GB"}{"recommendremoving"}  = "Deleting the installer scripts after you have finished using them is strongly recommended to secure your Xestia Scanner Server multiuser installation!";
+       $xestiascan_lang{"en-GB"}{"savesettingsbutton"} = "Save Settings";
+       $xestiascan_lang{"en-GB"}{"resetsettingsbutton"}        = "Reset Settings";
+
+       $xestiascan_lang{"en-GB"}{"adminaccountname"} = "Administrator";
+       $xestiascan_lang{"en-GB"}{"adminaccountpassword"} = "Password";
+
+       $xestiascan_lang{"en-GB"}{"installscriptkept"} = "Warning: The installer script has not been removed.";
+       $xestiascan_lang{"en-GB"}{"multiuserinstallscriptkept"} = "Warning: The multiuser installer script has not been removed.";
+       $xestiascan_lang{"en-GB"}{"multiuserscriptremoved"}     = "The multiuser installer script was removed.";
+       $xestiascan_lang{"en-GB"}{"installscriptremoved"}       = "The installer script was removed.";
+       $xestiascan_lang{"en-GB"}{"installedmessage"}   = "The configuration file for Xestia Scanner Server has been written. To change the settings in the configuration file at a later date use the Edit Settings link in the View Settings sub-menu at the top of the page when using Xestia Scanner Server.";
+       $xestiascan_lang{"en-GB"}{"cannotremovemultiuserinstallerscript"}       = "Unable to remove the multiuser installer script: %s. The multiuser installer script will have to be deleted manually.";
+       $xestiascan_lang{"en-GB"}{"cannotremoveinstallerscript"}        = "Unable to remove the installer script: %s. The installer script will have to be deleted manually.";
+       $xestiascan_lang{"en-GB"}{"usexestiascannerservertext"} = "To use Xestia Scanner Server click or select the link below (will not work if the Xestia Scanner Server script is not called xsdss.cgi):";
+       $xestiascan_lang{"en-GB"}{"usexestiascannerserverlink"} = "Start using Xestia Scanner Server";
+
+       $xestiascan_lang{"en-GB"}{"multiuserresults"} = "The multiuser installer has preformed the following actions:";
+       $xestiascan_lang{"en-GB"}{"forciblyrecreated"} = "The tables will be forcibly recreated.";
+       $xestiascan_lang{"en-GB"}{"notforciblyrecreated"} = "The tables will not be forcibly recreated.";
+       $xestiascan_lang{"en-GB"}{"modulestableerror"} = "An error occured while creating the permissions table for modules: ";
+       $xestiascan_lang{"en-GB"}{"modulestablesuccess"} = "The permissions table for modules was created successfully.";
+       $xestiascan_lang{"en-GB"}{"scannerstableerror"} = "An error occured while creating the permissions table for scanners: ";
+       $xestiascan_lang{"en-GB"}{"scannerstablesuccess"} = "The permissions table for scanners was created successfully.";
+       $xestiascan_lang{"en-GB"}{"sessionstableerror"} = "An error occured while creating the permissions table for scanners: ";
+       $xestiascan_lang{"en-GB"}{"sessionstablesuccess"} = "The sessions table was created successfully.";
+       $xestiascan_lang{"en-GB"}{"userstableerror"} = "An error occured while creating the permissions table for users: ";
+       $xestiascan_lang{"en-GB"}{"userstablesuccess"} = "The users table was created successfully.";
+       $xestiascan_lang{"en-GB"}{"adminaccounterror"} = "An error occured whilst trying to create the administrative account: ";
+       $xestiascan_lang{"en-GB"}{"adminaccountsuccess"} = "The administrative account was created successfully.";
+
+       $xestiascan_lang{"en-GB"}{"autherroroccured"} = "An error occured whilst using the authentication module: ";
+
+
+#################################################################################
+# Begin list of subroutines.                                                   #
+#################################################################################
+
+sub xestiascan_variablecheck{
+#################################################################################
+# xestiascan_variablecheck: Check to see if the data passed is valid.          #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_variablecheck(variablename, type, option, noerror);               #
+#                                                                              #
+# variablename Specifies the variable to be checked.                           #
+# type         Specifies what type the variable is.                            #
+# option       Specifies the maximum/minimum length of the variable            #
+#              (if minlength/maxlength is used) or if the filename should be   #
+#              checked to see if it is blank.                                  #
+# noerror      Specifies if Xestia Scanner Server should return an error or not#
+#              on certain values.                                              #
+#################################################################################
+
+       # Get the values that were passed to the subroutine.
+
+       my ($variable_data, $variable_type, $variable_option, $variable_noerror) = @_;
+
+       if ($variable_type eq "numbers"){
+
+               # Check for numbers and return an error if there is anything else than numebrs.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated.
+               $variable_data_validated =~ tr/0-9//d;          # Take away all of the numbers and from the variable. 
+                                                               # If it only contains numbers then it should be blank.
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "lettersnumbers"){
+
+               # Check for letters and numbers and return an error if there is anything else other
+               # than letters and numbers.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated
+               $variable_data_validated =~ tr/a-zA-Z0-9.//d;
+               $variable_data_validated =~ s/\s//g;
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "maxlength"){
+               # Check for the length of the variable, return an error if it is longer than the length specified.
+
+               # Check if the variable_data string is blank, if it is then set the variable_data_length
+               # to '0'.
+
+               my $variable_data_length = 0;
+
+               if (!$variable_data){
+
+                       # Set variable_data_length to '0'.
+                       $variable_data_length = 0;
+
+               } else {
+
+                       # Get the length of the variable recieved.
+                       $variable_data_length = length($variable_data);
+
+               }
+
+
+
+               if ($variable_data_length > $variable_option){
+
+                       # The variable length is longer than it should be so check if
+                       # the no error value is set 1.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1, so return an
+                               # value of 1 (meaning tha the variable is
+                               # too long to be used).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0, so return
+                               # an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       }
+
+               } else {
+
+                       # The variable length is exactly or shorter than specified, so continue to end of this section where
+                       # the return function should be.
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "datetime"){
+               # Check if the date and time setting format is valid.
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the date and
+                               # time format was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("dateformatblank");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr|dDmMyYhms/():[ ]||d;
+
+               if ($variable_data_validated eq ""){
+
+                       # The date and time format is valid. So
+                       # skip this bit.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the date and
+                               # time format was invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("dateformatinvalid");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "directory"){
+               # Check if the directory only contains letters and numbers and
+               # return an error if anything else appears.
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the directory
+                               # name was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankdirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               if ($variable_data_validated eq ""){
+
+                       # The validated data variable is blank, meaning that
+                       # it only contains letters and numbers.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the directory
+                               # name is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("invaliddirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "language_filename"){
+
+               # The variable type is a language filename type.
+               # Check if the language file name is blank and 
+               # if it is then return an error (or value).
+
+               if ($variable_data eq ""){
+
+                       # The language filename is blank so check the
+                       # no error value and return an error (or value).
+
+                       if ($variable_noerror eq 1){
+
+                               # Language filename is blank and the no error value
+                               # is set as 1, so return a value of 1 (saying that
+                               # the language filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Language filename is blank and the no error value
+                               # is not set as 1, so return an error.
+
+                               xestiascan_error("languagefilenameblank");
+
+                       } else {
+
+                               # The noerror value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               # Set the following variables for later on.
+
+               my $variable_data_length = 0;
+               my $variable_data_char = "";
+               my $variable_data_seek = 0;
+
+               # Get the length of the language file name.
+
+               $variable_data_length = length($variable_data);
+
+               do {
+
+                       # Get a character from the language filename passed to this 
+                       # subroutine and the character the seek counter value is set
+                       # to.
+
+                       $variable_data_char = substr($variable_data, $variable_data_seek, 1);
+
+                       # Check if the language filename contains a forward slash or a dot, 
+                       # if the selected character is a forward slash then return an error
+                       # (or value).
+
+                       if ($variable_data_char eq "/" || $variable_data_char eq "."){
+
+                               # The language filename contains a forward slash or
+                               # a dot so depending on the no error value, return
+                               # an error or a value.
+
+                               if ($variable_noerror eq 1){
+
+                                       # Language filename contains a forward slash or a dot
+                                       # and the no error value has been set to 1, so return 
+                                       # an value of 2 (saying that the language file name is 
+                                       # invalid).
+
+                                       return 2;
+
+                               } elsif ($variable_noerror eq 0) {
+
+                                       # Language filename contains a forward slash and the no
+                                       # error value has not been set to 1, so return an error.
+
+                                       xestiascan_error("languagefilenameinvalid");
+
+                               } else {
+
+                                       # The noerror value is something else other than
+                                       # 1 or 0 so return an error.
+
+                                       xestiascan_error("invalidvariable");
+
+                               }
+
+                       }
+
+                       # Increment the seek counter.
+
+                       $variable_data_seek++;
+
+               } until ($variable_data_seek eq $variable_data_length);
+
+               return 0;
+
+       } elsif ($variable_type eq "module"){
+
+               # The variable type is a presentation module filename.
+
+               # Check if the variable_data is blank and if it is
+               # return an error.
+
+               if ($variable_data eq ""){
+
+                       # The presentation module is blank so check if an error
+                       # value should be returned or a number should be
+                       # returned.
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name is blank and the no error value 
+                               # is set to 1 so return a value of 2 (meaning 
+                               # that the page filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains is blank and the no error 
+                               # value is set to 0 so return an error.
+
+                               xestiascan_critical("moduleblank");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_critical("invalidvalue");
+
+                       }
+
+               } else {
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data_validated eq ""){
+
+               } else {
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 1 so return a 
+                               # value of 2 (meaning that the page filename
+                               # is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 0 so return an
+                               # error.
+
+                               xestiascan_critical("moduleinvalid");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvalue");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "serverprotocol"){
+
+               # Check if the server protocol is TCP or UDP and return
+               # an error if it isn't.
+
+               if ($variable_data ne "tcp" && $variable_data ne "udp"){
+
+                       # The protocol given is not valid, check if the no
+                       # error value is set to 1 and return an error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the server protocol is
+                               # invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverprotocolinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "port"){
+
+               # Check if the port number given is less than 0 or more than 65535
+               # and return an error if it is.
+
+               if ($variable_data < 0 || $variable_data > 65535){
+
+                       # The port number is less than 0 and more than 65535 so
+                       # check if the no error value is set to 1 and return an
+                       # error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the port number is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverportnumberinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "utf8"){
+               
+               # The variable type is a UTF8 string.
+               
+               if (!$variable_data){
+                       
+                       $variable_data = "";
+                       
+               }
+               
+               my $chunk = 0;
+               my $process = 8192;
+               my $length = 0;
+               my $chunkdata = "";
+               
+               while ($chunk < $length){
+                       
+                       $chunkdata = substr($variable_data, $chunk, $process);
+                       
+                       if ($chunkdata =~ m/\A(
+                               [\x09\x0A\x0D\x20-\x7E]            # ASCII
+                               | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
+                               |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
+                               | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
+                       |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
+                       |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
+                       | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
+                       |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
+                       )*\z/x){
+                               
+                               # The UTF-8 string is valid.
+                               
+                       } else {
+                               
+                               # The UTF-8 string is not valid, check if the no error
+                               # value is set to 1 and return an error if it isn't.
+                               
+                               if ($variable_noerror eq 1){
+                                       
+                                       # The no error value has been set to 1, so return
+                                       # a value of 1 (meaning that the UTF-8 string is
+                                       # invalid).
+                                       
+                                       return 1; 
+                                       
+                               } elsif ($variable_noerror eq 0) {
+                                       
+                                       # The no error value has been set to 0, so return
+                                       # an error.
+                                       
+                                       xestiascan_error("invalidutf8");
+                                       
+                               } else {
+                                       
+                                       # The no error value is something else other than 0
+                                       # or 1, so return an error.
+                                       
+                                       xestiascan_error("invalidoption");
+                                       
+                               }
+                               
+                       }
+                       
+                       
+                       $chunk = $chunk + $process;
+                       
+               }
+               
+               return 0;
+               
+       }
+
+       # Another type than the valid ones above has been specified so return an error specifying an invalid option.
+       xestiascan_error("invalidoption");
+
+}
+
+sub xestiascan_error{
+#################################################################################
+# xestiascan_error: Subroutine for processing error messages.                  #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_error(errortype);                                                 #
+#                                                                              #
+# errortype    Specifies the error type to use.                                #
+#################################################################################
+
+       my $error_type = shift;
+
+       # Load the list of error messages.
+
+       my (%xestiascan_error, $xestiascan_error);
+
+       %xestiascan_error = (
+
+               # Generic Error Messages
+
+               "generic"                       => $xestiascan_lang{$language_selected}{generic},
+
+               "invalidvariable"               => $xestiascan_lang{$language_selected}{invalidvariable},
+               "invalidvalue"                  => $xestiascan_lang{$language_selected}{invalidvalue},
+               "invalidoption"                 => $xestiascan_lang{$language_selected}{invalidoption},
+               "variabletoolong"               => $xestiascan_lang{$language_selected}{variabletoolong},
+               "blankdirectory"                => $xestiascan_lang{$language_selected}{blankdirectory},
+               "invaliddirectory"              => $xestiascan_lang{$language_selected}{invaliddirectory},
+               "moduleblank"                   => $xestiascan_lang{$language_selected}{moduleblank},
+               "moduleinvalid"                 => $xestiascan_lang{$language_selected}{moduleinvalid},
+
+               # Specific Error Messages
+
+               "dbdirectorytoolong"            => $xestiascan_lang{$language_selected}{dbdirectorytoolong},
+               "outputdirectorytoolong"        => $xestiascan_lang{$language_selected}{outputdirectorytoolong},
+               "imagesuripathtoolong"          => $xestiascan_lang{$language_selected}{imagesuripathtoolong},
+               "dateformattoolong"             => $xestiascan_lang{$language_selected}{dateformattoolong},
+               "customdateformattoolong"       => $xestiascan_lang{$language_selected}{customdateformattoolong},
+               "languagefilenametoolong"       => $xestiascan_lang{$language_selected}{languagefilenametoolong},
+               
+               "dateformatblank"               => $xestiascan_lang{$language_selected}{dateformatblank},
+               "dateformatinvalid"             => $xestiascan_lang{$language_selected}{dateformatinvalid},
+               "languagefilenameinvalid"       => $xestiascan_lang{$language_selected}{languagefilenameinvalid},
+               
+               "dbdirectoryblank"              => $xestiascan_lang{$language_selected}{dbdirectoryblank},
+               "dbdirectoryinvalid"            => $xestiascan_lang{$language_selected}{dbdirectoryinvalid},
+
+               "textarearowblank"              => $xestiascan_lang{$language_selected}{textarearowblank},
+               "textarearowtoolong"            => $xestiascan_lang{$language_selected}{textarearowtoolong},
+               "textarearowinvalid"            => $xestiascan_lang{$language_selected}{textarearowinvalid},
+
+               "textareacolsblank"             => $xestiascan_lang{$language_selected}{textareacolsblank},
+               "textareacolstoolong"           => $xestiascan_lang{$language_selected}{textareacolstoolong},
+               "textareacolsinvalid"           => $xestiascan_lang{$language_selected}{textareacolsinvalid},
+
+               "outputdirectoryblank"          => $xestiascan_lang{$language_selected}{outputdirectoryblank},
+               "outputdirectoryinvalid"        => $xestiascan_lang{$language_selected}{outputdirectoryinvalid},
+
+               "presmoduleblank"               => $xestiascan_lang{$language_selected}{presmoduleblank},
+               "presmoduleinvalid"             => $xestiascan_lang{$language_selected}{presmoduleinvalid},
+
+               "authmoduleblank"               => $xestiascan_lang{$language_selected}{authmoduleblank},
+               "authmoduleinvalid"             => $xestiascan_lang{$language_selected}{authmoduleinvalid},
+               "authmoduleinvalidpermissions"  => $xestiascan_lang{$language_selected}{authmoduleinvalidpermissions},
+
+               "presmodulemissing"             => $xestiascan_lang{$language_selected}{presmodulemissing},
+               "authmodulemissing"             => $xestiascan_lang{$language_selected}{authmodulemissing},
+               "languagefilenamemissing"       => $xestiascan_lang{$language_selected}{languagefilenamemissing},
+
+               "servernametoolong"             => $xestiascan_lang{$language_selected}{servernametoolong},
+               "servernameinvalid"             => $xestiascan_lang{$language_selected}{servernameinvalid},
+               "serverportnumbertoolong"       => $xestiascan_lang{$language_selected}{serverportnumbertoolong},
+               "serverportnumberinvalidcharacters"     => $xestiascan_lang{$language_selected}{serverportnumberinvalidcharacters},
+               "serverportnumberinvalid"       => $xestiascan_lang{$language_selected}{serverportnumberinvalid},
+               "serverprotocolnametoolong"     => $xestiascan_lang{$language_selected}{serverprotocolnametoolong},
+               "serverprotocolinvalid"         => $xestiascan_lang{$language_selected}{serverprotocolinvalid},
+               "serverdatabasenametoolong"     => $xestiascan_lang{$language_selected}{serverdatabasenametoolong},
+               "serverdatabasenameinvalid"     => $xestiascan_lang{$language_selected}{serverdatabasenameinvalid},
+               "serverdatabaseusernametoolong" => $xestiascan_lang{$language_selected}{serverdatabaseusernametoolong},
+               "serverdatabaseusernameinvalid" => $xestiascan_lang{$language_selected}{serverdatabaseusernameinvalid},
+               "serverdatabasepasswordtoolong" => $xestiascan_lang{$language_selected}{serverdatabasepasswordtoolong},
+               "serverdatabasetableprefixtoolong"      => $xestiascan_lang{$language_selected}{serverdatabasetableprefixtoolong},
+               "serverdatabasetableprefixinvalid"      => $xestiascan_lang{$language_selected}{serverdatabasetableprefixinvalid},
+               "createmodulestoolong"                  => $xestiascan_lang{$language_selected}{createmodulestoolong},
+               "createscannerstoolong"                 => $xestiascan_lang{$language_selected}{createscannerstoolong},
+               "createsessionstoolong"                 => $xestiascan_lang{$language_selected}{createsessionstoolong},
+               "createuserstoolong"                    => $xestiascan_lang{$language_selected}{createuserstoolong},
+               "forcerecreatetoolong"                  => $xestiascan_lang{$language_selected}{forcerecreatetoolong},
+               "deleteinstalltoolong"                  => $xestiascan_lang{$language_selected}{deleteinstalltoolong},
+               "deletemultiusertoolong"                => $xestiascan_lang{$language_selected}{deletemultiusertoolong},
+       
+               "removeinstallscripttoolong"    => $xestiascan_lang{$language_selected}{removeinstallscripttoolong},
+               "cannotwriteconfigurationindirectory"   => $xestiascan_lang{$language_selected}{cannotwriteconfigurationindirectory},
+               "configurationfilereadpermissionsinvalid"       => $xestiascan_lang{$language_selected}{configurationfilereadpermissionsinvalid},
+               "configurationfilewritepermissionsinvalid"      => $xestiascan_lang{$language_selected}{configurationfilewritepermissionsinvalid},
+
+       );
+
+       # Check if the specified error is blank and if it is
+       # use the generic error messsage.
+
+       if (!$xestiascan_error{$error_type}){
+               $error_type = "generic";
+       }
+
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+
+       print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+       print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>\n";
+
+       print "<h2>$xestiascan_lang{$language_selected}{error}</h2>";
+
+       print $xestiascan_error{$error_type};
+       print "<br />\n";
+       print $xestiascan_lang{$language_selected}{errormessagetext};
+
+       print "</body>\n</html>";
+
+       exit;
+
+}
+
+sub xestiascan_processconfig{
+#################################################################################
+# xestiascan_processconfig: Processes an INI style configuration file.         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_processconfig(data);                                              #
+#                                                                              #
+# data Specifies the data to process.                                          #
+#################################################################################
+
+       my (@settings) = @_;
+
+       my ($settings_line, %settings, $settings, $sectionname, $setting_name, $setting_value);
+
+       foreach $settings_line (@settings){
+
+               next if !$settings_line;
+
+               # Check if the first character is a bracket.
+
+               if (substr($settings_line, 0, 1) eq "["){
+                       $settings_line =~ s/\[//;
+                       $settings_line =~ s/\](.*)//;
+                       $settings_line =~ s/\n//;
+                       $sectionname = $settings_line;
+                       next;
+               }
+
+               $setting_name  = $settings_line;
+               $setting_value = $settings_line;
+               $setting_name  =~ s/\=(.*)//;
+               $setting_name  =~ s/\n//;
+               $setting_value =~ s/(.*)\=//;
+               $setting_value =~ s/\n//;
+
+               # Remove the spacing before and after the '=' sign.
+
+               $setting_name =~ s/\s+$//;
+               $setting_value =~ s/^\s+//;
+               $setting_value =~ s/\r//;
+
+               $settings{$sectionname}{$setting_name} = $setting_value;
+
+       }
+
+       return %settings;
+
+}
+
+sub xestiascan_fileexists{
+       #################################################################################
+       # xestiascan_fileexists: Check if a file exists and returns a value depending on #
+       # if the file exists or not.                                                    #
+       #                                                                               # 
+       # Usage:                                                                        #
+       #                                                                               #
+       # xestiascan_fileexists(filename);                                              #
+       #                                                                               #
+       # filename      Specifies the file name to check if it exists or not.           #
+       #################################################################################
+       
+       # Get the value that was passed to the subroutine.
+       
+       my ($filename) = @_;
+       
+       # Check if the filename exists, if it does, return a value of 0, else
+       # return a value of 1, meaning that the file was not found.
+       
+       if (-e $filename){
+               
+               # Specified file does exist so return a value of 0.
+               
+               return 0;
+               
+       } else {
+               
+               # Specified file does not exist so return a value of 1.
+               
+               return 1;
+               
+       }
+       
+}
+
+sub xestiascan_filepermissions{
+       #################################################################################
+       # xestiascan_filepermissions: Check if the file permissions of a file and return #
+       # either a 1 saying that the permissions are valid or return a 0 saying that    #
+       # the permissions are invalid.                                                  #
+       #                                                                               #
+       # Usage:                                                                        #
+       #                                                                               #
+       # xestiascan_filepermissions(filename, [read], [write], [filemissingskip]);     #
+       #                                                                               #
+       # filename              Specifies the filename to check for permissions.        #
+       # read                  Preform check that the file is readable.                #
+       # write                 Preform check that the file is writeable.               #
+       # filemissingskip       Skip the check of seeing if it can read or write if the #
+       #                       file is missing.                                        #
+       #################################################################################
+       
+       # Get the values that was passed to the subroutine.
+       
+       my ($filename, $readpermission, $writepermission, $ignorechecks) = @_;
+       
+       # Check to make sure that the read permission and write permission values
+       # are only 1 character long.
+       
+       xestiascan_variablecheck($readpermission, "maxlength", 1, 0);
+       xestiascan_variablecheck($writepermission, "maxlength", 1, 0);
+       xestiascan_variablecheck($ignorechecks, "maxlength", 1, 0);
+       
+       my $ignorechecks_result = 0;
+       
+       # Check if the file should be ignored for read and write checking if 
+       # it doesn't exist.
+       
+       if ($ignorechecks){
+               
+               if (-e $filename){
+                       
+                       # The file exists so the checks are to be done.
+                       
+                       $ignorechecks_result = 0;
+                       
+               } else {
+                       
+                       # The file does not exist so the checks don't need to
+                       # be done to prevent false positives.
+                       
+                       $ignorechecks_result = 1;
+                       
+               }
+               
+       } else {
+               
+               $ignorechecks_result = 0;
+               
+       }
+       
+       # Check if the file should be checked to see if it can be read.
+       
+       if ($readpermission && $ignorechecks_result eq 0){
+               
+               # The file should be checked to see if it does contain read permissions
+               # and return a 0 if it is invalid.
+               
+               if (-r $filename){
+                       
+                       # The file is readable, so do nothing.
+                       
+               } else {
+                       
+                       # The file is not readable, so return 1.
+                       
+                       return 1;
+                       
+               }
+               
+       }
+       
+       # Check if the file should be checked to see if it can be written.
+       
+       if ($writepermission && $ignorechecks_result eq 0){
+               
+               # The file should be checked to see if it does contain write permissions
+               # and return a 0 if it is invalid.
+               
+               if (-w $filename){
+                       
+                       # The file is writeable, so do nothing.
+                       
+               } else {
+                       
+                       # The file is not writeable, so return 1.
+                       
+                       return 1;
+                       
+               }
+               
+       }
+       
+       # No problems have occured, so return 0.
+       
+       return 0;
+       
+}
+
+sub xestiascan_settings_load{
+#################################################################################
+# xestiascan_settings_load: Load the configuration settings into the global    #
+# variables.                                                                   #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_settings_load();                                                  #
+#################################################################################
+
+       # Check if the Xestia Scanner Server configuration file exists before using it and
+       # return an critical error if it doesn't exist.
+
+       my ($xestiascan_settingsfilehandle, @config_data, %config, $config);
+       my $xestiascan_conf_exist = xestiascan_fileexists("xsdss.cfg");
+
+       if ($xestiascan_conf_exist eq 1){
+
+               # The configuration really does not exist so return an critical error.
+               
+               return 1;
+
+       }
+       
+       # Check if the Xestia Scanner Server configuration file has valid permission settings
+       # before using it and return an critical error if it doesn't have the
+       # valid permission settings.
+
+       my $xestiascan_conf_permissions = xestiascan_filepermissions("xsdss.cfg", 1, 0);
+
+       if ($xestiascan_conf_permissions eq 1){
+
+               # The permission settings for the Xestia Scanner Server configuration file are
+               # invalid, so return an critical error.
+               
+               return 1;
+
+       }
+
+       # Converts the file into meaningful data for later on in this subroutine.
+
+       my $xestiascan_conf_file = 'xsdss.cfg';
+
+       open($xestiascan_settingsfilehandle, $xestiascan_conf_file);
+       binmode $xestiascan_settingsfilehandle, ':utf8';
+       @config_data = <$xestiascan_settingsfilehandle>;
+       %config = xestiascan_processconfig(@config_data);
+       close($xestiascan_settingsfilehandle);
+
+       # Go and fetch the settings and place them into a hash.
+       
+       %xestiascan_config = (
+
+               "system_language"               => $config{config}{system_language},
+               "system_presmodule"             => $config{config}{system_presmodule},
+               "system_authmodule"             => $config{config}{system_authmodule},
+               "system_outputmodule"           => $config{config}{system_outputmodule},
+               "system_datetime"               => $config{config}{system_datetime},
+               
+               "database_server"               => $config{config}{database_server},
+               "database_port"                 => $config{config}{database_port},
+               "database_protocol"             => $config{config}{database_protocol},
+               "database_sqldatabase"          => $config{config}{database_sqldatabase},
+               "database_username"             => $config{config}{database_username},
+               "database_password"             => $config{config}{database_password},
+               "database_tableprefix"          => $config{config}{database_tableprefix}
+
+       );
+
+       # Do a validation check on all of the variables that were loaded into the global configuration hash.
+
+       my $xestiascan_config_dbmodule_filename = xestiascan_variablecheck($xestiascan_config{"system_authmodule"}, "module", 0, 1);
+
+       # Check if the database module name is valid.
+
+       if ($xestiascan_config_dbmodule_filename eq 1){
+
+               # The database module filename given is blank so return.
+               
+               return 1;
+
+       }
+
+       if ($xestiascan_config_dbmodule_filename eq 2){
+
+               # The database module filename given is invalid so return
+               # an critical error.
+
+               return 1;
+
+       }
+
+       # Check if the database module does exist before loading it and return an critical error
+       # if the database module does not exist.
+
+       my $xestiascan_config_dbmodule_fileexists = xestiascan_fileexists("Modules/Auth/" . $xestiascan_config{"system_authmodule"} . ".pm");
+
+       if ($xestiascan_config_dbmodule_fileexists eq 1){
+
+               # Database module does not exist so return an critical error.
+               
+               return 1;
+
+       }
+
+       # Check if the database module does have the valid permission settings and return an
+       # critical error if the database module contains invalid permission settings.
+
+       my $xestiascan_config_dbmodule_permissions = xestiascan_filepermissions("Modules/Auth/" . $xestiascan_config{"system_authmodule"} . ".pm", 1, 0);
+
+       if ($xestiascan_config_dbmodule_permissions eq 1){
+
+               # Presentation module contains invalid permissions so return an critical error.
+               
+               return 1;
+
+       }
+       
+       return 0;
+
+}
+
+sub xestiascan_addtablerow{
+#################################################################################
+# xestiascan_addtablerow: Adds a table row.                                    #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_addtablerow(name, data);                                          #
+#                                                                              #
+# name         Specifies the name of the table row.                            #
+# namestyle    Specifies the style for the name of the table row.              #
+# data         Specifies the data to be used in the table row.                 #
+# datastyle    Specifies the style for the data of the table row.              #
+#################################################################################
+
+       my ($name, $namestyle, $data, $datastyle) = @_;
+
+       if (!$data){
+
+               $data = "";
+
+       }
+
+       print "<tr>\n";
+       print "<td class=\"$namestyle\">$name</td>\n";
+       print "<td class=\"$datastyle\">$data</td>\n";
+       print "</tr>\n";
+
+}
+
+#################################################################################
+# End list of subroutines.                                                     #
+#################################################################################
+
+# Process the list of available languages.
+
+my $language_list_name;
+my @language_list_short;
+my @language_list_long;
+
+foreach my $language (keys %xestiascan_lang){
+
+       $language_list_name = $xestiascan_lang{$language}{"languagename"} . " (" . $language .  ")";
+       push(@language_list_short, $language);
+       push(@language_list_long, $language_list_name);
+
+}
+
+my $http_query_confirm = $form_data->{'confirm'};
+
+$http_query_confirm = 0 if !$http_query_confirm;
+
+if ($http_query_confirm eq 1){
+
+       # The action to create the tables has been confirmed. Get
+       # the required values.
+       
+       my $http_query_authmodule       = $form_data->{'authmodule'};
+       
+       my $http_query_databaseserver   = $form_data->{'databaseserver'};
+       my $http_query_databaseport     = $form_data->{'databaseport'};
+       my $http_query_databaseprotocol = $form_data->{'databaseprotocol'};
+       my $http_query_databasename     = $form_data->{'databasename'};
+       my $http_query_databaseusername = $form_data->{'databaseusername'};
+       my $http_query_databasepassword = $form_data->{'databasepassword'};
+       my $http_query_databasetableprefix      = $form_data->{'databasetableprefix'};
+       
+       my $http_query_adminusername    = $form_data->{'multiuseradminusername'};
+       my $http_query_adminpassword    = $form_data->{'multiuseradminpassword'};
+       
+       my $http_query_createmodules    = $form_data->{'createmodules'};
+       my $http_query_createscanners   = $form_data->{'createscanners'};
+       my $http_query_createsessions   = $form_data->{'createsessions'};
+       my $http_query_createusers      = $form_data->{'createusers'};
+       
+       my $http_query_forcerecreate    = $form_data->{'forcerecreate'};
+       
+       my $http_query_deleteinstall    = $form_data->{'deleteinstall'};
+       my $http_query_deletemultiuser  = $form_data->{'deleteinstallmultiuser'};
+       
+       # Check the data that has been passed to the multiuser installer.
+       
+       if (!$http_query_createmodules){
+               
+               $http_query_createmodules = "off";
+               
+       }
+
+       if (!$http_query_createscanners){
+               
+               $http_query_createscanners = "off";
+               
+       }
+
+       if (!$http_query_createsessions){
+               
+               $http_query_createsessions = "off";
+               
+       }
+       
+       if (!$http_query_createusers){
+               
+               $http_query_createusers = "off";
+               
+       }
+       
+       if (!$http_query_forcerecreate){
+               
+               $http_query_forcerecreate = "off";
+               
+       }
+       
+       if (!$http_query_deleteinstall){
+       
+               $http_query_deleteinstall = "off";
+               
+       }
+       
+       if (!$http_query_deletemultiuser){
+               
+               $http_query_deletemultiuser = "off";
+               
+       }
+       
+       my $xestiascan_authmodule_modulename_check              = xestiascan_variablecheck($http_query_authmodule, "module", 0, 1);
+       my $xestiascan_databaseserver_length_check              = xestiascan_variablecheck($http_query_databaseserver, "maxlength", 128, 1);
+       my $xestiascan_databaseserver_lettersnumbers_check      = xestiascan_variablecheck($http_query_databaseserver, "lettersnumbers", 0, 1);
+       my $xestiascan_databaseport_length_check                = xestiascan_variablecheck($http_query_databaseport, "maxlength", 5, 1);
+       my $xestiascan_databaseport_numbers_check               = xestiascan_variablecheck($http_query_databaseport, "numbers", 0, 1);
+       my $xestiascan_databaseport_port_check                  = xestiascan_variablecheck($http_query_databaseport, "port", 0, 1);
+       my $xestiascan_databaseprotocol_length_check            = xestiascan_variablecheck($http_query_databaseprotocol, "maxlength", 5, 1);
+       my $xestiascan_databaseprotocol_protocol_check          = xestiascan_variablecheck($http_query_databaseprotocol, "serverprotocol", 0, 1);
+       my $xestiascan_databasename_length_check                = xestiascan_variablecheck($http_query_databasename, "maxlength", 32, 1);
+       my $xestiascan_databasename_lettersnumbers_check        = xestiascan_variablecheck($http_query_databasename, "lettersnumbers", 0, 1);
+       my $xestiascan_databaseusername_length_check            = xestiascan_variablecheck($http_query_databaseusername, "maxlength", 16, 1);
+       my $xestiascan_databaseusername_lettersnumbers_check    = xestiascan_variablecheck($http_query_databaseusername, "lettersnumbers", 0, 1);
+       my $xestiascan_databasepassword_length_check            = xestiascan_variablecheck($http_query_databasepassword, "maxlength", 64, 1);
+       my $xestiascan_databasetableprefix_length_check         = xestiascan_variablecheck($http_query_databasetableprefix, "maxlength", 16, 1);
+       my $xestiascan_databasetableprefix_lettersnumbers_check = xestiascan_variablecheck($http_query_databasetableprefix, "lettersnumbers", 0, 1);
+       
+       if ($xestiascan_authmodule_modulename_check eq 1){
+               
+               # The database module name is blank, so return
+               # an error.
+               
+               xestiascan_error("authmoduleblank");
+               
+       }
+       
+       if ($xestiascan_authmodule_modulename_check eq 2){
+               
+               # The database module name is invalid, so return
+               # an error.
+               
+               xestiascan_error("authmoduleinvalid");
+               
+       }
+       
+       if (!-e "Modules/Auth/" . $http_query_authmodule . ".pm"){
+               
+               # The database module is missing so return an
+               # error.
+               
+               xestiascan_error("authmodulemissing");
+               
+       }
+       
+       if ($xestiascan_databaseserver_length_check eq 1){
+               
+               # The length of the database server name is too long so
+               # return an error.
+               
+               xestiascan_error("servernametoolong");
+               
+       }
+       
+       if ($xestiascan_databaseserver_lettersnumbers_check eq 1){
+               
+               # The database server name contains characters other
+               # than letters and numbers, so return an error.
+               
+               xestiascan_error("servernameinvalid");
+               
+       }
+       
+       if ($xestiascan_databaseport_length_check eq 1){
+               
+               # The database port number length is too long so return
+               # an error.
+               
+               xestiascan_error("serverportnumbertoolong");
+               
+       }
+       
+       if ($xestiascan_databaseport_numbers_check eq 1){
+               
+               # The database port number contains characters other
+               # than numbers so return an error.
+               
+               xestiascan_error("serverportnumberinvalidcharacters");
+               
+       }
+       
+       if ($xestiascan_databaseport_port_check eq 1){
+               
+               # The database port number given is invalid so return
+               # an error.
+               
+               xestiascan_error("serverportnumberinvalid");
+               
+       }
+       
+       if ($xestiascan_databaseprotocol_length_check eq 1){
+               
+               # The database protocol name given is too long so
+               # return an error.
+               
+               xestiascan_error("serverprotocolnametoolong");
+               
+       }
+       
+       if ($xestiascan_databaseprotocol_protocol_check eq 1){
+               
+               # The server protcol given is invalid so return
+               # an error.
+               
+               xestiascan_error("serverprotocolinvalid");
+               
+       }
+       
+       if ($xestiascan_databasename_length_check eq 1){
+               
+               # The SQL database name is too long so return
+               # an error.
+               
+               xestiascan_error("serverdatabasenametoolong");
+               
+       }
+       
+       if ($xestiascan_databasename_lettersnumbers_check eq 1){
+               
+               # The database name contains invalid characters
+               # so return an error.
+               
+               xestiascan_error("serverdatabasenameinvalid");
+               
+       }
+       
+       if ($xestiascan_databaseusername_length_check eq 1){
+               
+               # The database username given is too long so
+               # return an error.
+               
+               xestiascan_error("serverdatabaseusernametoolong");
+               
+       }
+       
+       if ($xestiascan_databaseusername_lettersnumbers_check eq 1){
+               
+               # The database username contains invalid characters
+               # so return an error.
+               
+               xestiascan_error("serverdatabaseusernameinvalid");
+               
+       }
+       
+       if ($xestiascan_databasepassword_length_check eq 1){
+               
+               # The database password given is too long so return
+               # an error.
+               
+               xestiascan_error("serverdatabasepasswordtoolong");
+               
+       }
+       
+       if ($xestiascan_databasetableprefix_length_check eq 1){
+               
+               # The database table prefix given is too long so
+               # return an error.
+               
+               xestiascan_error("serverdatabasetableprefixtoolong");
+               
+       }
+       
+       if ($xestiascan_databasetableprefix_lettersnumbers_check eq 1){
+               
+               # The database table prefix given contains invalid
+               # characters so return an error.
+               
+               xestiascan_error("serverdatabasetableprefixinvalid");
+               
+       }
+       
+       # Check the admin username and password to make sure they have valid UTF-8.
+
+       xestiascan_variablecheck($http_query_adminusername, "utf8", 0, 0);
+       xestiascan_variablecheck($http_query_adminpassword, "utf8", 0, 0);
+       
+       # Check the checkable values.
+       
+       my $xestiascan_createmodules_length_check               = xestiascan_variablecheck($http_query_createmodules, "maxlength", 3, 1);
+       my $xestiascan_createscanners_length_check              = xestiascan_variablecheck($http_query_createscanners, "maxlength", 3, 1);
+       my $xestiascan_createsessions_length_check              = xestiascan_variablecheck($http_query_createsessions, "maxlength", 3, 1);
+       my $xestiascan_createusers_length_check                 = xestiascan_variablecheck($http_query_createusers, "maxlength", 3, 1);
+       my $xestiascan_forcerecreate_length_check               = xestiascan_variablecheck($http_query_forcerecreate, "maxlength", 3, 1);
+       my $xestiascan_deleteinstall_length_check               = xestiascan_variablecheck($http_query_deleteinstall, "maxlength", 3, 1);
+       my $xestiascan_deletemultiuser_length_check             = xestiascan_variablecheck($http_query_deletemultiuser, "maxlength", 3, 1);
+       
+       if ($xestiascan_createmodules_length_check eq 1){
+               
+               xestiascan_error("createmodulestoolong");
+               
+       }
+       
+       if ($xestiascan_createscanners_length_check eq 1){
+       
+               xestiascan_error("createscannerstoolong");
+               
+       }
+       
+       if ($xestiascan_createsessions_length_check eq 1){
+
+               xestiascan_error("createsessionstoolong");
+               
+       }
+       
+       if ($xestiascan_createusers_length_check eq 1){
+       
+               xestiascan_error("createuserstoolong");
+               
+       }
+       
+       if ($xestiascan_forcerecreate_length_check eq 1){
+
+               xestiascan_error("forcerecreatetoolong");
+               
+       }
+       
+       if ($xestiascan_deleteinstall_length_check eq 1){
+               
+               xestiascan_error("deleteinstalltoolong");
+               
+       }
+       
+       if ($xestiascan_deletemultiuser_length_check eq 1){
+               
+               xestiascan_error("deletemultiusertoolong");
+               
+       }
+       
+       # Check to see if the tables need to be recreated forcibly.
+       
+       my $forcerecreate = 0;
+       
+       if ($http_query_forcerecreate eq "on"){
+               
+               $forcerecreate = 1;
+               
+       }
+       
+       # Load the authentication module. Double check to make sure
+       # it really is a multiuser module and throw an error if not.
+       
+       my $authmodule_fullname = "Auth::" . $http_query_authmodule;
+       ($authmodule_fullname) = $authmodule_fullname =~ m/^(.*)$/g; # CHECK THIS!!
+       eval "use " . $authmodule_fullname;
+       $authmodule_fullname = "Modules::Auth::" . $http_query_authmodule;
+       my $authmodule = $authmodule_fullname->new();
+       
+       my %authmodule_capabilities = $authmodule->capabilities();
+       
+       if ($authmodule_capabilities{'multiuser'} ne 1){
+       
+               # Return an error, this module is not a multiuser module.
+               
+               xestiascan_error("notmultiuser");
+               
+       }
+       
+       # Check if password value is blank and load settings files
+       # if this is the case.
+       
+       if (!$http_query_databasepassword){
+               
+               if (xestiascan_settings_load eq 0){
+                       
+                       $http_query_databasepassword = $xestiascan_config{"database_password"};
+                       
+               }
+               
+       }
+       
+       # Load the settings for the database server.
+       
+       $authmodule->loadsettings({ DateTime => "DD/MM/YY hh:mm:ss", Server => $http_query_databaseserver, Port => $http_query_databaseport, Protocol => $http_query_databaseprotocol, Database => $http_query_databasename, Username => $http_query_databaseusername, Password => $http_query_databasepassword, TablePrefix => $http_query_databasetableprefix });
+       
+       # Connect to the database server.
+       
+       $authmodule->connect();
+
+       if ($authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               print "Content-Type: text/html; charset=utf-8;\r\n\r\n";
+               print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+               print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n";
+               print "<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>";
+               
+               print "<div class=\"topbar\">
+               <span class=\"title\">" . $xestiascan_lang{$language_selected}{installertitle} .  "</span>";
+               print "</div>"; 
+               
+               print "<div class=\"pagespacing\">";
+               print $xestiascan_lang{$language_selected}{autherroroccured} . $authmodule->geterror(1);
+               print "</div>";
+               
+               exit;
+               
+       }
+
+       # Print the header part.
+       
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+       
+       print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+       print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n";
+       print "<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>";
+
+       print "<div class=\"topbar\">
+       <span class=\"title\">" . $xestiascan_lang{$language_selected}{installertitle} .  "</span>";
+       print "</div>"; 
+       
+       print "<div class=\"pagespacing\">\n";
+       print "<span class=\"pageheader\">$xestiascan_lang{$language_selected}{installertitle}</span><br /><br />\n";
+       
+       print $xestiascan_lang{$language_selected}{multiuserresults} . "<br /><br />";
+       
+       # Create/Recreate the tables as needed.
+       
+       if ($forcerecreate eq 1){
+       
+               print $xestiascan_lang{$language_selected}{forciblyrecreated};
+               
+       } else {
+       
+               print $xestiascan_lang{$language_selected}{notforciblyrecreated};
+               
+       }
+       
+       print "<br /><br />";
+       
+       # Create/Recreate the modules permissions table.
+       
+       if ($http_query_createmodules eq "on"){
+       
+               $authmodule->populatetables("modules", $forcerecreate);
+       
+               if ($authmodule->geterror eq "DatabaseError"){
+               
+                       print $xestiascan_lang{$language_selected}{modulestableerror} . $authmodule->geterror(1) . "<br />";    
+       
+               } else {
+                       
+                       print $xestiascan_lang{$language_selected}{modulestablesuccess} . "<br />";
+                       
+               }
+                       
+       }
+               
+       # Create/Recreate the scanners permissions table.
+
+       if ($http_query_createscanners eq "on"){
+       
+               $authmodule->populatetables("scanners", $forcerecreate);
+
+               if ($authmodule->geterror eq "DatabaseError"){
+               
+                       print $xestiascan_lang{$language_selected}{scannerstableerror} . $authmodule->geterror(1) . "<br />";   
+       
+               } else {
+               
+                       print $xestiascan_lang{$language_selected}{scannerstablesuccess} . "<br />";
+                       
+               }
+                       
+       }
+               
+       # Create/Recreate the sessions permissions table.
+
+       if ($http_query_createsessions eq "on"){
+       
+               $authmodule->populatetables("sessions", $forcerecreate);
+               
+               if ($authmodule->geterror eq "DatabaseError"){
+               
+                       print $xestiascan_lang{$language_selected}{sessionstableerror} . $authmodule->geterror(1) . "<br />";
+                       
+               } else {
+                       
+                       print $xestiascan_lang{$language_selected}{sessionstablesuccess} . "<br />";
+                       
+               }
+               
+       }
+       
+       # Create/Recreate the users table.
+       
+       if ($http_query_createusers eq "on"){
+       
+               $authmodule->populatetables("users", $forcerecreate);
+               
+               if ($authmodule->geterror eq "DatabaseError"){
+                       
+                       print $xestiascan_lang{$language_selected}{userstableerror} . $authmodule->geterror(1) . "<br />";
+                       
+               } else {
+                       
+                       print $xestiascan_lang{$language_selected}{userstablesuccess} . "<br />";
+               
+                       # Since the users table was created, add the Administrative account.
+                       
+                       my (%userinfo, $userinfo);
+                       
+                       $userinfo{Username} = $http_query_adminusername;
+                       $userinfo{Name} = "Administrator";
+                       $userinfo{Password} = $http_query_adminpassword; 
+                       $userinfo{Enabled} = "on";
+                       $userinfo{Admin} = "on";
+                       
+                       $authmodule->adduser($http_query_adminusername, %userinfo);
+                       
+                       if ($authmodule->geterror eq "DatabaseError"){
+                       
+                               print $xestiascan_lang{$language_selected}{adminaccounterror} . $authmodule->geterror(1) . "<br />";
+                               
+                       } else {
+                               
+                               print $xestiascan_lang{$language_selected}{adminaccountsuccess} . "<br />";
+                               
+                       }
+                       
+               }
+               
+       }
+       
+       print "<br />";
+
+       # Check if the scripts need deleting.
+       
+       my $installscriptmessage;
+       
+       if ($http_query_deleteinstall eq "on"){
+               
+               if (unlink($originstallscriptname)){
+                       
+                       print $xestiascan_lang{$language_selected}{installscriptremoved} . "<br />";
+                       
+               } else {
+
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{cannotremoveinstallerscript};
+                       $installscriptmessage =~ s/%s/$!/g;
+                       
+                       print $installscriptmessage . "<br />";
+                       
+               }
+               
+       } else {
+       
+               print $xestiascan_lang{$language_selected}{installscriptkept} . "<br />";
+               
+       }
+       
+       if ($http_query_deletemultiuser eq "on"){
+               
+               if (unlink($installscriptname)){
+               
+                       print $xestiascan_lang{$language_selected}{multiuserscriptremoved} . "<br />";  
+                       
+               } else {
+                       
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{cannotremovemultiuserinstallerscript};
+                       $installscriptmessage =~ s/%s/$!/g;
+                       
+                       print $installscriptmessage . "<br />";         
+                       
+               }
+               
+       } else {
+               
+               print $xestiascan_lang{$language_selected}{multiuserinstallscriptkept} . "<br />";
+               
+       }
+       
+       print "<br />";
+       
+       print $xestiascan_lang{$language_selected}{usexestiascannerservertext} . "<br /><br />";
+       
+       print "<a href=\"" . $xestiascanscriptname . "\">$xestiascan_lang{$language_selected}{usexestiascannerserverlink}</a>";
+       
+       print "</div>";
+       
+       exit;
+       
+}
+
+# Load the configuration file and get the required settings.
+
+# Check to see if the settings file is valid.
+
+# Get the list of database modules.
+
+opendir(DATABASEDIR, "Modules/Auth");
+my @dbmodule_directory = grep /m*\.pm$/, readdir(DATABASEDIR);
+closedir(DATABASEDIR);
+
+my @database_modules;
+
+foreach my $dbmodule_file (@dbmodule_directory){
+
+       # Get the friendly name for the database module.
+
+       next if $dbmodule_file =~ m/^\./;
+       next if $dbmodule_file !~ m/.pm$/;
+       $dbmodule_file =~ s/.pm$//g;
+       push(@database_modules, $dbmodule_file);
+
+}
+
+
+# Check to see if the database module does support a multiuser configuration.
+
+my $dbmodule;
+my $dbmodule_out = "";
+my @dbmodule_multiuser;
+my $dbmodule_fullname;
+my %dbmodule_capabilities;
+use lib "Modules/";
+
+foreach my $dbmodule_file (@database_modules){
+
+       # Load the module and see if has multiuser support and
+       # if it has then add it to the list of multiuser supported
+       # database modules and then unload it.
+
+       my $dbmodule_fullname = "Auth::" . $dbmodule_file;
+       ($dbmodule_fullname) = $dbmodule_fullname =~ m/^(.*)$/g; # CHECK THIS!!
+       eval "use " . $dbmodule_fullname;
+       $dbmodule_fullname = "Modules::Auth::" . $dbmodule_file;
+       $dbmodule = $dbmodule_fullname->new();
+
+       %dbmodule_capabilities = $dbmodule->capabilities();
+
+       undef($dbmodule);
+       
+       push(@dbmodule_multiuser, $dbmodule_file) if $dbmodule_capabilities{'multiuser'} eq 1;
+
+}
+
+# Print out a form specifying if the users and/or sessions table should be created.
+
+my $config_fail = 0;
+
+if (xestiascan_settings_load ne 0){
+
+       $config_fail = 1;
+       
+} else {
+       
+       $default_dbmodule       = $xestiascan_config{system_authmodule};
+       $default_server         = $xestiascan_config{database_server};
+       $default_port           = $xestiascan_config{database_port};
+       $default_protocol       = $xestiascan_config{database_protocol};
+       $default_name           = $xestiascan_config{database_sqldatabase};
+       $default_username       = $xestiascan_config{database_username};
+       $default_prefix         = $xestiascan_config{database_tableprefix};
+       
+}
+
+print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+
+print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n";
+print "<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>";
+
+# Start language bar.
+
+print "<div class=\"topbar\">
+<span class=\"title\">" . $xestiascan_lang{$language_selected}{installertitle} .  "</span>";
+
+my $language_name_short;
+my $language_list_seek = 0;
+my $installlanguage_out = "";
+
+$installlanguage_out = "<select name=\"installlanguage\">\n";
+
+foreach $language_name_short (@language_list_short){
+
+       $installlanguage_out = $installlanguage_out . "<option value=\"" . $language_name_short . "\">" . $language_list_long[$language_list_seek] . "</option>\n";
+       $language_list_seek++;
+
+}
+
+$installlanguage_out = $installlanguage_out . "</select>\n";
+
+print "<form action=\"" . $installscriptname . "\" method=\"POST\">\n$installlanguage_out\n<input type=\"submit\" value=\"$xestiascan_lang{$language_selected}{switch}\">\n</form>\n";
+print "</div>";
+
+print "<div class=\"pagespacing\">";
+
+print "<span class=\"pageheader\">$xestiascan_lang{$language_selected}{installertitle}</span><br /><br />\n";
+print $xestiascan_lang{$language_selected}{installertext};
+
+print "<br /><br />";
+
+if ($config_fail eq 1){
+
+       print $xestiascan_lang{$language_selected}{invalidconfigfile};
+       print "<br /><br />";
+       
+}
+
+print "<form action=\"" . $installscriptname . "\" method=\"POST\">";
+print "<input type=\"hidden\" name=\"confirm\" value=\"1\">\n<input type=\"hidden\" name=\"installlanguage\" value=\"$language_selected\">\n";
+
+# End of language bar, begin main installer part.
+
+print "<table width=\"100%\">";
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{authsettings}, "tablecellheader", "", "tablecellheader");
+
+$dbmodule_out = "<select name=\"authmodule\">";
+
+foreach my $dbmodule_file (@dbmodule_multiuser){
+       if ($default_dbmodule eq $dbmodule_file){
+               $dbmodule_out = $dbmodule_out . "<option value=\"$dbmodule_file\" selected>$dbmodule_file</option>";            
+       } else {
+               $dbmodule_out = $dbmodule_out . "<option value=\"$dbmodule_file\">$dbmodule_file</option>";
+       }
+}
+
+$dbmodule_out = $dbmodule_out . "</select><br />" . $xestiascan_lang{$language_selected}{multiuseronly};
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{authenticationmodule}, "tablename", $dbmodule_out, "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseserver}, "tablename", "<input type=\"text\" name=\"databaseserver\" size=\"32\" maxlength=\"128\" value=\"$default_server\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseport}, "tablename", "<input type=\"text\" name=\"databaseport\" maxlength=\"5\" size=\"5\" value=\"$default_port\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseprotocol}, "tablename", "<select name=\"databaseprotocol\">\n<option value=\"tcp\">tcp</option>\n<option value=\"udp\">udp</option>\n</select>\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasename}, "tablename", "<input type=\"text\" name=\"databasename\" size=\"32\" maxlength=\"32\" value=\"$default_name\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseusername}, "tablename", "<input type=\"text\" name=\"databaseusername\" size=\"16\" maxlength=\"16\" value=\"$default_username\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasepassword}, "tablename", "<input type=\"password\" name=\"databasepassword\" size=\"32\" maxlength=\"64\"><br />Leave password blank to use password in configuration file.\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasetableprefix}, "tablename", "<input type=\"text\" name=\"databasetableprefix\" size=\"32\" maxlength=\"32\" value=\"$default_prefix\">\n", "tabledata");
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{adminuseraccountsettings}, "tablecellheader", "", "tablecellheader");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{adminusername}, "tablename", "<input type=\"text\" name=\"multiuseradminusername\" size=\"32\" maxlength=\"32\" value=\"$xestiascan_lang{$language_selected}{adminaccountname}\">", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{adminpassword}, "tablename", "<input type=\"password\" name=\"multiuseradminpassword\" size=\"32\" maxlength=\"128\" value=\"$xestiascan_lang{$language_selected}{adminaccountpassword}\">", "tabledata");
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{installationoptions}, "tablecellheader", "", "tablecellheader");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{createtables}, "tablename", "<input type=\"checkbox\" name=\"createmodules\" checked>" . $xestiascan_lang{$language_selected}{createtablemodulepermissions} . "<br /><input type=\"checkbox\" name=\"createscanners\" checked>" . $xestiascan_lang{$language_selected}{createtablescannerspermissions} . "<br /><input type=\"checkbox\" name=\"createsessions\" checked>" . $xestiascan_lang{$language_selected}{createtablesessions} . "<br /><input type=\"checkbox\" name=\"createusers\" checked>" . $xestiascan_lang{$language_selected}{createtableusers} . "<br />", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{forcerecreate}, "tablename", "<input type=\"checkbox\" name=\"forcerecreate\">" . $xestiascan_lang{$language_selected}{forcerecreatetables}, "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{deleteinstallscripts}, "tablename", "<input type=\"checkbox\" name=\"deleteinstall\" checked>" . $xestiascan_lang{$language_selected}{removeinstallscript} . "<br /><input type=\"checkbox\" name=\"deleteinstallmultiuser\" checked>" . $xestiascan_lang{$language_selected}{removemultiuserinstallscript} . "<br /><br /><b>" . $xestiascan_lang{$language_selected}{warningmessage} . $xestiascan_lang{$language_selected}{recommendremoving} . "</b>", "tabledata");
+
+print "</table>\n";
+
+print "<input type=\"submit\" value=\"Create tables\"> | <input type=\"reset\" value=\"Reset settings\">";
+
+print "</form></div>";
+
+print "</body></html>";
+
+__END__
\ No newline at end of file
diff --git a/cgi-files/install.cgi b/cgi-files/install.cgi
new file mode 100755 (executable)
index 0000000..5ecf3ed
--- /dev/null
@@ -0,0 +1,2398 @@
+#!/usr/bin/perl -Tw
+
+#################################################################################
+# Xestia Scanner Server Installer Script (install.cgi)                         #
+# Installation script for Xestia Scanner Server                                        #
+#                                                                              #
+# Version: 0.1.0                                                               #
+#                                                                              #
+# Copyright (C) 2005-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This module is licensed under the same license as Xestia Scanner Server which #
+# is licensed under the GPL version 3.                                         #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+################################################################################# 
+
+# TODO: ADD SCANNED IMAGES (FS & URI LOCATIONS) TO THE INSTALLED!!!
+
+use strict;                            # Throw errors if there's something wrong.
+use warnings;                          # Write warnings to the HTTP Server Log file.
+
+use Cwd qw(abs_path cwd);
+
+use utf8;
+
+eval "use CGI::Lite";
+
+if ($@){
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+       print "The CGI::Lite Perl Module is not installed. Please install CGI::Lite and then run this installation script again. CGI::Lite can be installed through CPAN.";
+       exit;
+}
+
+eval "use Tie::IxHash";
+
+if ($@){
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+       print "The Tie::IxHash Perl Module is not installed. Please install Tie::IxHash and then run this installation script again. Tie::IxHash can be installed through CPAN.";
+       exit;
+}
+
+# Check if mod_perl is running and if it is then add a notice to say
+# that additional configuration has to be made.
+
+my $modperlenabled = 0;
+my $installscriptname = "install.cgi";
+my $multiuserinstallscriptname = "install-multiuser.cgi";
+my $xestiascanscriptname = "xsdss.cgi";
+
+#if ($ENV{'MOD_PERL'}){
+
+       # MOD_PERL 2.X SPECIFIC SECTION.
+
+#      use lib '';
+#      chdir('');
+
+#      $modperlenabled         = 1;
+#      $installscriptname      = "install.pl";
+#      $xestiascanscriptname   = "kiriwrite.pl";
+
+#}
+
+# Setup strings in specific languages. Style should be no spacing for
+# language title and one tabbed spacing for each string.
+
+# Define some default settings.
+
+my $default_language           = "en-GB";
+my $default_imagesuri          = "/images/xestiascan";
+my $default_scansuri           = "/images/xestiascan/scans";
+
+my $default_scansfs            = abs_path("..") . "/images/xestiascan/scans";
+
+my $default_outputmodule       = "Normal";
+
+my $default_server             = "localhost";
+my $default_port               = "5432";
+my $default_protocol           = "tcp";
+my $default_name               = "database";
+my $default_username           = "username";
+my $default_prefix             = "xestiascan";
+
+my ($xestiascan_lang, %xestiascan_lang);
+
+$xestiascan_lang{"en-GB"}{"languagename"}      = "English (British)";
+       $xestiascan_lang{"en-GB"}{"testpass"}           = "OK";
+       $xestiascan_lang{"en-GB"}{"testfail"}           = "Error";
+
+       $xestiascan_lang{"en-GB"}{"generic"}                    = "An error occured which is not known to the Xestia Scanner Server installer.";
+       $xestiascan_lang{"en-GB"}{"invalidvariable"}            = "The variable given was invalid.";
+       $xestiascan_lang{"en-GB"}{"invalidvalue"}               = "The value given was invalid.";
+       $xestiascan_lang{"en-GB"}{"invalidoption"}              = "The option given was invalid.";
+       $xestiascan_lang{"en-GB"}{"variabletoolong"}            = "The variable given is too long.";
+       $xestiascan_lang{"en-GB"}{"blankdirectory"}             = "The directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"invaliddirectory"}           = "The directory name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"moduleblank"}                        = "The module filename given is blank.";
+       $xestiascan_lang{"en-GB"}{"moduleinvalid"}              = "The module filename given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"authdirectorytoolong"}       = "The authentication directory name given is too long.";
+       $xestiascan_lang{"en-GB"}{"outputdirectorytoolong"}     = "The output directory name given is too long.";
+       $xestiascan_lang{"en-GB"}{"imagesuripathtoolong"}       = "The images URI path name given is too long.";
+       $xestiascan_lang{"en-GB"}{"scansuripathtoolong"}        = "The scans URI path name given is too long.";
+       $xestiascan_lang{"en-GB"}{"scansfspathtoolong"}         = "The scans filesystem path name given is too long.";
+       $xestiascan_lang{"en-GB"}{"dateformattoolong"}          = "The date format given is too long.";
+       $xestiascan_lang{"en-GB"}{"customdateformattoolong"}    = "The custom date format given is too long.";
+       $xestiascan_lang{"en-GB"}{"languagefilenametoolong"}    = "The language filename given is too long.";
+
+       $xestiascan_lang{"en-GB"}{"dateformatblank"}            = "The date format given was blank.";
+       $xestiascan_lang{"en-GB"}{"dateformatinvalid"}          = "The date format given is invalid.";
+       $xestiascan_lang{"en-GB"}{"languagefilenameinvalid"}    = "The language filename given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"authdirectoryblank"}         = "The authentication directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"authdirectoryinvalid"}       = "The authentication directory name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"outputdirectoryblank"}       = "The output directory name given is blank.";
+       $xestiascan_lang{"en-GB"}{"outputdirectoryinvalid"}     = "The output directory name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"textarearowblank"}           = "The text area row value given is blank.";
+       $xestiascan_lang{"en-GB"}{"textarearowtoolong"}         = "The text area row value given is too long.";
+       $xestiascan_lang{"en-GB"}{"textarearowinvalid"}         = "The text area row value given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"textareacolsblank"}          = "The text area columns value given is blank.";
+       $xestiascan_lang{"en-GB"}{"textareacolstoolong"}                = "The text area columns value given is too long.";
+       $xestiascan_lang{"en-GB"}{"textareacolsinvalid"}                = "The text area columns value given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"presmoduleblank"}            = "The presentation module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"presmoduleinvalid"}          = "The presentation module name given is invalid.";
+
+       $xestiascan_lang{"en-GB"}{"authmoduleblank"}            = "The authentication module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"authmoduleinvalid"}          = "The authentication module name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"outputmoduleblank"}          = "The output module name given is blank.";
+       $xestiascan_lang{"en-GB"}{"outputmoduleinvalid"}        = "The output module name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"presmodulemissing"}          = "The presentation module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"outputmodulemissing"}                = "The output module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"authmodulemissing"}          = "The authentication module with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"languagefilenamemissing"}    = "The language file with the filename given is missing.";
+       $xestiascan_lang{"en-GB"}{"servernametoolong"}          = "The database server name given is too long.";
+       $xestiascan_lang{"en-GB"}{"servernameinvalid"}          = "The database server name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverportnumbertoolong"}    = "The database server port number given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverportnumberinvalidcharacters"}  = "The database server port number given contains invalid characters.";
+       $xestiascan_lang{"en-GB"}{"serverportnumberinvalid"}    = "The database server port number given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverprotocolnametoolong"}  = "The database server protocol name given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverprotocolinvalid"}              = "The database server protocol name is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasenametoolong"}  = "The database name given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasenameinvalid"}  = "The database name given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabaseusernametoolong"}      = "The database server username given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabaseusernameinvalid"}      = "The database server username given is invalid.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasepasswordtoolong"}      = "The database server password is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasetableprefixtoolong"}   = "The database server table prefix given is too long.";
+       $xestiascan_lang{"en-GB"}{"serverdatabasetableprefixinvalid"}   = "The database server table prefix given is invalid.";
+       $xestiascan_lang{"en-GB"}{"removeinstallscripttoolong"} = "The remove installer script value given is too long.";
+       $xestiascan_lang{"en-GB"}{"removemultiuserinstallscripttoolong"}        = "The remove multiuser installer script value given is too long.";
+       $xestiascan_lang{"en-GB"}{"cannotwriteconfigurationindirectory"}        = "The configuration file cannot be written because the directory the install script is running from has invalid permissions.";
+       $xestiascan_lang{"en-GB"}{"configurationfilereadpermissionsinvalid"}    = "The configuration that currently exists has invalid read permissions set.";
+       $xestiascan_lang{"en-GB"}{"configurationfilewritepermissionsinvalid"}   = "The configuration that currently exists has invalid write permissions set.";
+
+       $xestiascan_lang{"en-GB"}{"errormessagetext"}   = "Please press the back button on your browser or preform the command needed to return to the previous page.";
+
+       $xestiascan_lang{"en-GB"}{"switch"}             = "Switch";
+       $xestiascan_lang{"en-GB"}{"setting"}            = "Setting";
+       $xestiascan_lang{"en-GB"}{"value"}              = "Value";
+       $xestiascan_lang{"en-GB"}{"filename"}           = "Filename";
+       $xestiascan_lang{"en-GB"}{"module"}             = "Module";
+       $xestiascan_lang{"en-GB"}{"result"}             = "Result";
+       $xestiascan_lang{"en-GB"}{"requiredver"}        = "Required Version";
+       $xestiascan_lang{"en-GB"}{"installedver"}       = "Installed Version";
+       $xestiascan_lang{"en-GB"}{"error"}              = "Error!";
+       $xestiascan_lang{"en-GB"}{"criticalerror"}      = "Critical Error!";
+       $xestiascan_lang{"en-GB"}{"errormessage"}       = "Error: ";
+       $xestiascan_lang{"en-GB"}{"warningmessage"}     = "Warning: ";
+
+       $xestiascan_lang{"en-GB"}{"doesnotexist"}       = "Does not exist.";
+       $xestiascan_lang{"en-GB"}{"invalidpermissionsset"}      = "Invalid permissions set.";
+
+       $xestiascan_lang{"en-GB"}{"dependencyperlmodulesmissing"}       = "One or more Perl modules that are needed by Xestia Scanner Server are not installed or has problems. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"databaseperlmodulesmissing"} = "One or more Perl modules that are needed by the Xestia Scanner Server database modules are not installed or has problems. See the Xestia Scanner Server documentation for more information on this. There should however, be no problems with the database modules which use the Perl modules that have been found.";
+       $xestiascan_lang{"en-GB"}{"filepermissionsinvalid"}     = "One or more of the filenames checked does not exist or has invalid permissions set. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"dependencymodulesnotinstalled"}      = "One of the required Perl modules is not installed or has errors. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"databasemodulesnotinstalled"}        = "None of Perl modules that are used by the authentication modules are not installed. See the Xestia Scanner Server documentation for more information on this.";
+       $xestiascan_lang{"en-GB"}{"filepermissionerrors"}       = "One or more filenames checked has errors. See the Xestia Scanner Server documentation for more information on this.",
+
+       $xestiascan_lang{"en-GB"}{"installertitle"}     = "Xestia Scanner Server Installer";
+       $xestiascan_lang{"en-GB"}{"installertext"}      = "This installer script will setup the configuration file used for Xestia Scanner Server. The settings displayed here can be changed at a later date by selecting the Edit Settings link in the View Settings sub-menu.";
+       $xestiascan_lang{"en-GB"}{"modperlnotice"}      = "mod_perl has been detected. Please ensure that you have setup this script and the main Xestia Scanner Server script so that mod_perl can use Xestia Scanner Server properly. Please read the mod_perl specific part of Chapter 1: Installation in the Xestia Scanner Server documentation.";
+       $xestiascan_lang{"en-GB"}{"dependencytitle"}    = "Dependency and file testing results";
+       $xestiascan_lang{"en-GB"}{"requiredmodules"}    = "Required Modules";
+       $xestiascan_lang{"en-GB"}{"perlmodules"}        = "These Perl modules are used by Xestia Scanner Server and can be downloaded from CPAN if they are missing. Please check and compare the required and installed versions as installed modules that do not meet the required version may cause Xestia Scanner Server to not work properly.";
+       $xestiascan_lang{"en-GB"}{"databasemodules"}    = "Perl Database Modules";
+       $xestiascan_lang{"en-GB"}{"databasemodulestext"}= "These Perl modules are used by the authentication modules.";
+       $xestiascan_lang{"en-GB"}{"filepermissions"}    = "File permissions";
+       $xestiascan_lang{"en-GB"}{"filepermissionstext"}        = "The file permissions are for file and directories that are critical to Xestia Scanner Server such as module and language directories.";
+       
+       $xestiascan_lang{"en-GB"}{"settingstitle"}      = "Xestia Scanner Server Settings";
+       $xestiascan_lang{"en-GB"}{"settingstext"}       = "The settings given here will be used by Xestia Scanner Server. Some default settings are given here. Certain database modules (like SQLite) do not need the database server settings and can be left alone.";
+       $xestiascan_lang{"en-GB"}{"directories"}        = "Directories";
+       $xestiascan_lang{"en-GB"}{"databasedirectory"}  = "Database Directory";
+       $xestiascan_lang{"en-GB"}{"outputdirectory"}    = "Output Directory";
+       $xestiascan_lang{"en-GB"}{"imagesuripath"}      = "Images (URI path)";
+       $xestiascan_lang{"en-GB"}{"scansuripath"}       = "Scans (URI path)";
+       $xestiascan_lang{"en-GB"}{"scansfspath"}        = "Scans (Filesystem path)";
+       $xestiascan_lang{"en-GB"}{"display"}            = "Display";
+       $xestiascan_lang{"en-GB"}{"textareacols"}       = "Text Area Columns";
+       $xestiascan_lang{"en-GB"}{"textarearows"}       = "Text Area Rows";
+       $xestiascan_lang{"en-GB"}{"date"}               = "Date";
+       $xestiascan_lang{"en-GB"}{"dateformat"}         = "Date Format";
+       $xestiascan_lang{"en-GB"}{"language"}           = "Language";
+       $xestiascan_lang{"en-GB"}{"systemlanguage"}     = "System Language";
+       $xestiascan_lang{"en-GB"}{"modules"}            = "Modules";
+       $xestiascan_lang{"en-GB"}{"presentationmodule"} = "Presentation Module";
+       $xestiascan_lang{"en-GB"}{"outputmodule"}       = "Output Module";
+       $xestiascan_lang{"en-GB"}{"authmodule"}         = "Authentication Module";
+       $xestiascan_lang{"en-GB"}{"databaseserver"}     = "Database Server";
+       $xestiascan_lang{"en-GB"}{"databaseport"}       = "Database Port";
+       $xestiascan_lang{"en-GB"}{"databaseprotocol"}   = "Database Protocol";
+       $xestiascan_lang{"en-GB"}{"databasename"}       = "Database Name";
+       $xestiascan_lang{"en-GB"}{"databaseusername"}   = "Database Username";
+       $xestiascan_lang{"en-GB"}{"databasepassword"}   = "Database Password";
+       $xestiascan_lang{"en-GB"}{"databasetableprefix"}        = "Database Table Prefix";
+       $xestiascan_lang{"en-GB"}{"installationoptions"}        = "Installation Options";
+       $xestiascan_lang{"en-GB"}{"installoptions"}     = "Install Options";
+       $xestiascan_lang{"en-GB"}{"removeinstallscript"}        = "Delete this installer script after configuration file has been written.";
+       $xestiascan_lang{"en-GB"}{"removemultiuserinstallscript"}       = "Delete the multiuser installer script if not needed.";
+       $xestiascan_lang{"en-GB"}{"savesettingsbutton"} = "Save Settings";
+       $xestiascan_lang{"en-GB"}{"resetsettingsbutton"}        = "Reset Settings";
+
+       $xestiascan_lang{"en-GB"}{"installscriptremoved"}       = "The installer script was removed.";
+       $xestiascan_lang{"en-GB"}{"installedmessage"}   = "The configuration file for Xestia Scanner Server has been written. To change the settings in the configuration file at a later date use the Edit Settings link in the View Settings sub-menu at the top of the page when using Xestia Scanner Server.";
+       $xestiascan_lang{"en-GB"}{"cannotremovescript"} = "Unable to remove the installer script: %s. The installer script will have to be deleted manually.";
+       $xestiascan_lang{"en-GB"}{"cannotremovemultiuserscript"}        = "Unable to remove the multiuser installer script: %s. The installer script will have to be deleted manually.";
+       $xestiascan_lang{"en-GB"}{"usexestiascannerservertext"} = "To use Xestia Scanner Server click or select the link below (will not work if the Xestia Scanner Server script is not called xsdss.cgi):";
+       $xestiascan_lang{"en-GB"}{"usexestiascannerserverlink"} = "Start using Xestia Scanner Server.";
+
+       $xestiascan_lang{"en-GB"}{"multiuserinstall"} = "The authentication module selected requires additional setup. Please click on the multiuser installer link below for more instructions.";
+       $xestiascan_lang{"en-GB"}{"multiuserinstalllink"} = "Start the Multiuser Installer.";
+
+my $query_lite = new CGI::Lite;
+my $form_data = $query_lite->parse_form_data;
+
+my $language_selected = "";
+my $http_query_confirm = $form_data->{'confirm'};
+my $http_query_installlanguage = $form_data->{'installlanguage'};
+
+if (!$http_query_installlanguage){
+
+       $language_selected = $default_language;
+
+} else {
+
+       $language_selected = $http_query_installlanguage;
+
+}
+
+# Process the list of available languages.
+
+my $language_list_name;
+my @language_list_short;
+my @language_list_long;
+
+foreach my $language (keys %xestiascan_lang){
+
+       $language_list_name = $xestiascan_lang{$language}{"languagename"} . " (" . $language .  ")";
+       push(@language_list_short, $language);
+       push(@language_list_long, $language_list_name);
+
+}
+
+# The CSS Stylesheet to use.
+
+my $cssstyle = "
+
+a {
+       color: #FFFFFF;
+}
+
+body {
+       margin: 0px; 
+       font-family: sans-serif; 
+       padding: 0px; 
+       font-size: 13px;
+       background-color: #402040;
+       color: #ffffff;
+       background-image: url('/images/xestiascan/pagebackground.png');
+       background-repeat: repeat-x;
+}
+
+td,table {
+       padding: 5px;
+       border-spacing: 0px;
+}
+
+.languagebar {
+       background-color: #204040;
+       vertical-align: top;
+}
+
+.languagebarselect {
+       text-align: right;
+       background-color: #204040;
+}
+
+.tablecellheader {
+       font-size: 12px;
+       background-color: #703570;      
+       font-weight: bold;
+       text-align: left;
+       background-image: url('/images/xestiascan/tabletop.png');
+       background-repeat: repeat-x;
+}
+
+.tabledata {
+       background-color: #603060;
+}
+
+.topbar {
+       padding: 3px;
+       background-color: #753575;
+       border-bottom-style: solid;
+       border-bottom-width: 1px;
+       border-bottom-color: #EE70EE;
+       text-align: right;
+       min-height: 17px;
+       background-image: url('/images/xestiascan/menutop.png');
+       background-repeat: repeat-x;
+}
+
+.title {
+       font-size: 16px;
+       font-weight: bold;
+       position: absolute;
+       text-align: left;
+       z-index: 0;
+       left: 0;
+       padding-left: 3px;
+}
+
+.pageheader {
+       font-size: 18px;
+       font-weight: bold;
+}
+
+.subheader {
+       font-size: 14px;
+       font-weight: bold;
+}
+
+.tablename {
+
+       background-color: #301530;
+
+}
+
+.pagespacing {
+
+       padding: 3px;
+
+}
+
+";
+
+
+#################################################################################
+# Begin list of subroutines.                                                   #
+#################################################################################
+
+sub xestiascan_variablecheck{
+#################################################################################
+# xestiascan_variablecheck: Check to see if the data passed is valid.          #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_variablecheck(variablename, type, option, noerror);               #
+#                                                                              #
+# variablename Specifies the variable to be checked.                           #
+# type         Specifies what type the variable is.                            #
+# option       Specifies the maximum/minimum length of the variable            #
+#              (if minlength/maxlength is used) or if the filename should be   #
+#              checked to see if it is blank.                                  #
+# noerror      Specifies if Kiriwrite should return an error or not on         #
+#              certain values.                                                 #
+#################################################################################
+
+       # Get the values that were passed to the subroutine.
+
+       my ($variable_data, $variable_type, $variable_option, $variable_noerror) = @_;
+
+       if ($variable_type eq "numbers"){
+
+               # Check for numbers and return an error if there is anything else than numebrs.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated.
+               $variable_data_validated =~ tr/0-9//d;          # Take away all of the numbers and from the variable. 
+                                                               # If it only contains numbers then it should be blank.
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "lettersnumbers"){
+
+               # Check for letters and numbers and return an error if there is anything else other
+               # than letters and numbers.
+
+               my $variable_data_validated = $variable_data;   # Copy the variable_data to variable_data_validated
+               $variable_data_validated =~ tr/a-zA-Z0-9.//d;
+               $variable_data_validated =~ s/\s//g;
+
+               if ($variable_data_validated eq ""){
+                       # The validated variable is blank. So continue to the end of this section where the return function should be.
+               } else {
+                       # The variable is not blank, so check if the no error value is set
+                       # to 1 or not.
+
+                       if ($variable_noerror eq 1){
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 1. So return an value of 1.
+                               # (meaning that the data is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # The validated variable is not blank and the noerror
+                               # value is set to 0.
+
+                               xestiascan_error("invalidvariable");
+
+                       } else {
+
+                               # The variable noerror value is something else
+                               # pther than 1 or 0. So return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "maxlength"){
+               # Check for the length of the variable, return an error if it is longer than the length specified.
+
+               # Check if the variable_data string is blank, if it is then set the variable_data_length
+               # to '0'.
+
+               my $variable_data_length = 0;
+
+               if (!$variable_data){
+
+                       # Set variable_data_length to '0'.
+                       $variable_data_length = 0;
+
+               } else {
+
+                       # Get the length of the variable recieved.
+                       $variable_data_length = length($variable_data);
+
+               }
+
+
+
+               if ($variable_data_length > $variable_option){
+
+                       # The variable length is longer than it should be so check if
+                       # the no error value is set 1.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1, so return an
+                               # value of 1 (meaning tha the variable is
+                               # too long to be used).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0, so return
+                               # an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("variabletoolong");
+
+                       }
+
+               } else {
+
+                       # The variable length is exactly or shorter than specified, so continue to end of this section where
+                       # the return function should be.
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "datetime"){
+               # Check if the date and time setting format is valid.
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the date and
+                               # time format was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("dateformatblank");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr|dDmMyYhms/():[ ]||d;
+
+               if ($variable_data_validated eq ""){
+
+                       # The date and time format is valid. So
+                       # skip this bit.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the date and
+                               # time format was invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("dateformatinvalid");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "directory"){
+               # Check if the directory only contains letters and numbers and
+               # return an error if anything else appears.
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data eq ""){
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # a value of 1 (meaning that the directory
+                               # name was blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 1 so return
+                               # an error.
+
+                               xestiascan_error("blankdirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1, so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               if ($variable_data_validated eq ""){
+
+                       # The validated data variable is blank, meaning that
+                       # it only contains letters and numbers.
+
+               } else {
+
+                       # The validated data variable is not blank, meaning 
+                       # that it contains something else, so return an error
+                       # (or a value).
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value is set to 1 so return
+                               # an value of 2. (meaning that the directory
+                               # name is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value is set to 0 so return
+                               # an error.
+
+                               xestiascan_error("invaliddirectory");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "language_filename"){
+
+               # The variable type is a language filename type.
+               # Check if the language file name is blank and 
+               # if it is then return an error (or value).
+
+               if ($variable_data eq ""){
+
+                       # The language filename is blank so check the
+                       # no error value and return an error (or value).
+
+                       if ($variable_noerror eq 1){
+
+                               # Language filename is blank and the no error value
+                               # is set as 1, so return a value of 1 (saying that
+                               # the language filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Language filename is blank and the no error value
+                               # is not set as 1, so return an error.
+
+                               xestiascan_error("languagefilenameblank");
+
+                       } else {
+
+                               # The noerror value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvariable");
+
+                       }
+
+               }
+
+               # Set the following variables for later on.
+
+               my $variable_data_length = 0;
+               my $variable_data_char = "";
+               my $variable_data_seek = 0;
+
+               # Get the length of the language file name.
+
+               $variable_data_length = length($variable_data);
+
+               do {
+
+                       # Get a character from the language filename passed to this 
+                       # subroutine and the character the seek counter value is set
+                       # to.
+
+                       $variable_data_char = substr($variable_data, $variable_data_seek, 1);
+
+                       # Check if the language filename contains a forward slash or a dot, 
+                       # if the selected character is a forward slash then return an error
+                       # (or value).
+
+                       if ($variable_data_char eq "/" || $variable_data_char eq "."){
+
+                               # The language filename contains a forward slash or
+                               # a dot so depending on the no error value, return
+                               # an error or a value.
+
+                               if ($variable_noerror eq 1){
+
+                                       # Language filename contains a forward slash or a dot
+                                       # and the no error value has been set to 1, so return 
+                                       # an value of 2 (saying that the language file name is 
+                                       # invalid).
+
+                                       return 2;
+
+                               } elsif ($variable_noerror eq 0) {
+
+                                       # Language filename contains a forward slash and the no
+                                       # error value has not been set to 1, so return an error.
+
+                                       xestiascan_error("languagefilenameinvalid");
+
+                               } else {
+
+                                       # The noerror value is something else other than
+                                       # 1 or 0 so return an error.
+
+                                       xestiascan_error("invalidvariable");
+
+                               }
+
+                       }
+
+                       # Increment the seek counter.
+
+                       $variable_data_seek++;
+
+               } until ($variable_data_seek eq $variable_data_length);
+
+               return 0;
+
+       } elsif ($variable_type eq "module"){
+
+               # The variable type is a presentation module filename.
+
+               # Check if the variable_data is blank and if it is
+               # return an error.
+
+               if ($variable_data eq ""){
+
+                       # The presentation module is blank so check if an error
+                       # value should be returned or a number should be
+                       # returned.
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name is blank and the no error value 
+                               # is set to 1 so return a value of 2 (meaning 
+                               # that the page filename is blank).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains is blank and the no error 
+                               # value is set to 0 so return an error.
+
+                               xestiascan_critical("moduleblank");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_critical("invalidvalue");
+
+                       }
+
+               } else {
+
+               }
+
+               my $variable_data_validated = $variable_data;
+               $variable_data_validated =~ tr/a-zA-Z0-9//d;
+
+               if ($variable_data_validated eq ""){
+
+               } else {
+
+                       if ($variable_noerror eq 1){
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 1 so return a 
+                               # value of 2 (meaning that the page filename
+                               # is invalid).
+
+                               return 2;
+
+                       } elsif ($variable_noerror eq 0) {
+
+                               # Module name contains invalid characters and
+                               # the no error value is set to 0 so return an
+                               # error.
+
+                               xestiascan_critical("moduleinvalid");
+
+                       } else {
+
+                               # The no error value is something else other
+                               # than 0 or 1 so return an error.
+
+                               xestiascan_error("invalidvalue");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "serverprotocol"){
+
+               # Check if the server protocol is TCP or UDP and return
+               # an error if it isn't.
+
+               if ($variable_data ne "tcp" && $variable_data ne "udp"){
+
+                       # The protocol given is not valid, check if the no
+                       # error value is set to 1 and return an error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the server protocol is
+                               # invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverprotocolinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       } elsif ($variable_type eq "port"){
+
+               # Check if the port number given is less than 0 or more than 65535
+               # and return an error if it is.
+
+               if ($variable_data < 0 || $variable_data > 65535){
+
+                       # The port number is less than 0 and more than 65535 so
+                       # check if the no error value is set to 1 and return an
+                       # error if it isn't.
+
+                       if ($variable_noerror eq 1){
+
+                               # The no error value has been set to 1, so return a
+                               # value of 1 (meaning that the port number is invalid).
+
+                               return 1;
+
+                       } elsif ($variable_noerror eq 0){
+
+                               # The no error value has been set to 0, so return
+                               # an error.
+
+                               xestiascan_error("serverportnumberinvalid");
+
+                       } else {
+
+                               # The no error value is something else other than 0
+                               # or 1, so return an error.
+
+                               xestiascan_error("invalidoption");
+
+                       }
+
+               }
+
+               return 0;
+
+       }
+
+       # Another type than the valid ones above has been specified so return an error specifying an invalid option.
+       xestiascan_error("invalidoption");
+
+}
+
+sub xestiascan_error{
+#################################################################################
+# xestiascan_error: Subroutine for processing error messages.                  #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_error(errortype);                                                 #
+#                                                                              #
+# errortype    Specifies the error type to use.                                #
+#################################################################################
+
+       my $error_type = shift;
+
+       # Load the list of error messages.
+
+       my (%xestiascan_error, $xestiascan_error);
+
+       %xestiascan_error = (
+
+               # Generic Error Messages
+
+               "generic"                       => $xestiascan_lang{$language_selected}{generic},
+
+               "invalidvariable"               => $xestiascan_lang{$language_selected}{invalidvariable},
+               "invalidvalue"                  => $xestiascan_lang{$language_selected}{invalidvalue},
+               "invalidoption"                 => $xestiascan_lang{$language_selected}{invalidoption},
+               "variabletoolong"               => $xestiascan_lang{$language_selected}{variabletoolong},
+               "blankdirectory"                => $xestiascan_lang{$language_selected}{blankdirectory},
+               "invaliddirectory"              => $xestiascan_lang{$language_selected}{invaliddirectory},
+               "moduleblank"                   => $xestiascan_lang{$language_selected}{moduleblank},
+               "moduleinvalid"                 => $xestiascan_lang{$language_selected}{moduleinvalid},
+
+               # Specific Error Messages
+
+               "authdirectorytoolong"          => $xestiascan_lang{$language_selected}{dbdirectorytoolong},
+               "outputdirectorytoolong"        => $xestiascan_lang{$language_selected}{outputdirectorytoolong},
+               "imagesuripathtoolong"          => $xestiascan_lang{$language_selected}{imagesuripathtoolong},
+               "dateformattoolong"             => $xestiascan_lang{$language_selected}{dateformattoolong},
+               "customdateformattoolong"       => $xestiascan_lang{$language_selected}{customdateformattoolong},
+               "languagefilenametoolong"       => $xestiascan_lang{$language_selected}{languagefilenametoolong},
+               
+               "dateformatblank"               => $xestiascan_lang{$language_selected}{dateformatblank},
+               "dateformatinvalid"             => $xestiascan_lang{$language_selected}{dateformatinvalid},
+               "languagefilenameinvalid"       => $xestiascan_lang{$language_selected}{languagefilenameinvalid},
+               
+               "dbdirectoryblank"              => $xestiascan_lang{$language_selected}{dbdirectoryblank},
+               "dbdirectoryinvalid"            => $xestiascan_lang{$language_selected}{dbdirectoryinvalid},
+
+               "textarearowblank"              => $xestiascan_lang{$language_selected}{textarearowblank},
+               "textarearowtoolong"            => $xestiascan_lang{$language_selected}{textarearowtoolong},
+               "textarearowinvalid"            => $xestiascan_lang{$language_selected}{textarearowinvalid},
+
+               "textareacolsblank"             => $xestiascan_lang{$language_selected}{textareacolsblank},
+               "textareacolstoolong"           => $xestiascan_lang{$language_selected}{textareacolstoolong},
+               "textareacolsinvalid"           => $xestiascan_lang{$language_selected}{textareacolsinvalid},
+
+               "outputdirectoryblank"          => $xestiascan_lang{$language_selected}{outputdirectoryblank},
+               "outputdirectoryinvalid"        => $xestiascan_lang{$language_selected}{outputdirectoryinvalid},
+
+               "presmoduleblank"               => $xestiascan_lang{$language_selected}{presmoduleblank},
+               "presmoduleinvalid"             => $xestiascan_lang{$language_selected}{presmoduleinvalid},
+
+               "authmoduleblank"               => $xestiascan_lang{$language_selected}{authmoduleblank},
+               "authmoduleinvalid"             => $xestiascan_lang{$language_selected}{authmoduleinvalid},
+
+               "presmodulemissing"             => $xestiascan_lang{$language_selected}{presmodulemissing},
+               "authmodulemissing"             => $xestiascan_lang{$language_selected}{authmodulemissing},
+               "languagefilenamemissing"       => $xestiascan_lang{$language_selected}{languagefilenamemissing},
+
+               "servernametoolong"             => $xestiascan_lang{$language_selected}{servernametoolong},
+               "servernameinvalid"             => $xestiascan_lang{$language_selected}{servernameinvalid},
+               "serverportnumbertoolong"       => $xestiascan_lang{$language_selected}{serverportnumbertoolong},
+               "serverportnumberinvalidcharacters"     => $xestiascan_lang{$language_selected}{serverportnumberinvalidcharacters},
+               "serverportnumberinvalid"       => $xestiascan_lang{$language_selected}{serverportnumberinvalid},
+               "serverprotocolnametoolong"     => $xestiascan_lang{$language_selected}{serverprotocolnametoolong},
+               "serverprotocolinvalid"         => $xestiascan_lang{$language_selected}{serverprotocolinvalid},
+               "serverdatabasenametoolong"     => $xestiascan_lang{$language_selected}{serverdatabasenametoolong},
+               "serverdatabasenameinvalid"     => $xestiascan_lang{$language_selected}{serverdatabasenameinvalid},
+               "serverdatabaseusernametoolong" => $xestiascan_lang{$language_selected}{serverdatabaseusernametoolong},
+               "serverdatabaseusernameinvalid" => $xestiascan_lang{$language_selected}{serverdatabaseusernameinvalid},
+               "serverdatabasepasswordtoolong" => $xestiascan_lang{$language_selected}{serverdatabasepasswordtoolong},
+               "serverdatabasetableprefixtoolong"      => $xestiascan_lang{$language_selected}{serverdatabasetableprefixtoolong},
+               "serverdatabasetableprefixinvalid"      => $xestiascan_lang{$language_selected}{serverdatabasetableprefixinvalid},
+
+               "removeinstallscripttoolong"    => $xestiascan_lang{$language_selected}{removeinstallscripttoolong},
+               "cannotwriteconfigurationindirectory"   => $xestiascan_lang{$language_selected}{cannotwriteconfigurationindirectory},
+               "configurationfilereadpermissionsinvalid"       => $xestiascan_lang{$language_selected}{configurationfilereadpermissionsinvalid},
+               "configurationfilewritepermissionsinvalid"      => $xestiascan_lang{$language_selected}{configurationfilewritepermissionsinvalid},
+
+       );
+
+       # Check if the specified error is blank and if it is
+       # use the generic error messsage.
+
+       if (!$xestiascan_error{$error_type}){
+               $error_type = "generic";
+       }
+
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+
+       print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+       print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>\n";
+
+       print "<h2>$xestiascan_lang{$language_selected}{error}</h2>";
+
+       print $xestiascan_error{$error_type};
+       print "<br />\n";
+       print $xestiascan_lang{$language_selected}{errormessagetext};
+
+       print "</body>\n</html>";
+
+       exit;
+
+}
+
+sub xestiascan_writeconfig{
+#################################################################################
+# xestiascan_writeconfig: Writes a configuration file.                         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_writeconfig();                                                    #
+#################################################################################
+
+       my ($passedsettings) = @_;
+
+       # Open the configuration file for writing.
+
+       open (my $configfile, "> " . "xsdss.cfg");
+
+       print $configfile "[config]
+directory_noncgi_images = $passedsettings->{ImagesURIPath}
+directory_noncgi_scans = $passedsettings->{ScansURIPath}
+directory_fs_scans = $passedsettings->{ScansFSPath}
+
+system_language = $passedsettings->{Language}
+system_presmodule = $passedsettings->{PresentationModule}
+system_outputmodule = $passedsettings->{OutputModule}
+system_authmodule = $passedsettings->{AuthModule}
+system_datetime = $passedsettings->{DateFormat}
+               
+database_server = $passedsettings->{DatabaseServer}
+database_port = $passedsettings->{DatabasePort}
+database_protocol = $passedsettings->{DatabaseProtocol}
+database_sqldatabase = $passedsettings->{DatabaseName}
+database_username = $passedsettings->{DatabaseUsername}
+database_password = $passedsettings->{DatabasePassword}
+database_tableprefix = $passedsettings->{DatabaseTablePrefix}
+       ";
+
+       close ($configfile);
+       
+       # Set the correct permissions for the file.
+       
+       chmod (0660, "xsdss.cfg");
+
+}
+
+sub xestiascan_addtablerow{
+#################################################################################
+# xestiascan_addtablerow: Adds a table row.                                    #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_addtablerow(name, data);                                          #
+#                                                                              #
+# name         Specifies the name of the table row.                            #
+# namestyle    Specifies the style for the name of the table row.              #
+# data         Specifies the data to be used in the table row.                 #
+# datastyle    Specifies the style for the data of the table row.              #
+#################################################################################
+
+       #my ($name, $namestyle, $data, $datastyle) = @_;
+
+       my $tablecell;
+
+       print "<tr>\n";
+       
+       my $data;
+       my $datastyle;
+       
+       while (@_){
+
+               $data           = shift @_;
+               $datastyle      = shift @_;
+               
+               if (!$data){
+                       
+                       $data = "";
+                       
+               }
+
+               if (!$datastyle){
+                       
+                       $datastyle = "";
+                       
+               }
+               
+               print "<td class=\"$datastyle\">$data</td>\n";
+
+               $data = "";
+               $datastyle = "";
+               
+               
+       }       
+
+       print "</tr>\n";
+       
+       #print "<tr>\n";
+       #print "<td class=\"$namestyle\">$name</td>\n";
+       #print "<td class=\"$datastyle\">$data</td>\n";
+       #print "</tr>\n";
+
+}
+
+sub xestiascan_processconfig{
+#################################################################################
+# xestiascan_processconfig: Processes an INI style configuration file.         #
+#                                                                              #
+# Usage:                                                                       #
+#                                                                              #
+# xestiascan_processconfig(data);                                              #
+#                                                                              #
+# data Specifies the data to process.                                          #
+#################################################################################
+
+       my (@settings) = @_;
+
+       my ($settings_line, %settings, $settings, $sectionname, $setting_name, $setting_value);
+
+       foreach $settings_line (@settings){
+
+               next if !$settings_line;
+
+               # Check if the first character is a bracket.
+
+               if (substr($settings_line, 0, 1) eq "["){
+                       $settings_line =~ s/\[//;
+                       $settings_line =~ s/\](.*)//;
+                       $settings_line =~ s/\n//;
+                       $sectionname = $settings_line;
+                       next;
+               }
+
+               $setting_name  = $settings_line;
+               $setting_value = $settings_line;
+               $setting_name  =~ s/\=(.*)//;
+               $setting_name  =~ s/\n//;
+               $setting_value =~ s/(.*)\=//;
+               $setting_value =~ s/\n//;
+
+               # Remove the spacing before and after the '=' sign.
+
+               $setting_name =~ s/\s+$//;
+               $setting_value =~ s/^\s+//;
+               $setting_value =~ s/\r//;
+
+               $settings{$sectionname}{$setting_name} = $setting_value;
+
+       }
+
+       return %settings;
+
+}
+
+#################################################################################
+# End list of subroutines.                                                     #
+#################################################################################
+
+if (!$http_query_confirm){
+
+       $http_query_confirm = 0;
+
+}
+
+if ($http_query_confirm eq 1){
+
+       # The confirm value has been given so get the data from the query.
+
+       my $http_query_imagesuripath            = $form_data->{'imagesuripath'};
+       my $http_query_scansuripath             = $form_data->{'scansuripath'};
+       my $http_query_scansfspath              = $form_data->{'scansfspath'};
+
+       my $http_query_dateformat               = $form_data->{'dateformat'};
+       my $http_query_customdateformat         = $form_data->{'customdateformat'};
+
+       my $http_query_language                 = $form_data->{'language'};
+
+       my $http_query_presmodule               = $form_data->{'presmodule'};
+       my $http_query_outputmodule             = $form_data->{'outputmodule'};
+       my $http_query_authmodule               = $form_data->{'authmodule'};
+
+       my $http_query_databaseserver           = $form_data->{'databaseserver'};
+       my $http_query_databaseport             = $form_data->{'databaseport'};
+       my $http_query_databaseprotocol         = $form_data->{'databaseprotocol'};
+       my $http_query_databasename             = $form_data->{'databasename'};
+       my $http_query_databaseusername         = $form_data->{'databaseusername'};
+       my $http_query_databasepassword         = $form_data->{'databasepassword'};
+       my $http_query_databasetableprefix      = $form_data->{'databasetableprefix'};
+       
+       my $http_query_removeinstallscript      = $form_data->{'removeinstallscript'};
+       my $http_query_removemultiuserinstallscript     = $form_data->{'removemultiuserinstallscript'};
+
+       # Check the length of the variables.
+
+       my $xestiascan_imagesuripath_length_check       = xestiascan_variablecheck($http_query_imagesuripath, "maxlength", 512, 1);
+       my $xestiascan_scansuripath_length_check        = xestiascan_variablecheck($http_query_scansuripath, "maxlength", 512, 1);
+       my $xestiascan_scansfspath_length_check         = xestiascan_variablecheck($http_query_scansfspath, "maxlength", 4096, 1);
+       my $xestiascan_dateformat_length_check          = xestiascan_variablecheck($http_query_dateformat, "maxlength", 32, 1);
+       my $xestiascan_customdateformat_length_check    = xestiascan_variablecheck($http_query_customdateformat, "maxlength", 32, 1);
+       my $xestiascan_language_length_check            = xestiascan_variablecheck($http_query_language, "maxlength", 16, 1);
+
+       # Check if any errors occured while checking the
+       # length of the variables.
+
+       if ($xestiascan_imagesuripath_length_check eq 1){
+
+               # The images URI path given is too long
+               # so return an error.
+
+               xestiascan_error("imagesuripathtoolong");
+
+       }
+       
+       if ($xestiascan_scansuripath_length_check eq 1){
+               
+               # The scans URI path given is too long
+               # so return an error.
+               
+               xestiascan_error("scansuripathtoolong");
+               
+       }
+       
+       if ($xestiascan_scansfspath_length_check eq 1){
+               
+               # The scans filesystem path given is too long
+               # so return an error.
+               
+               xestiascan_error("scansfspathtoolong");
+               
+       }
+
+       if ($xestiascan_dateformat_length_check eq 1){
+
+               # The date format given is too long
+               # so return an error.
+
+               xestiascan_error("dateformattoolong");
+
+       }
+
+       if ($xestiascan_customdateformat_length_check eq 1){
+
+               # The date format given is too long
+               # so return an error.
+
+               xestiascan_error("customdateformattoolong");
+
+       }
+
+       if ($xestiascan_language_length_check eq 1){
+
+               # The language filename given is too long
+               # so return an error.
+
+               xestiascan_error("languagefilenametoolong");
+
+       }
+
+       # Check if the custom date and time setting has anything
+       # set and if it doesn't then use the predefined one set.
+
+       my $finaldateformat = "";
+
+       if ($http_query_customdateformat ne ""){
+
+               $finaldateformat = $http_query_customdateformat;
+
+       } else {
+
+               $finaldateformat = $http_query_dateformat;
+
+       }
+
+       my $xestiascan_datetime_check           = xestiascan_variablecheck($finaldateformat, "datetime", 0, 1);
+
+       if ($xestiascan_datetime_check eq 1){
+
+               # The date and time format is blank so return
+               # an error.
+
+               xestiascan_error("dateformatblank");
+
+       } elsif ($xestiascan_datetime_check eq 2){
+
+               # The date and time format is invalid so
+               # return an error.
+
+               xestiascan_error("dateformatinvalid");
+
+       }
+
+       # Check if the language filename given is valid.
+
+       my $xestiascan_language_languagefilename_check = xestiascan_variablecheck($http_query_language, "language_filename", "", 1);
+
+       if ($xestiascan_language_languagefilename_check eq 1) {
+
+               # The language filename given is blank so
+               # return an error.
+
+               xestiascan_error("languagefilenameblank");
+
+       } elsif ($xestiascan_language_languagefilename_check eq 2){
+
+               # The language filename given is invalid so
+               # return an error.
+
+               xestiascan_error("languagefilenameinvalid");
+
+       }
+
+       # Check the module names to see if they're valid.
+
+       my $xestiascan_presmodule_modulename_check      = xestiascan_variablecheck($http_query_presmodule, "module", 0, 1);
+       my $xestiascan_outputmodule_modulename_check    = xestiascan_variablecheck($http_query_outputmodule, "module", 0, 1);
+       my $xestiascan_authmodule_modulename_check              = xestiascan_variablecheck($http_query_authmodule, "module", 0, 1);
+
+       if ($xestiascan_presmodule_modulename_check eq 1){
+
+               # The presentation module name is blank, so return
+               # an error.
+
+               xestiascan_error("presmoduleblank");
+
+       }
+
+       if ($xestiascan_presmodule_modulename_check eq 2){
+
+               # The presentation module name is invalid, so return
+               # an error.
+
+               xestiascan_error("presmoduleinvalid");
+
+       }
+
+       if ($xestiascan_outputmodule_modulename_check eq 1){
+
+               # The output module name is blank, so return
+               # an error.
+
+               xestiascan_error("outputmoduleblank");
+
+       }
+
+       if ($xestiascan_outputmodule_modulename_check eq 2){
+
+               # The output module name is invalid, so return
+               # an error.
+
+               xestiascan_error("outputmoduleinvalid");
+
+       }
+
+       if ($xestiascan_authmodule_modulename_check eq 1){
+
+               # The database module name is blank, so return
+               # an error.
+
+               xestiascan_error("authmoduleblank");
+
+       }
+
+       if ($xestiascan_authmodule_modulename_check eq 2){
+
+               # The database module name is invalid, so return
+               # an error.
+
+               xestiascan_error("authmoduleinvalid");
+
+       }
+
+       # Check if the database module, presentation module,
+       # output module and language file exists.
+
+       if (!-e "Modules/Presentation/" . $http_query_presmodule . ".pm"){
+
+               # The presentation module is missing so return an
+               # error.
+
+               xestiascan_error("presmodulemissing");
+
+       }
+
+       if (!-e "Modules/Output/" . $http_query_outputmodule . ".pm"){
+
+               # The database module is missing so return an
+               # error.
+
+               xestiascan_error("outputmodulemissing");
+
+       }
+
+       if (!-e "Modules/Auth/" . $http_query_authmodule . ".pm"){
+
+               # The database module is missing so return an
+               # error.
+
+               xestiascan_error("authmodulemissing");
+
+       }
+
+       if (!-e "lang/" . $http_query_language . ".lang"){
+
+               # The language file is missing so return an
+               # error.
+
+               xestiascan_error("languagefilenamemissing");
+
+       }
+
+       # Check the database server settings.
+
+       my $xestiascan_databaseserver_length_check              = xestiascan_variablecheck($http_query_databaseserver, "maxlength", 128, 1);
+       my $xestiascan_databaseserver_lettersnumbers_check      = xestiascan_variablecheck($http_query_databaseserver, "lettersnumbers", 0, 1);
+       my $xestiascan_databaseport_length_check                        = xestiascan_variablecheck($http_query_databaseport, "maxlength", 5, 1);
+       my $xestiascan_databaseport_numbers_check               = xestiascan_variablecheck($http_query_databaseport, "numbers", 0, 1);
+       my $xestiascan_databaseport_port_check                  = xestiascan_variablecheck($http_query_databaseport, "port", 0, 1);
+       my $xestiascan_databaseprotocol_length_check            = xestiascan_variablecheck($http_query_databaseprotocol, "maxlength", 5, 1);
+       my $xestiascan_databaseprotocol_protocol_check          = xestiascan_variablecheck($http_query_databaseprotocol, "serverprotocol", 0, 1);
+       my $xestiascan_databasename_length_check                        = xestiascan_variablecheck($http_query_databasename, "maxlength", 32, 1);
+       my $xestiascan_databasename_lettersnumbers_check                = xestiascan_variablecheck($http_query_databasename, "lettersnumbers", 0, 1);
+       my $xestiascan_databaseusername_length_check            = xestiascan_variablecheck($http_query_databaseusername, "maxlength", 16, 1);
+       my $xestiascan_databaseusername_lettersnumbers_check    = xestiascan_variablecheck($http_query_databaseusername, "lettersnumbers", 0, 1);
+       my $xestiascan_databasepassword_length_check            = xestiascan_variablecheck($http_query_databasepassword, "maxlength", 64, 1);
+       my $xestiascan_databasetableprefix_length_check         = xestiascan_variablecheck($http_query_databasetableprefix, "maxlength", 16, 1);
+       my $xestiascan_databasetableprefix_lettersnumbers_check = xestiascan_variablecheck($http_query_databasetableprefix, "lettersnumbers", 0, 1);
+
+       if ($xestiascan_databaseserver_length_check eq 1){
+
+               # The length of the database server name is too long so
+               # return an error.
+
+               xestiascan_error("servernametoolong");
+
+       }
+
+       if ($xestiascan_databaseserver_lettersnumbers_check eq 1){
+
+               # The database server name contains characters other
+               # than letters and numbers, so return an error.
+
+               xestiascan_error("servernameinvalid");
+
+       }
+
+       if ($xestiascan_databaseport_length_check eq 1){
+
+               # The database port number length is too long so return
+               # an error.
+
+               xestiascan_error("serverportnumbertoolong");
+
+       }
+
+       if ($xestiascan_databaseport_numbers_check eq 1){
+
+               # The database port number contains characters other
+               # than numbers so return an error.
+
+               xestiascan_error("serverportnumberinvalidcharacters");
+
+       }
+
+       if ($xestiascan_databaseport_port_check eq 1){
+
+               # The database port number given is invalid so return
+               # an error.
+
+               xestiascan_error("serverportnumberinvalid");
+
+       }
+
+       if ($xestiascan_databaseprotocol_length_check eq 1){
+
+               # The database protocol name given is too long so
+               # return an error.
+
+               xestiascan_error("serverprotocolnametoolong");
+
+       }
+
+       if ($xestiascan_databaseprotocol_protocol_check eq 1){
+
+               # The server protcol given is invalid so return
+               # an error.
+
+               xestiascan_error("serverprotocolinvalid");
+
+       }
+
+       if ($xestiascan_databasename_length_check eq 1){
+
+               # The SQL database name is too long so return
+               # an error.
+
+               xestiascan_error("serverdatabasenametoolong");
+
+       }
+
+       if ($xestiascan_databasename_lettersnumbers_check eq 1){
+
+               # The database name contains invalid characters
+               # so return an error.
+
+               xestiascan_error("serverdatabasenameinvalid");
+
+       }
+
+       if ($xestiascan_databaseusername_length_check eq 1){
+
+               # The database username given is too long so
+               # return an error.
+
+               xestiascan_error("serverdatabaseusernametoolong");
+
+       }
+
+       if ($xestiascan_databaseusername_lettersnumbers_check eq 1){
+
+               # The database username contains invalid characters
+               # so return an error.
+
+               xestiascan_error("serverdatabaseusernameinvalid");
+
+       }
+
+       if ($xestiascan_databasepassword_length_check eq 1){
+
+               # The database password given is too long so return
+               # an error.
+
+               xestiascan_error("serverdatabasepasswordtoolong");
+
+       }
+
+       if ($xestiascan_databasetableprefix_length_check eq 1){
+
+               # The database table prefix given is too long so
+               # return an error.
+
+               xestiascan_error("serverdatabasetableprefixtoolong");
+
+       }
+
+       if ($xestiascan_databasetableprefix_lettersnumbers_check eq 1){
+
+               # The database table prefix given contains invalid
+               # characters so return an error.
+
+               xestiascan_error("serverdatabasetableprefixinvalid");
+
+       }
+
+       # Check the length of value of the checkboxes.
+
+       my $xestiascan_removeinstallscript_length_check = xestiascan_variablecheck($http_query_removeinstallscript, "maxlength", 2, 1);
+
+       if ($xestiascan_removeinstallscript_length_check eq 1){
+
+               # The remove install script value is too long
+               # so return an error.
+
+               xestiascan_error("removeinstallscripttoolong");
+
+       }
+       
+       my $xestiascan_removemultiuserinstallscript_length_check        = xestiascan_variablecheck($http_query_removemultiuserinstallscript, "maxlength", 2, 1);
+       
+       if ($xestiascan_removemultiuserinstallscript_length_check eq 1){
+               
+               # The remove install script value is too long
+               # so return an error.
+               
+               xestiascan_error("removemultiuserinstallscripttoolong");
+               
+       }
+
+       # Check if there is write permissions for the directory.
+
+       if (!-w '.'){
+
+               # No write permissions for the directory the
+               # script is running from so return an error.
+
+               xestiascan_error("cannotwriteconfigurationindirectory");
+
+       }
+
+       # Check if the configuration file already exists.
+
+       if (-e 'xsdss.cfg'){
+
+               # Check if the configuration file has read permissions.
+
+               if (!-r 'xsdss.cfg'){
+
+                       # The configuration file has invalid read permissions
+                       # set so return an error.
+
+                       xestiascan_error("configurationfilereadpermissionsinvalid");
+
+               }
+
+               # Check if the configuration file has write permissions.
+
+               if (!-w 'xsdss.cfg'){
+
+                       # The configuration file has invalid write permissions
+                       # set so return an error.
+
+                       xestiascan_error("configurationfilewritepermissionsinvalid");
+
+               }
+
+       }
+
+       # Include the Modules directory.
+       
+       use lib "Modules/";
+       
+       # Load the authentication module.
+
+       my %capabilities;
+       my $multiuser = 0;
+       my $encodedpassword = "";
+       
+       my $presmodulename = "Auth::" . $http_query_authmodule;
+       ($presmodulename) = $presmodulename =~ m/^(.*)$/g; # CHECK THIS!!
+       eval "use " . $presmodulename;
+       $presmodulename = "Modules::Auth::" . $http_query_authmodule;
+       
+       # Work out if database module is 
+       
+       %capabilities = $presmodulename->capabilities();
+       
+       $multiuser = $capabilities{multiuser};
+       
+       if (!$multiuser){
+       
+               $multiuser = 0;
+               
+       }
+       
+       # Write the new configuration file.
+
+       xestiascan_writeconfig({ ScansURIPath => $http_query_scansuripath, ScansFSPath => $http_query_scansfspath , ImagesURIPath => $http_query_imagesuripath, DateFormat => $finaldateformat, Language => $http_query_language, PresentationModule => $http_query_presmodule, OutputModule => $http_query_outputmodule, AuthModule => $http_query_authmodule, DatabaseServer => $http_query_databaseserver, DatabasePort => $http_query_databaseport, DatabaseProtocol => $http_query_databaseprotocol, DatabaseName => $http_query_databasename, DatabaseUsername => $http_query_databaseusername, DatabasePassword => $http_query_databasepassword, DatabaseTablePrefix => $http_query_databasetableprefix });
+
+       my $installscriptmessage        = "";
+       
+       # Check if the installation script should be deleted.
+
+       if (!$http_query_removeinstallscript){
+
+               $http_query_removeinstallscript = "off";
+
+       }
+       
+       if (!$http_query_removemultiuserinstallscript){
+       
+               $http_query_removemultiuserinstallscript = "off";
+               
+       }
+
+       # Check to see if multiuser is enabled and go to the multiuser script if needed.
+       
+       if ($http_query_removeinstallscript eq "on" && $multiuser eq 0){
+
+               if (unlink($installscriptname)){
+
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{installscriptremoved};
+
+               } else {
+
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{cannotremovescript};
+                       $installscriptmessage =~ s/%s/$!/g;
+
+               }
+
+       }
+       
+       if ($http_query_removemultiuserinstallscript eq "on" && $multiuser eq 0){
+       
+               if (unlink($installscriptname)){
+                       
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{installscriptremoved};
+                       
+               } else {
+                       
+                       $installscriptmessage = $xestiascan_lang{$language_selected}{cannotremovescript};
+                       $installscriptmessage =~ s/%s/$!/g;
+                       
+               }               
+               
+       }
+       
+       if ($multiuser eq 1){
+       
+               $installscriptmessage = $xestiascan_lang{$language_selected}{multiuserinstall};
+               
+       }
+
+       print "Content-type: text/html; charset=utf-8;\r\n\r\n";
+
+       #print start_html({ -title => $xestiascan_lang{$language_selected}{installertitle}, -style => { -code => $cssstyle }});
+       print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+       print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>\n";
+       print "<div class=\"topbar\"><span class=\"title\">Xestia Scanner Server Installer</span></div>";
+       print "<div class=\"pagespacing\">\n";
+       print $xestiascan_lang{$language_selected}{installedmessage};
+
+       if ($installscriptmessage){
+
+               print "<br /><br />\n";
+               print $installscriptmessage;
+
+       }
+
+       print "<br /><br />\n";
+       
+       if ($multiuser eq 0){
+       
+               print $xestiascan_lang{$language_selected}{usexestiascannerservertext};
+               print "<br /><br />\n";
+               print "<a href=\"" . $xestiascanscriptname . "\">$xestiascan_lang{$language_selected}{usexestiascannerserverlink}</a>";
+       
+       } elsif ($multiuser eq 1){
+                       
+               print "<a href=\"" . $multiuserinstallscriptname . "\">$xestiascan_lang{$language_selected}{multiuserinstalllink}</a>";         
+               
+       }
+       
+       print "</div>";
+       print "</body>\n</html>";
+
+       exit;
+
+}
+
+# Create a list of common date and time formats.
+
+my @datetime_formats = ( 
+       'DD/MM/YY (hh:mm:ss)', 'DD/MM/YY hh:mm:ss', 'D/M/Y (hh:mm:ss)',
+       'D/M/Y hh:mm:ss', 'D/M/YY (hh:mm:ss)', 'D/M/YY hh:mm:ss',
+       'DD/MM (hh:mm:ss)', 'D/M (hh:mm:ss)', 'DD/MM hh:mm:ss', 
+       'D/M hh:mm:ss', 'DD/MM hh:mm', 'D/M hh:mm',
+       'DD/MM/YY', 'D/M/Y', 'DD/MM',
+
+       'YY-MM-DD (hh:mm:ss)', 'YY-MM-DD hh:mm:ss', 'Y-M-D (hh:mm:ss)',
+       'Y-M-D hh:mm:ss', 'M-D (hh:mm:ss)', 'M-D hh:mm:ss',
+       'YY-MM-DD', 'MM-DD' 
+);
+
+# Create the list of tests to do.
+
+my %test_list;
+my %dependency_results;
+my %database_results;
+my %file_results;
+
+tie(%test_list, "Tie::IxHash");
+tie(%dependency_results, "Tie::IxHash");
+tie(%database_results, "Tie::IxHash");
+tie(%file_results, "Tie::IxHash");
+
+my $test;
+my $date;
+
+my $dependency_error = 0;
+my $database_onemodule = 0;
+my $database_error = 0;
+my $file_error = 0;
+
+my $module_version;
+
+my $language_name;
+my $language_xml_data;
+my $language_file_friendly;
+
+my $presentation_file_friendly;
+
+# Check to see if the needed Perl modules are installed.
+
+$test_list{CheckDBI}{Name}             = "DBI";
+$test_list{CheckDBI}{Type}             = "dependency";
+$test_list{CheckDBI}{Code}             = "DBI";
+$test_list{CheckDBI}{Version}          = "1.605";
+
+$test_list{CheckCGILite}{Name}         = "CGI::Lite";
+$test_list{CheckCGILite}{Type}         = "dependency";
+$test_list{CheckCGILite}{Code}         = "CGI::Lite";
+$test_list{CheckCGILite}{Version}      = "2.02";
+
+$test_list{Encode}{Name}               = "Encode";
+$test_list{Encode}{Type}               = "dependency";
+$test_list{Encode}{Code}               = "Encode";
+$test_list{Encode}{Version}            = "2.23";
+
+$test_list{HashSearch}{Name}           = "Hash::Search";
+$test_list{HashSearch}{Type}           = "dependency";
+$test_list{HashSearch}{Code}           = "Hash::Search";
+$test_list{HashSearch}{Version}                = "0.03";
+
+$test_list{CheckTieHash}{Name}         = "Tie::IxHash";
+$test_list{CheckTieHash}{Type}                 = "dependency";
+$test_list{CheckTieHash}{Code}                 = "Tie::IxHash";
+$test_list{CheckTieHash}{Version}      = "1.22";
+
+$test_list{CheckMimeBase64}{Name}      = "MIME::Base64";
+$test_list{CheckMimeBase64}{Type}      = "dependency";
+$test_list{CheckMimeBase64}{Code}      = "MIME::Base64";
+$test_list{CheckMimeBase64}{Version}   = "3.13";
+
+$test_list{CheckSane}{Name}            = "Sane";
+$test_list{CheckSane}{Type}            = "dependency";
+$test_list{CheckSane}{Code}            = "Sane";
+$test_list{CheckSane}{Version}         = "0.03";
+
+$test_list{CheckFileCopy}{Name}                = "File::Copy";
+$test_list{CheckFileCopy}{Type}                = "dependency";
+$test_list{CheckFileCopy}{Code}                = "File::Copy";
+$test_list{CheckFileCopy}{Version}     = "2.11";
+
+$test_list{CheckFileBasename}{Name}            = "File::Basename";
+$test_list{CheckFileBasename}{Type}            = "dependency";
+$test_list{CheckFileBasename}{Code}            = "File::Basename";
+$test_list{CheckFileBasename}{Version}         = "2.76";
+
+$test_list{CheckSysHostname}{Name}             = "Sys::Hostname";
+$test_list{CheckSysHostname}{Type}             = "dependency";
+$test_list{CheckSysHostname}{Code}             = "Sys::Hostname";
+$test_list{CheckSysHostname}{Version}          = "1.11";
+
+$test_list{CheckImageMagick}{Name}             = "Image::Magick";
+$test_list{CheckImageMagick}{Type}             = "dependency";
+$test_list{CheckImageMagick}{Code}             = "Image::Magick";
+$test_list{CheckImageMagick}{Version}          = "6.3.7";
+
+$test_list{CheckDigest}{Name}          = "Digest";
+$test_list{CheckDigest}{Type}          = "dependency";
+$test_list{CheckDigest}{Code}          = "Digest";
+$test_list{CheckDigest}{Version}       = "1.15";
+
+$test_list{CheckNetSMTP}{Name}         = "Net::SMTP";
+$test_list{CheckNetSMTP}{Type}         = "dependency";
+$test_list{CheckNetSMTP}{Code}         = "Net::SMTP";
+$test_list{CheckNetSMTP}{Version}      = "2.31";
+
+$test_list{CheckFileMimeInfo}{Name}            = "File::MimeInfo";
+$test_list{CheckFileMimeInfo}{Type}            = "dependency";
+$test_list{CheckFileMimeInfo}{Code}            = "File::MimeInfo";
+$test_list{CheckFileMimeInfo}{Version}         = "0.15";
+
+
+$test_list{DBDPg}{Name}                        = "DBD::Pg";
+$test_list{DBDPg}{Type}                        = "database";
+$test_list{DBDPg}{Code}                        = "DBD::Pg";
+$test_list{DBDPg}{Version}             = "2.17.1";
+
+# Check the file and directory permissions to see if they are correct.
+
+$test_list{MainDirectory}{Name}                = "Xestia Scanner Server Directory (.)";
+$test_list{MainDirectory}{Type}                = "file";
+$test_list{MainDirectory}{Code}                = ".";
+$test_list{MainDirectory}{Writeable}   = "1";
+
+$test_list{LanguageDirectory}{Name}            = "Language Directory (lang)";
+$test_list{LanguageDirectory}{Type}            = "file";
+$test_list{LanguageDirectory}{Code}            = "lang";
+$test_list{LanguageDirectory}{Writeable}       = "0";
+
+$test_list{ModulesDirectory}{Name}             = "Modules Directory (Modules)";
+$test_list{ModulesDirectory}{Type}             = "file";
+$test_list{ModulesDirectory}{Code}             = "Modules";
+$test_list{ModulesDirectory}{Writeable}                = "0";
+
+$test_list{AuthModulesDirectory}{Name}         = "Authentication Modules Directory (Modules/Auth)";
+$test_list{AuthModulesDirectory}{Type}         = "file";
+$test_list{AuthModulesDirectory}{Code}         = "Modules/Auth";
+$test_list{AuthModulesDirectory}{Writeable}    = "0";
+
+$test_list{ExportModulesDirectory}{Name}       = "Export Modules Directory (Modules/Export)";
+$test_list{ExportModulesDirectory}{Type}       = "file";
+$test_list{ExportModulesDirectory}{Code}       = "Modules/Export";
+$test_list{ExportModulesDirectory}{Writeable}  = "0";
+
+$test_list{OutputModulesDirectory}{Name}       = "Output Modules Directory (Modules/Output)";
+$test_list{OutputModulesDirectory}{Type}       = "file";
+$test_list{OutputModulesDirectory}{Code}       = "Modules/Output";
+$test_list{OutputModulesDirectory}{Writeable}  = "0";
+
+$test_list{PresModulesDirectory}{Name}         = "Presentation Modules Directory (Modules/Presentation)";
+$test_list{PresModulesDirectory}{Type}         = "file";
+$test_list{PresModulesDirectory}{Code}         = "Modules/Presentation";
+$test_list{PresModulesDirectory}{Writeable}    = "0";
+
+$test_list{SystemModulesDirectory}{Name}       = "System Modules Directory (Modules/System)";
+$test_list{SystemModulesDirectory}{Type}       = "file";
+$test_list{SystemModulesDirectory}{Code}       = "Modules/System";
+$test_list{SystemModulesDirectory}{Writeable}  = "0";
+
+# Preform those tests.
+
+foreach $test (keys %test_list){
+
+       # Check the type of test.
+
+       $ENV{PATH}='/bin:/usr/bin';
+       
+       if ($test_list{$test}{Type} eq "dependency"){
+               
+               if (eval "require " . $test_list{$test}{Code}){
+                       
+                       # The module exists and is working correctly.
+
+                       $dependency_results{$test_list{$test}{Name}}{result}    = $xestiascan_lang{$language_selected}{testpass};
+                       
+                       # Get the current version of the module (if possible);
+                       
+                       # Launch another copy of Perl, this probably is the only memory efficent way.
+                       
+                       my $command = "perl -M$test_list{$test}{Code} -e \'print \"\$$test_list{$test}{Code}::VERSION\"\'";
+                       my $result = `$command`;
+                       
+                       $dependency_results{$test_list{$test}{Name}}{version}   = $result;
+                       $dependency_results{$test_list{$test}{Name}}{testname}  = $test;
+                       
+               } else {
+
+                       # The module does not exist or has an error.
+
+                       $dependency_error = 1;
+                       $dependency_results{$test_list{$test}{Name}}{result}    = $xestiascan_lang{$language_selected}{testfail} . " ($!)";
+                       $dependency_results{$test_list{$test}{Name}}{version}   = "N/A";
+                       $dependency_results{$test_list{$test}{Name}}{testname}  = $test;
+
+               }
+               
+       } elsif ($test_list{$test}{Type} eq "database"){
+
+               if (eval "require " . $test_list{$test}{Code}){
+
+                       # The module exists and it is working correctly.
+
+                       $database_results{$test_list{$test}{Name}}{result}      = $xestiascan_lang{$language_selected}{testpass};
+                       $database_onemodule = 1;
+                       
+                       # Launch another copy of Perl, this probably is the only memory efficent way.
+                       
+                       my $command = "perl -M$test_list{$test}{Code} -e \'print \"\$$test_list{$test}{Code}::VERSION\"\'";
+                       my $result = `$command`;
+                       
+                       $database_results{$test_list{$test}{Name}}{version}     = $result;
+                       $database_results{$test_list{$test}{Name}}{testname}    = $test;
+
+               } else {
+
+                       # The module does not exist or has an error.
+
+                       $database_error = 1;
+                       $database_results{$test_list{$test}{Name}}{result}      = $xestiascan_lang{$language_selected}{testfail};
+                       $database_results{$test_list{$test}{Name}}{version}     = "N/A";
+                       $database_results{$test_list{$test}{Name}}{testname}    = $test;
+
+               }
+
+       } elsif ($test_list{$test}{Type} eq "file"){
+
+               if (-e $test_list{$test}{Code}){
+
+                       # The filename given does exist.
+
+               } else {
+
+                       # the filename given does not exist.
+
+                       $file_error = 1;
+                       $file_results{$test_list{$test}{Name}}{result}  = $xestiascan_lang{$language_selected}{errormessage} . $xestiascan_lang{$language_selected}{doesnotexist};
+
+               }       
+
+               # Test to see if the filename given has read
+               # permissions.
+
+               if (-r $test_list{$test}{Code}){
+
+                       # The filename given has valid permissions set.
+
+                       $file_results{$test_list{$test}{Name}}{result}  = $xestiascan_lang{$language_selected}{testpass};
+
+               } else {
+
+                       # The filename given has invalid permissions set.
+
+                       $file_error = 1;
+                       $file_results{$test_list{$test}{Name}}{result} = $xestiascan_lang{$language_selected}{errormessage} . $xestiascan_lang{$language_selected}{invalidpermissionsset};
+
+               }
+
+               if ($test_list{$test}{Writeable} eq 1){
+
+                       # Test to see if the filename given has write
+                       # permissions.
+
+                       if (-w $test_list{$test}{Code}){
+
+                               # The filename given has valid permissions set.
+
+                               $file_results{$test_list{$test}{Name}}{result}  = $xestiascan_lang{$language_selected}{testpass};
+
+                       } else {
+
+                               # The filename given has invalid permissions set.
+
+                               $file_error = 1;
+                               $file_results{$test_list{$test}{Name}}{result}  = $xestiascan_lang{$language_selected}{errormessage} . $xestiascan_lang{$language_selected}{invalidpermissionsset};
+
+                       }
+
+               }
+
+       }
+
+}
+
+# Print the header.
+
+print "Content-Type: text/html; charset=utf-8;\r\n\r\n";
+
+# Print the page for installing Kiriwrite.
+
+print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
+print "<head>\n<title>$xestiascan_lang{$language_selected}{installertitle}</title>\n";
+print "<style type=\"text/css\" media=\"screen\">$cssstyle</style>\n</head>\n<body>";
+
+print "<div class=\"topbar\">
+<span class=\"title\">" . $xestiascan_lang{$language_selected}{installertitle} .  "</span>";
+my $language_name_short;
+my $language_list_seek = 0;
+my $installlanguage_out = "";
+
+$installlanguage_out = "<select name=\"installlanguage\">\n";
+
+foreach $language_name_short (@language_list_short){
+
+       $installlanguage_out = $installlanguage_out . "<option value=\"" . $language_name_short . "\">" . $language_list_long[$language_list_seek] . "</option>\n";
+       $language_list_seek++;
+
+}
+
+$installlanguage_out = $installlanguage_out . "</select>\n";
+
+print "<form action=\"" . $installscriptname . "\" method=\"POST\">\n$installlanguage_out\n<input type=\"submit\" value=\"$xestiascan_lang{$language_selected}{switch}\">\n</form>\n";
+print "</div>";
+
+print "<div class=\"pagespacing\">\n";
+
+print "<span class=\"pageheader\">$xestiascan_lang{$language_selected}{installertitle}</span><br /><br />\n";
+print $xestiascan_lang{$language_selected}{installertext} . "<br /><br />\n";
+
+#if ($modperlenabled eq 1){
+#      print "<br /><br />";
+#      print $xestiascan_lang{$language_selected}{modperlnotice};
+#}
+
+print "<span class=\"subheader\">$xestiascan_lang{$language_selected}{dependencytitle}</span><br /><br />\n";
+print "<b>$xestiascan_lang{$language_selected}{requiredmodules}</b><br /><br />\n";
+print $xestiascan_lang{$language_selected}{perlmodules};
+print "<br /><br />\n";
+
+if ($dependency_error eq 1){
+
+       print $xestiascan_lang{$language_selected}{errormessage};
+       print $xestiascan_lang{$language_selected}{dependencyperlmodulesmissing};
+       print "<br /><br />\n";
+
+}
+
+print "<table>\n";
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{module}, "tablecellheader", $xestiascan_lang{$language_selected}{result}, "tablecellheader", $xestiascan_lang{$language_selected}{requiredver}, "tablecellheader", $xestiascan_lang{$language_selected}{installedver}, "tablecellheader");
+
+foreach $test (keys %dependency_results) {
+       
+       xestiascan_addtablerow($test, "tablename", $dependency_results{$test}{result}, "tabledata", $test_list{$dependency_results{$test}{testname}}{Version}, "tabledata", $dependency_results{$test}{version}, "tabledata");
+
+}
+
+print "</table>";
+
+print "<br /><b>$xestiascan_lang{$language_selected}{databasemodules}</b><br /><br />\n";
+print $xestiascan_lang{$language_selected}{databasemodulestext};
+print "<br /><br />\n";
+
+print "<table>\n";
+
+if ($database_error eq 1){
+
+       print $xestiascan_lang{$language_selected}{warningmessage};
+       print $xestiascan_lang{$language_selected}{databaseperlmodulesmissing};
+       print "<br /><br />\n";
+
+}
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{module}, "tablecellheader", $xestiascan_lang{$language_selected}{result}, "tablecellheader", $xestiascan_lang{$language_selected}{requiredver}, "tablecellheader", $xestiascan_lang{$language_selected}{installedver}, "tablecellheader");
+
+foreach $test (keys %database_results) {
+
+       xestiascan_addtablerow($test, "tablename", $database_results{$test}{result}, "tabledata", $test_list{$database_results{$test}{testname}}{Version}, "tabledata", $database_results{$test}{version}, "tabledata");
+
+}
+
+print "</table><br />";
+
+print "<b>$xestiascan_lang{$language_selected}{filepermissions}</b><br /><br />\n";
+
+print $xestiascan_lang{$language_selected}{filepermissionstext};
+print "<br /><br />\n";
+
+if ($file_error eq 1){
+
+       print $xestiascan_lang{$language_selected}{errormessage};
+       print $xestiascan_lang{$language_selected}{filepermissionsinvalid};
+       print "<br /><br />\n";
+
+}
+
+print "<table>";
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{filename}, "tablecellheader", "Result", "tablecellheader");
+
+foreach $test (keys %file_results) {
+
+       xestiascan_addtablerow($test, "tablename", $file_results{$test}{result}, "tabledata");
+
+}
+
+print "</table>";
+
+if ($dependency_error eq 1){
+
+       print "<hr />\n";
+       print "<b>$xestiascan_lang{$language_selected}{criticalerror}</b><br /><br />\n";
+       print $xestiascan_lang{$language_selected}{dependencymodulesnotinstalled} . "\n";
+       print "</body>\n</html>";
+       exit;
+
+}
+
+if ($database_onemodule eq 0){
+
+       print "<hr />\n";
+       print "<b>$xestiascan_lang{$language_selected}{criticalerror}</b><br /><br />\n";
+       print $xestiascan_lang{$language_selected}{databasemodulesnotinstalled} . "\n";
+       print "</body>\n</html>";
+       exit;
+
+}
+
+if ($file_error eq 1){
+
+       print "<hr />\n";
+       print "<b>$xestiascan_lang{$language_selected}{criticalerror}</b><br /><br />\n";
+       print $xestiascan_lang{$language_selected}{filepermissionerrors} . "\n";
+       print "</body>\n</html>";
+       exit;
+
+}
+
+my @language_short;
+my (%available_languages, $available_languages);
+my @presentation_modules;
+my @output_modules;
+my @auth_modules;
+my $select_data = "";
+my (%language_data, $language_data);
+my @lang_data;
+my $xestiascan_languagefilehandle;
+my $language_out = "";
+my ($presmodule_name, $presmodule_out) = "";
+my ($authmodule_name, $authmodule_out) = "";
+my ($outputmodule_name, $outputmodule_out) = "";
+
+# Get the list of available languages.
+
+tie(%available_languages, 'Tie::IxHash');
+
+opendir(LANGUAGEDIR, "lang");
+my @language_directory = grep /m*\.lang$/, readdir(LANGUAGEDIR);
+closedir(LANGUAGEDIR);
+
+foreach my $language_file (@language_directory){
+
+       # Load the language file.
+
+       next if $language_file =~ m/^\./;
+       next if $language_file !~ m/.lang$/;
+       
+       open ($xestiascan_languagefilehandle, "lang/" . $language_file);
+       @lang_data = <$xestiascan_languagefilehandle>;
+       %language_data = xestiascan_processconfig(@lang_data);
+       close ($xestiascan_languagefilehandle);
+
+       # Get the friendly name for the language file.
+
+       $language_file_friendly = $language_file;
+       $language_file_friendly =~ s/.lang$//g;
+
+       $language_name = $language_data{about}{name};
+
+       $available_languages{$language_file_friendly} = $language_name . " (" . $language_file_friendly . ")";
+
+}
+
+# Get the list of presentation modules.
+
+opendir(OUTPUTSYSTEMDIR, "Modules/Presentation");
+my @presmodule_directory = grep /m*\.pm$/, readdir(OUTPUTSYSTEMDIR);
+closedir(OUTPUTSYSTEMDIR);
+
+foreach my $presmodule_file (@presmodule_directory){
+
+       # Get the friendly name for the database module.
+
+       next if $presmodule_file =~ m/^\./;
+       next if $presmodule_file !~ m/.pm$/;
+       $presmodule_file =~ s/.pm$//g;
+       push(@presentation_modules, $presmodule_file);
+
+}
+
+# Get the list of output modules.
+
+opendir(OUTPUTDIR, "Modules/Output");
+my @outputmodule_directory = grep /m*\.pm$/, readdir(OUTPUTDIR);
+closedir(OUTPUTDIR);
+
+foreach my $outputmodule_file (@outputmodule_directory){
+
+       # Get the friendly name for the database module.
+
+       next if $outputmodule_file =~ m/^\./;
+       next if $outputmodule_file !~ m/.pm$/;
+       $outputmodule_file =~ s/.pm$//g;
+       push(@output_modules, $outputmodule_file);
+
+}
+
+# Get the list of database modules.
+
+opendir(DATABASEDIR, "Modules/Auth");
+my @authmodule_directory = grep /m*\.pm$/, readdir(DATABASEDIR);
+closedir(DATABASEDIR);
+
+foreach my $authmodule_file (@authmodule_directory){
+
+       # Get the friendly name for the database module.
+
+       next if $authmodule_file =~ m/^\./;
+       next if $authmodule_file !~ m/.pm$/;
+       $authmodule_file =~ s/.pm$//g;
+       push(@auth_modules, $authmodule_file);
+
+}
+
+print "<h3>$xestiascan_lang{$language_selected}{settingstitle}</h3>";
+print $xestiascan_lang{$language_selected}{settingstext};
+print "<br /><br />\n";
+
+print "<form action=\"" . $installscriptname . "\" method=\"POST\">";
+print "<input type=\"hidden\" name=\"confirm\" value=\"1\">\n<input type=\"hidden\" name=\"installlanguage\" value=\"$language_selected\">\n";
+
+print "<table width=\"100%\">";
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{setting}, "tablecellheader", $xestiascan_lang{$language_selected}{value}, "tablecellheader");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{directories}, "tablecellheader", "", "tablecellheader");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{imagesuripath}, "tablename", "<input type=\"text\" name=\"imagesuripath\" size=\"32\" maxlength=\"512\" value=\"$default_imagesuri\">", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{scansuripath}, "tablename", "<input type=\"text\" name=\"scansuripath\" size=\"32\" maxlength=\"512\" value=\"$default_scansuri\">", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{scansfspath}, "tablename", "<input type=\"text\" name=\"scansfspath\" size=\"64\" maxlength=\"4096\" value=\"$default_scansfs\">", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{date}, "tablecellheader", "", "tablecellheader");
+
+foreach my $select_name (@datetime_formats){
+       $select_data = $select_data . "<option value=\"$select_name\">" . $select_name . "</option>\n";
+}
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{dateformat}, "tablename", "<select name=\"dateformat\">$select_data</select>\n<input type=\"text\" size=\"32\" maxlength=\"64\" name=\"customdateformat\">", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{language}, "tablecellheader", "", "tablecellheader");
+
+foreach my $language (keys %available_languages){
+       if ($language eq $language_selected){
+               $language_out = $language_out . "<option value=\"" . $language . "\" selected=selected>" . $available_languages{$language} . "</option>\n";
+       } else {
+               $language_out = $language_out . "<option value=\"" . $language . "\">" . $available_languages{$language} . "</option>\n";
+       }
+}
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{systemlanguage}, "tablename", "<select name=\"language\">\r\n$language_out\r\n</select>", "tabledata");
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{modules}, "tablecellheader", "", "tablecellheader");
+
+foreach $presmodule_name (@presentation_modules){
+       $presmodule_out = $presmodule_out . "<option value=\"$presmodule_name\">$presmodule_name</option>";
+}
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{presentationmodule}, "tablename", "<select name=\"presmodule\">$presmodule_out</select>", "tabledata");
+
+foreach $outputmodule_name (@output_modules){
+       if ($default_outputmodule = $outputmodule_name){
+               $outputmodule_out = $outputmodule_out . "<option value=\"$outputmodule_name\" selected>$outputmodule_name</option>";            
+       } else {
+               $outputmodule_out = $outputmodule_out . "<option value=\"$outputmodule_name\">$outputmodule_name</option>";
+       }
+}
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{outputmodule}, "tablename", "<select name=\"outputmodule\">$outputmodule_out</select>", "tabledata");
+
+foreach $authmodule_name (@auth_modules){
+       $authmodule_out = $authmodule_out . "<option value=\"$authmodule_name\">$authmodule_name</option>";
+}
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{authmodule}, "tablename", "<select name=\"authmodule\">$authmodule_out</select>", "tabledata");
+
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseserver}, "tablename", "<input type=\"text\" name=\"databaseserver\" size=\"32\" maxlength=\"128\" value=\"$default_server\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseport}, "tablename", "<input type=\"text\" name=\"databaseport\" maxlength=\"5\" size=\"5\" value=\"$default_port\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseprotocol}, "tablename", "<select name=\"databaseprotocol\">\n<option value=\"tcp\">tcp</option>\n<option value=\"udp\">udp</option>\n</select>\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasename}, "tablename", "<input type=\"text\" name=\"databasename\" size=\"32\" maxlength=\"32\" value=\"$default_name\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databaseusername}, "tablename", "<input type=\"text\" name=\"databaseusername\" size=\"16\" maxlength=\"16\" value=\"$default_username\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasepassword}, "tablename", "<input type=\"password\" name=\"databasepassword\" size=\"32\" maxlength=\"64\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{databasetableprefix}, "tablename", "<input type=\"text\" name=\"databasetableprefix\" size=\"32\" maxlength=\"32\" value=\"$default_prefix\">\n", "tabledata");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{installationoptions}, "tablecellheader", "", "tablecellheader");
+xestiascan_addtablerow($xestiascan_lang{$language_selected}{installoptions}, "tablename", "<input type=\"checkbox\" name=\"removeinstallscript\" checked=checked value=\"on\"> $xestiascan_lang{$language_selected}{removeinstallscript}\n<br />\n<input type=\"checkbox\" name=\"removemultiuserinstallscript\" checked=checked value=\"on\"> $xestiascan_lang{$language_selected}{removemultiuserinstallscript}\n", "tabledata");
+
+print "</table>\n";
+
+print "<br />\n<input type=\"submit\" value=\"$xestiascan_lang{$language_selected}{savesettingsbutton}\"> | <input type=\"reset\" value=\"$xestiascan_lang{$language_selected}{resetsettingsbutton}\">\n";
+
+print "</form>\n</div>\n</body>\n</html>";
+exit;
+
+__END__
\ No newline at end of file
diff --git a/cgi-files/lang/en-GB.lang b/cgi-files/lang/en-GB.lang
new file mode 100644 (file)
index 0000000..a66cb49
--- /dev/null
@@ -0,0 +1,327 @@
+[about]
+name = English (British)
+creator = Steve Brokenshire
+mailaddress = sbrokenshire|ao|xestia|dottie|co|dottie|uk
+
+[auth]
+login = Login
+loginbutton = Login
+username = User Name
+password = Password
+keeploggedin = Keep logged in
+cookiesrequired = Cookies support must be enabled in your browser in order to be to login.
+loginerror = The credentials supplied were invalid or you have been logged out as your session has expired. Please check that the username and password you have entered are correct and contact your system administrator if you are still unable to login.
+
+loggedout = Logged Out
+loggedoutmsg = You have logged out.
+displaylogin = Display the login page.
+
+[users]
+
+submenu_listusers = List Users
+submenu_adduser = Add User
+submenu_logoutallusers = Logout All Users
+
+userslist = Users List
+adduser = Add User
+edituser = Edit User
+deleteuser = Delete User
+
+userinformation = User Information
+userpermissions = User Permissions
+
+nameofoutputmoduleerror = The name of the output format module that caused this error is: %s
+nameofexportmoduleerror = The name of the export format module that caused this error is: %s
+
+permit = Permit
+
+returnuserlist = Return to the user list.
+
+adduserbutton = Add User
+edituserbutton = Edit User
+
+listusers = List Users
+showdeactivated = Show Deactivated Users
+update = Update
+username = User Name
+name = Name
+password = Password
+confirmpassword = Confirm Password
+adminprivs = Administrator Privileges
+accountenabled = Account Enabled
+scannerlist = Scanner List
+scannername = Scanner Name
+allowaccess = Allow Access
+connected = Connected
+devconnected = Connected
+devdisconnected = Disconnected
+outputmodulelist = Output Format Module List
+exportmodulelist = Export Format Module List
+modulename = Module Name
+available = Available
+modavailable = Available
+modunavailable = Unavailable
+newpassword = New Password
+confirmnewpassword = Confirm New Password
+
+userdetails = User Details
+
+edituser = Edit User
+
+useradded = User Added
+useraddedtolist = The user '%s' was added to the user list.
+
+useredited = User Edited
+usereditedsuccess = The user '%s' on the user list was edited.
+usereditedlogout = If the user being edited was yourself and you have changed your username, you will be logged out of the Kiriwrite.
+
+deleteuser = Delete User
+deleteuserareyousure = Are you sure you want to delete '%s' from the user list?
+deleteuserbutton = Yes, delete User
+noreturnuserlist = No, return to the user list.
+
+userdeleted = User Deleted
+userdeletedsuccess = The user '%s' was deleted from the user list.
+
+logoutallusers = Logout All Users
+logoutallquestion = Are you sure you want to logout all users?
+logoutallwarning = All users (including the user executing this action) will be logged out of the system and will need to log in again.
+logoutallsuccess = All users (including yourself) have been logged out.
+logoutallloginagain = You will need to log back in again.
+logoutallcontinue = Click on this link to continue.
+
+logoutallbutton = Logout All Users 
+
+[setting]
+
+submenu_viewsettings = View Settings
+submenu_editsettings = Edit Settings
+
+viewsettings = View Settings
+currentsettings = The current settings being used are the following:
+directories = Directories
+databasedirectory = Database Directory
+outputdirectory = Output Directory
+imagesuripath = Images (URI path)
+scansuripath = Scans (URI path)
+scansfspath = Scans (Filesystem path)
+display = Display
+textareacols = Text Area Columns
+textarearows = Text Area Rows
+pagecount = Pages on browse
+templatecount = Templates on browse
+filtercount = Filters on browse
+date = Date
+dateformat = Date Format
+language = Language
+systemlanguage = System Language
+modules = Modules
+presentationmodule = Presentation Module
+outputmodule = Output Format Module
+authmodule = Authentication Module
+altersettings = To alter the current settings, select the Edit Settings option at the top of the page.
+
+editsettings = Edit Settings
+warning = Warning: 
+warningmessage = Settings that have changed take effect after clicking on the 'Change Settings' button and viewing the confirmation message.
+singleday = D - Show single digit day if day value is less than 10.
+doubleday = DD - Show double digit day if day value is less than 10.
+singlemonth = M - Show single digit month if month value is less than 10.
+doublemonth = MM - Show double digit month if month value is less than 10.
+singleyear = Y - Show double digit year value.
+doubleyear = YY - Show four digit year value.
+singlehour = h - Show single digit hour if hour value is less than 10.
+doublehour = hh - Show double digit hour if hour value is less than 10.
+singleminute = m - Show single digit minute if minute value is less than 10.
+doubleminute = mm - Show double digit minute if minute value is less than 10.
+singlesecond = s - Show single digit second if second value is less than 10.
+doublesecond = ss - Show double digit second if second value is less than 10.
+othercharacters = Other Characters: / - < > ;
+databaseserver = Database Server
+databaseport = Database Port
+databaseprotocol = Database Protocol
+databasename = Database Name
+databaseusername = Database Username
+databasepassword = Database Password
+keepcurrentpassword = Keep the current password
+tableprefix = Table Prefix
+changesettingsbutton = Change Settings
+returnsettingslist = Return to the list of settings.
+settingsedited = Settings Edited
+settingseditedmessage = The settings have been changed and will take effect on the next page load of Xestia Scanner Server.
+
+[error]
+
+error = Error!
+extendederror = The extended information about the error is:
+generic = An error has occurred but not an error that is known to Kiriwrite.
+blankfilename = The filename specified was blank.
+blankvariable = A blank variable was specified.
+fileexists = A filename specified already exists.
+internalerror = An internal error has occurred within Kiriwrite.
+invalidaction = An invalid action was specified.
+invalidfilename = The filename given contains invalid characters.
+invalidmode = An invalid mode was specified.
+invalidutf8 = A UTF-8 string is invalid.
+invalidvariable = An variable with invalid data has been found.
+variabletoolong = A variable given is too long.
+authconnectionerror = An authentication (database) connection error has occurred.
+autherror = An authentication error occurred.
+authmoduleblank = The authentication module name given is blank.
+authmoduleinvalid = The name of the authentication module given is invalid.
+authmodulemissing = The authentication module with the name given is missing.
+blankdatetimeformat = The date and time format given is blank.
+blankdirectory = The directory name specified was blank.
+blankpictureid = The picture ID given was blank.
+blankvariable = The variable given was blank.
+bottomrightx = No value for Bottom Right X was given.
+bottomrightxinvalidnumber = The Bottom Right X value given is invalid.
+bottomrighty = No value for Bottom Right Y was given.
+bottomrightyinvalidnumber = The Bottom Right Y value given is invalid.
+brightnessblank = The brightness value given was blank.
+brightnessinvalidnumber = The brightness value given was invalid.
+colourblank = No setting for Colour was given.
+colourinvalidoption = The Colour setting given is invalid.
+invaliddirectory = The directory name specified was invalid.
+invaliddatetimeformat = The date and time format given is invalid.
+languagefilenamemissing = The language filename given does not exist.
+moduleinvalid = The module name given was invalid.
+nametoolong = The name given is too long.
+notpermitted = You do not have permission to preform this action in Xestia Scanner Server.
+outputmoduleblank = The output format module name given is blank.
+outputmoduleinvalid = The output format module name given is invalid.
+passwordblank = The password given was blank.
+passwordsdonotmatch = The passwords given do not match.
+passwordtoolong = The password given was too long.
+permissiontypeblank = The permission type given was blank.
+presmoduleblank = The presentation module name given is blank.
+presmoduleinvalid = The presentation module name given is invalid.
+presmodulemissing = The presentation module with the filename given is missing.
+rotateblank = The rotate option given is blank.
+rotateinvalidoption = The rotate option given is invalid.
+resolutionblank = The resolution value given was blank.
+resolutioninvalidnumber = The resolution value given was invalid.
+scannererror = An error occurred whilst trying to use the scanner.
+scannerpermissioninvalid = The scanner cannot be used as you don't have permission to use it.
+serverdatabasenameinvalid = The server database name given is invalid.
+serverdatabasenametoolong = The server database name given is too long.
+serverdatabasepasswordtoolong = The server database password given is too long.
+serverdatabasetableprefixinvalid = The server database table prefix given is invalid.
+serverdatabasetableprefixtoolong = The server database table prefix given is too long.
+serverdatabaseusernameinvalid = The server database username given is invalid.
+serverdatabaseusernametoolong = The server database username given is too long.
+servernameinvalid = The database server name given is invalid.
+servernametoolong = The database server name given is too long.
+serverportnumberinvalid = The database port number given is invalid.
+serverportnumberinvalidcharacters = The database port number given contains characters other than numbers.
+serverportnumbertoolong = The database port number given is too long.
+serverprotocolinvalid = An invalid database server protocol was specified.
+serverprotocolnametoolong = The database server protocol name given is too long.
+userediterror = An error occurred whilst editing the user details.
+userexists = A user with the username given already exists.
+userdoesnotexist = There is no user with the username given.
+usernameblank = The username given is blank.
+usernameinvalid = The username given is invalid.
+usernametoolong = The username given is too long.
+
+[options]
+edit = Edit
+delete = Delete
+compile = Compile
+
+[blank]
+noname = No Name
+nodescription = No Description
+blankdatabasename = Blank Database Name
+
+[common]
+alter = Alter
+setting = Setting
+value = Value
+restorecurrent = Restore current settings
+restoredefault = Restore default settings
+clearvalues = Clear values
+selectnone = Select None
+options = Options
+
+tags = Kiriwrite Tags:
+pagecontent = <kiriwrite:pagecontent> - Specifies the page content.
+pagetitle = <kiriwrite:pagetitle> - Specifies the page title (and page section depending on page settings).
+pagename = <kiriwrite:pagename> - Specifies the page name.
+pagedescription = <kiriwrite:pagedescription> - Specifies the page description.
+pagesection = <kiriwrite:pagesection> - Specifies the page section.
+pageautosection = <kiriwrite:autosection> - Automatic page section name.
+pageautotitle = <kiriwrite:autotitle> - Automatic page title (and page section depending on page settings).
+
+[menu]
+scanconfig = Scan Configuration
+userconfig = User Configuration
+settingsconfig = Settings Configuration
+logout = Logout
+
+[scan]
+scanconfig = Scan Configuration
+
+process = Process
+switchscanner = Switch Scanner
+previewdocument = Preview Document
+startscanning = Start Scanning
+
+noscanners = No scanners are available. Please check the connections to the server and make sure that the modules/drivers for the scanners are enabled.
+scanner = Scanner :
+documentpreview = Document Preview
+
+documentsettings = Document Settings
+picturedimensions = Picture Dimensions
+topleftx = Top Left X: 
+toplefty = Top Left Y: 
+bottomrightx = Bottom Right X: 
+bottomrighty = Bottom Right Y: 
+picturesettings = Picture Settings
+pictureresolution = Picture Resolution: 
+rotate = Rotate: 
+r0deg = 0 degrees
+r90deg = 90 degrees
+r180deg = 180 degrees
+r270deg = 270 degrees
+brightness = Brightness: 
+colour = Colour:
+colourrgb = Colour (RGB)
+grey = Greyscale
+
+dpi = dpi
+mm = mm
+
+picturesettings = Picture Settings
+outputmoduleresults = Output Format Module Results
+outputmodulefailed = The output format module failed with the following error: %s
+outputmoduleunable = As the output format module failed, the process is unable to continue.
+outputmodulecomplete = The output format module completed with no errors.
+exportmoduleresults = Export Format Modules Results
+exportmodulefailed = The export format module failed with the following error: %s 
+exportmodulecomplete = The export format module completed with no errors.
+noexportmoduleselected = No export format modules were selected.
+resultsuffix = %s - Results
+imagepreview = Image Preview
+outputformatsettings = Output Format Module Settings
+outputmodule = Output format module: 
+noneavailable = None available.
+nooutputmodulesavail = There are no output format modules available. Unable to continue.
+nooutputmoduleopts = There are no options available for this output format module.
+outputmodulemissing = The output format module with the filename given is missing. Unable to continue.
+outputmoduleinvalidfilepermissions = You cannot use this output format module as the file permissions set for it are invalid. Unable to continue.
+outputmoduleinvaliddbpermissions = You cannot use this output format module as you do not have permission to use it. Unable to continue.
+outputmoduleinvalidname = The name of the output format module given is invalid. Unable to continue.
+exportformatsettings = Export Format Module Settings
+noexportmodulesavail = There are no export format modules available. Unable to continue.
+exportmoduleinvalidfilepermissions = You cannot use this export format module as you do not have permission to use it.
+exportmoduleinvaliddbpermissions = You cannot use this export format module as the file permissions set for it are invalid.
+exportmoduleinvalidname = The name of the export format module given is invalid.
+exportmodulemissing = The export format module with the filename given is missing.
+noexportmoduleopts = There are no options available for this export format module.
+
+causedpictureresolution = %s (caused by the Picture Resolution setting)
+causedtopleftx = %s (caused by the Top Left X Picture Dimension setting)
+causedtoplefty = %s (caused by the Top Left Y Picture Dimension setting)
+causedbottomrightx = %s (caused by the Bottom Right X Picture Dimension setting)
+causedbottomrighty = %s (caused by the Bottom Right Y Picture Dimension setting)
\ No newline at end of file
diff --git a/cgi-files/page.html b/cgi-files/page.html
new file mode 100644 (file)
index 0000000..f1917c3
--- /dev/null
@@ -0,0 +1,256 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+       <head>
+               <title>Xestia Scanner Server<xestiascan:title></title>
+               <style type="text/css" media="screen">
+                       body {
+                               margin: 0px; 
+                               font-family: sans-serif; 
+                               padding: 0px; 
+                               font-size: 13px;
+                               background-color: #402040;
+                               color: #ffffff;
+                               background-image: url('<xestiascan:imagespath>/pagebackground.png');
+                               background-repeat: repeat-x;
+                       }
+                       
+                       a:link {
+                               color: #ffffff;
+                       }
+                               
+                       a:hover {
+                               color: #bbbbbb;
+                       }
+                               
+                       a:visited {
+                               color: #ffffff;
+                       }
+                       
+                       table {
+                               width: 100%;
+                       }
+                       
+                       tr {
+                               padding: 5px;
+                       }
+                       
+                       /*
+                       
+                       select, input, button {
+                               font-size: 12px;
+                               background-color: #408080;
+                               color: #ffffff;
+                               border-style: solid;
+                               border-style: 1px;
+                               border-color: #102020;
+                               padding: 2px;
+                       }
+                       
+                       */
+                       
+                       textarea {
+                               font-size: 12px;
+                               background-color: #408080;
+                               color: #ffffff;
+                               border-style: solid;
+                               border-style: 1px;
+                               border-color: #102020;
+                               padding: 2px;
+                               white-space: nowrap;
+                       }
+                       
+                       .page {
+                       }
+                       
+                       .pagedata {
+                               padding: 0px;
+                       }
+                       
+                       .topbar {
+                               padding: 3px;
+                               background-color: #753575;
+                               border-bottom-style: solid;
+                               border-bottom-width: 1px;
+                               border-bottom-color: #EE70EE;
+                               text-align: right;
+                               min-height: 17px;
+                               background-image: url('<xestiascan:imagespath>/menutop.png');
+                               background-repeat: repeat-x;
+                       }
+                       
+                       .title {
+                               font-size: 16px;
+                               font-weight: bold;
+                               position: absolute;
+                               text-align: left;
+                               z-index: 0;
+                               left: 0;
+                               padding-left: 3px;
+                       }
+                       
+                       .tablecellheader {
+                               font-size: 12px;
+                               background-color: #703570;      
+                               font-weight: bold;
+                               text-align: left;
+                               background-image: url('<xestiascan:imagespath>/tabletop.png');
+                               background-repeat: repeat-x;
+                       }
+                       
+                       .tablecell1 {
+                               background-color: #603060;
+                               font-size: 12px;
+                       }
+                       
+                       .tablecell2 {
+                               background-color: #402040;
+                               font-size: 12px;
+                       }
+                       
+                       .tablecelldisabled {
+                               background-color: #808080;
+                               font-size: 12px;
+                       }
+
+                       .copyrightbar {
+                               background-color: #30AAAA;
+                               padding: 7px;
+                               border-top: solid;
+                               border-top-color: #70bbbb;
+                               border-top-width: 1px;
+                       }
+                       
+                       .errorsectionbox {
+                               border-color: #A00000;
+                               border-style: solid;
+                               border-width: 1px;
+                               margin: 5px;
+                       }
+                       
+                       .errorboxheader {
+                               background-color: #700000;
+                               font-size: 16px;
+                               padding: 5px;
+                               text-align: center;
+                       }
+                       
+                       .errorbox {
+                               padding: 5px;
+                               background-color: #350000;
+                       }
+                       
+                       .copyrighttext {
+                               font-size:12px;
+                       }
+                       
+                       .datalist {
+                               border: solid;
+                               border-width: 1px;
+                               border-color: #CC60CC;
+                               padding: 5px;
+                               background-color: #703570;
+                       }
+
+                       .warningcell {
+                               background-color: #902020;
+                               font-size: 12px;
+                       }
+
+                       .warningoption {
+                               background-color: #902020;
+                       }
+
+                       .pageheader {
+                               font-size: 18px;
+                               font-weight: bold;
+                       }
+
+                       .smallpageheader{
+                               font-weight: bold;
+                       }
+                       
+                       .scannermenu{
+                               text-align: center;
+                               padding: 3px;
+                               background-color: #603060;
+                               border-bottom-style: solid;
+                               border-bottom-width: 1px;
+                               border-bottom-color: #CC60CC;
+                               text-align: center;
+                               background-image: url('<xestiascan:imagespath>/scannertop.png');
+                               background-repeat: repeat-x;
+                       }
+                       
+                       .sectionbox {
+                               float: left;
+                               width: inherit;
+                               border-color: #A050A0;
+                               border-style: solid;
+                               border-width: 1px;
+                               padding: 0px;
+                               margin: 5px;
+                       }
+                       
+                       .sectiontitle{
+                               background-color: #753575;
+                               font-size: 16px;
+                               padding: 5px;
+                               text-align: center;
+                               background-image: url('<xestiascan:imagespath>/sectiontop.png');
+                               background-repeat: repeat-x;
+                               border-bottom-color: #904590;
+                               border-bottom-style: solid;
+                               border-bottom-width: 1px;
+                       }
+                       
+                       .sectionboxnofloat {
+                               border-color: #A050A0;
+                               border-style: solid;
+                               border-width: 1px;
+                               padding: 0px;
+                               margin: 5px;
+                       }
+                       
+                       .secondbox{
+                               padding: 5px;
+                               background-color: #502550;
+                       }
+                       
+                       .previewimage{
+                               text-align: center;
+                       }
+                       
+                       .outputmoduletitle, .exportmoduletitle{
+                               padding: 5px;
+                               background-color: #603060;
+                               font-weight: bold;
+                       }
+                       
+                       .outputmoduleoptions, .exportmoduleoptions{
+                               padding-left: 15px;
+                               padding-top: 5px;
+                               padding-right: 5px;
+                               padding-bottom: 5px;
+                               background-color: #502550;
+                       }
+                       
+               </style>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8;">
+       </head>
+       <body>
+               <div class="topbar">
+                               <span class="title">Xestia Scanner Server</span>
+                               <xestiascan:menu>
+               </div>
+               <div class="page">
+
+                       <div class="pagedata">
+                               <xestiascan:pagedata>
+                       </div>
+                       
+               </div>
+               <!--<div class="copyrightbar">
+                       &copy;2010 Steve Brokenshire<br />
+               </div>-->
+       </body>
+</html> 
diff --git a/cgi-files/xsdss.cgi b/cgi-files/xsdss.cgi
new file mode 100644 (file)
index 0000000..822526d
--- /dev/null
@@ -0,0 +1,665 @@
+#!/usr/bin/perl -w
+
+#################################################################################
+# Xestia Scanner Server (xsdss.cgi)                                            #
+# Main program script                                                          #
+#                                                                              #
+# Version: 0.1.0                                                               #
+#                                                                              #
+# Copyright (C) 2005-2011 Steve Brokenshire <sbrokenshire@xestia.co.uk>                #
+#                                                                              #
+# This code has been forked from Kiriwrite <http://xestia.co.uk/kiriwrite>.    #
+# Save development time, recycle your code where possible!                     #
+#                                                                              #
+# This program is free software: you can redistribute it and/or modify         #
+# it under the terms of the GNU General Public License as published by         #
+# the Free Software Foundation, version 3 of the License.                      #
+#                                                                              #
+# This program is distributed in the hope that it will be useful,              #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                        #
+# GNU General Public License for more details.                                 #
+#                                                                              #
+# You should have received a copy of the GNU General Public License            #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.                #
+#################################################################################
+
+use strict;
+use warnings;
+
+use utf8;
+use CGI::Lite;
+use Tie::IxHash;
+use MIME::Base64 3.13 qw(decode_base64url);
+
+binmode STDOUT, ':utf8';
+
+# This is commented out because it uses a fair bit of CPU usage.
+
+#use CGI::Carp('fatalsToBrowser');     # Output errors to the browser.
+
+# Declare global variables for Xestia Scanner Server settings and languages.
+
+our ($xestiascan_config, %xestiascan_config, %xestiascan_lang, $xestiascan_lang, $xestiascan_version, %xestiascan_version, $xestiascan_env, %xestiascan_env, $xestiascan_presmodule, $xestiascan_authmodule, $xestiascan_script_name, $xestiascan_env_path);
+our ($form_data, %form_data);
+our ($loggedin_user);
+our $successful_auth = 0;
+
+# If you are using mod_perl please change these settings to the correct
+# directory where this script is being run from.
+
+use lib '.';
+chdir('.');
+
+# Load the common functions module.
+
+use Modules::System::Common;
+
+# Setup the version information for Xestia Scanner Version.
+
+%xestiascan_version = (
+       "major"         => 0,
+       "minor"         => 1,
+       "revision"      => 0
+);
+
+xestiascan_initialise;         # Initialise the Xestia Scanner Server enviroment.
+xestiascan_settings_load;      # Load the configuration options.
+
+my $query_lite = new CGI::Lite;
+$form_data = $query_lite->parse_form_data();
+
+# Check to see if the user is logged in and present a form if not.
+
+use Modules::System::Auth;
+
+# Check to see if the module is a multiuser module.
+
+my %authmodule_capabilities = $xestiascan_authmodule->capabilities();
+
+if ($authmodule_capabilities{'multiuser'} eq 0){
+       
+       # Module does not have multiuser support so don't do
+       # any authentication.
+       
+       $successful_auth = 1;
+       
+}
+
+my $auth_username = "";
+my $auth_password = "";
+my $auth_seed = "";
+my $auth_stayloggedin = "";
+my $auth_validinput = 1;
+my $cookie_expirestime = 0;
+my $auth_failure = int(0);
+my $print_cookie = 0;
+my $auth_result = "none";
+       
+my $cookie_data = $query_lite->parse_cookies;
+
+$auth_username = decode_base64url($cookie_data->{ $main::xestiascan_config{'database_tableprefix'} . '_auth_username'});
+$auth_seed     = $cookie_data->{ $main::xestiascan_config{'database_tableprefix'} . '_auth_seed'};
+
+if (!$auth_username || !$auth_seed){
+
+       # The authentication data contains invalid input.
+       
+       $auth_validinput = 0;
+       
+}
+
+# Check to see if the username and seed are valid and
+# skip to the login form if it isn't.
+       
+if ($auth_validinput eq 1){
+       
+       # Connect to the database server and authenticate.
+       
+       $xestiascan_authmodule->connect();
+
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       $auth_result = $xestiascan_authmodule->userauth("seed", $auth_username, $auth_seed);
+       
+       if ($xestiascan_authmodule->geterror eq "DatabaseError"){
+                       
+               # A database error has occured so return an error with
+               # the extended error information.
+                       
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+                       
+       }
+               
+       $successful_auth = 1 if $auth_result eq 1;
+       $auth_failure = 1 if $auth_result ne 1;
+       $auth_failure = 0 if (!$auth_seed || $auth_seed eq "");
+       
+       # Disconnect from the database server.
+       
+       #$xestiascan_authmodule->disconnect();
+               
+}
+
+if ($form_data->{'mode'} && $form_data->{'mode'} eq "auth" && $successful_auth eq 0){
+       
+       $auth_username          = $form_data->{'username'};
+       $auth_password          = $form_data->{'password'};
+       $auth_stayloggedin      = $form_data->{'stayloggedin'};
+       
+       if (!$auth_stayloggedin || $auth_stayloggedin ne "on"){
+               
+               $auth_stayloggedin = 0;
+               $cookie_expirestime = 10800;
+               
+       } else {
+               
+               $auth_stayloggedin = 1;
+               $cookie_expirestime = 31536000;
+               
+       }
+
+       $xestiascan_authmodule->connect();
+
+       # Check if any errors occured while connecting to the database server.
+       
+       if ($main::xestiascan_authmodule->geterror eq "AuthConnectionError"){
+               
+               # A database connection error has occured so return
+               # an error.
+               
+               xestiascan_error("authconnectionerror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       ($auth_result, $auth_seed)      = $xestiascan_authmodule->userauth("password", $auth_username, $auth_password, $auth_stayloggedin);
+       
+       if ($xestiascan_authmodule->geterror eq "DatabaseError"){
+               
+               # A database error has occured so return an error with
+               # the extended error information.
+               
+               xestiascan_error("autherror", $main::xestiascan_authmodule->geterror(1));
+               
+       }
+       
+       $successful_auth = 1 if $auth_result eq 1;
+       $auth_failure = 1 if $auth_result ne 1;
+
+       # Disconnect from the database server.
+       
+       #$xestiascan_authmodule->disconnect();
+       
+       $form_data->{'mode'} = "";
+
+       $print_cookie = 1;
+       
+}
+
+if ($successful_auth eq 0) {
+
+       # No valid authenication credentials are available so write a form.
+       
+       my $authpagedata = xestiascan_auth_authenticate($auth_failure);
+
+       xestiascan_output_header;
+       xestiascan_output_page("Login", $authpagedata, "none");
+       exit;
+       
+}
+
+if ($successful_auth eq 1){
+
+       $loggedin_user = $auth_username;
+       
+}
+
+# endif
+
+# Check if a mode has been specified and if a mode has been specified, continue
+# and work out what mode has been specified.
+
+if ($form_data->{'mode'}){
+       my $http_query_mode = $form_data->{'mode'};
+
+       if ($http_query_mode eq "scan"){
+
+               use Modules::System::Scan;
+               
+               if ($form_data->{'action'}){
+               
+                       my $http_query_action = $form_data->{'action'};
+                       
+                       if ($http_query_action eq "scan"){
+                       
+                               my $http_query_previewdocument = $form_data->{'previewdocument'};
+                               my $http_query_switch = $form_data->{'switch'};
+
+                               $http_query_previewdocument = "no" if !$http_query_previewdocument;
+                               $http_query_switch = "no" if !$http_query_switch;
+                               
+                               # Get the variables needed for the subroutine.
+                               
+                               my %previewoptions;
+                               
+                               $previewoptions{ScannerID} = $form_data->{'scanner'};
+                               $previewoptions{Brightness} = $form_data->{'brightness'};
+                               $previewoptions{Contrast} = $form_data->{'contrast'};
+                               $previewoptions{Rotate} = $form_data->{'rotate'};
+                               $previewoptions{Colour} = $form_data->{'colourtype'};
+                               $previewoptions{Resolution} = $form_data->{'imagedpi'};
+                               $previewoptions{TopLeftX} = $form_data->{'topleftx'};
+                               $previewoptions{TopLeftY} = $form_data->{'toplefty'};
+                               $previewoptions{BottomRightX} = $form_data->{'bottomrightx'};
+                               $previewoptions{BottomRightY} = $form_data->{'bottomrighty'};
+                               
+                               $previewoptions{TopLeftX} = "0" if !$previewoptions{TopLeftX};
+                               
+                               if ($http_query_switch eq "switched"){
+                               
+                                       # Switching scanners so don't need to scan.
+                                       
+                                       my $pagedata = xestiascan_scan_preview("off", %previewoptions);
+
+                                       # Output the header to browser/console/stdout.
+                                       
+                                       xestiascan_output_header;
+                                       xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database");      # Output the page to browser/console/stdout.
+                                       exit;   # End the script.
+                                       
+                               }
+                               
+                               if ($http_query_previewdocument eq "on"){
+                                       
+                                       # No action specified so write out default form.
+                                       
+                                       my $pagedata = xestiascan_scan_preview("on", %previewoptions);
+                                       
+                                       # Output the header to browser/console/stdout.
+                                       
+                                       xestiascan_output_header;
+                                       xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database");      # Output the page to browser/console/stdout.
+                                       exit;   # End the script.
+                       
+                               } else {
+
+                                       my $http_query_outputformat = $form_data->{'outputformat'};
+                                       my $http_query_formatswitch = $form_data->{'formatswitch'};
+                                       my $http_query_confirm = $form_data->{'confirm'};
+                                       my $http_query_imagehex = $form_data->{'imagehex'};
+                                       
+                                       $http_query_formatswitch = "no" if !$http_query_formatswitch;
+                                       $previewoptions{Switched} = $http_query_formatswitch;
+                                       
+                                       if (!$http_query_confirm){
+                                               $http_query_confirm = 0;
+                                       }
+                                       
+                                       if ($http_query_formatswitch eq "yes"){
+                                               $http_query_confirm = 0;
+                                       }
+                                       
+                                       $previewoptions{ImageHex} = $http_query_imagehex if $http_query_imagehex;
+                                       $previewoptions{OutputFormat} = $http_query_outputformat if $http_query_outputformat;
+                                       
+                                       my $pagedata = xestiascan_scan_final($http_query_confirm, %previewoptions);
+                       
+                                       xestiascan_output_header;
+                                       xestiascan_output_page($xestiascan_lang{scan}{picturesettings}, $pagedata, "database"); # Output the page to browser/console/stdout.
+                                       exit;   # End the script.
+                                       
+                               }
+                               
+                       } elsif ($http_query_action eq "getpreviewimage"){
+                       
+                               my $http_query_pictureid = $form_data->{'pictureid'};
+                               my $http_query_dontclear = $form_data->{'dontclear'};
+                               
+                               if (!$http_query_dontclear){
+                                       $http_query_dontclear = 0;
+                               }
+                               
+                               xestiascan_scan_getpreviewimage($http_query_pictureid, $http_query_dontclear);
+                               exit;
+                               
+                       }
+                               
+               }
+                       
+               # No action specified so write out default form.
+                       
+               my $pagedata = xestiascan_scan_preview();
+                       
+               # Output the header to browser/console/stdout.
+                       
+               xestiascan_output_header;
+               xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database");      # Output the page to browser/console/stdout.
+               exit;   # End the script.
+               
+       } elsif ($http_query_mode eq "users"){
+
+               use Modules::System::Users;
+
+               if ($form_data->{'action'}){
+
+                       my $http_query_action = $form_data->{'action'};
+
+                       if ($http_query_action eq "add"){
+
+                               my $http_query_confirm = $form_data->{'confirm'};
+                               
+                               if (!$http_query_confirm){
+                                       
+                                       # The http_query_confirm variable is uninitialised, so place a
+                                       # '0' (meaning an unconfirmed action).
+                                       
+                                       $http_query_confirm = 0;
+                                       
+                               }
+                               
+                               if ($http_query_confirm eq 1){
+                               
+                                       use Hash::Search;
+                                       my $hs = new Hash::Search;
+                                       my %http_userinfo;
+                                       %form_data = $query_lite->parse_form_data();
+                                       
+                                       $http_userinfo{'Username'}              = $form_data->{'username'};
+                                       $http_userinfo{'Name'}                  = $form_data->{'name'};
+                                       $http_userinfo{'Password'}              = $form_data->{'password'};
+                                       $http_userinfo{'ConfirmPassword'}       = $form_data->{'confirmpassword'};
+                                       $http_userinfo{'Admin'}                 = $form_data->{'admin'};
+                                       $http_userinfo{'Enabled'}               = $form_data->{'enabled'};
+                                       
+                                       # Get the list of scanners from the query.
+                                       
+                                       $hs->hash_search("^scanner_", %form_data);
+                                       my %http_scanner = $hs->hash_search_resultdata;
+                                       
+                                       # Get the list of output modules from the query.
+                                       
+                                       $hs->hash_search("^outputmodule_", %form_data);
+                                       my %http_outputmodules = $hs->hash_search_resultdata;
+                                       
+                                       # Get the list of export modules from the query.
+                                       
+                                       $hs->hash_search("^exportmodule_", %form_data);
+                                       my %http_exportmodules = $hs->hash_search_resultdata;
+                                       
+                                       my $pagedata = xestiascan_users_add($http_userinfo{Username}, \%http_userinfo, \%http_scanner, \%http_outputmodules, \%http_exportmodules, $http_query_confirm);
+                                       
+                                       xestiascan_output_header;       # Output the header to browser/console/stdout;
+                                       xestiascan_output_page($xestiascan_lang{users}{adduser}, $pagedata, "users");   # Output the page to browser/console/stdout;
+                                       exit;                           # End the script.
+                                       
+                               }
+
+                               my $pagedata = xestiascan_users_add;
+
+                               xestiascan_output_header;       # Output the header to browser/console/stdout;
+                               xestiascan_output_page($xestiascan_lang{users}{adduser}, $pagedata, "users");   # Output the page to browser/console/stdout;
+                               exit;                           # End the script.                               
+
+                       } elsif ($http_query_action eq "edit"){
+                               
+                               my $http_query_confirm  = $form_data->{'confirm'};
+                               my $http_query_username = $form_data->{'user'};
+
+                               if (!$http_query_confirm){
+                                       
+                                       # The http_query_confirm variable is uninitialised, so place a
+                                       # '0' (meaning an unconfirmed action).
+                                       
+                                       $http_query_confirm = 0;
+                                       
+                               }                               
+                               
+                               if ($http_query_confirm eq 1){
+                               
+                                       # The action to edit the user has been confirmed so collect
+                                       # the information needed for the xestiascan_users_edit
+                                       # subroutine.
+                                       
+                                       use Hash::Search;
+                                       my $hs = new Hash::Search;
+                                       my %http_userinfo;
+                                       my %form_data = $query_lite->parse_form_data();
+                                       
+                                       my $confirm                             = $form_data->{'confirm'};
+                                       $http_userinfo{'OriginalUsername'}      = $form_data->{'username_original'};
+                                       $http_userinfo{'NewUsername'}           = $form_data->{'username'};
+                                       $http_userinfo{'Name'}                  = $form_data->{'name'};
+                                       $http_userinfo{'Password'}              = $form_data->{'password'};
+                                       $http_userinfo{'ConfirmPassword'}       = $form_data->{'confirmpassword'};
+                                       $http_userinfo{'Admin'}                 = $form_data->{'admin'};
+                                       $http_userinfo{'Enabled'}               = $form_data->{'enabled'};
+                                       
+                                       # Get the list of scanners from the query.
+                                       
+                                       $hs->hash_search("^scanner_", %form_data);
+                                       my %http_scanner = $hs->hash_search_resultdata;
+                                       
+                                       # Get the list of output modules from the query.
+                                       
+                                       $hs->hash_search("^outputmodule_", %form_data);
+                                       my %http_outputmodules = $hs->hash_search_resultdata;
+                                       
+                                       # Get the list of export modules from the query.
+                                       
+                                       $hs->hash_search("^exportmodule_", %form_data);
+                                       my %http_exportmodules = $hs->hash_search_resultdata;
+                                       
+                                       my $pagedata = xestiascan_users_edit($http_userinfo{OriginalUsername}, \%http_userinfo, \%http_scanner, \%http_outputmodules, \%http_exportmodules, $confirm);
+                                       
+                                       xestiascan_output_header;       # Output the header to browser/console/stdout;
+                                       xestiascan_output_page($xestiascan_lang{users}{edituser}, $pagedata, "users");  # Output the page to browser/console/stdout;
+                                       exit;                           # End the script.                                       
+                                       
+                               }
+                               
+                               my $pagedata = xestiascan_users_edit($http_query_username);
+                               
+                               xestiascan_output_header;       # Output the header to browser/console/stdout;
+                               xestiascan_output_page($xestiascan_lang{users}{edituser}, $pagedata, "users");  # Output the page to browser/console/stdout;
+                               exit;                           # End the script.                               
+                               
+                       } elsif ($http_query_action eq "delete"){
+
+                               my $http_query_confirm  = $form_data->{'confirm'};
+                               my $http_query_username = $form_data->{'user'};
+                               
+                               if (!$http_query_confirm){
+                                       
+                                       # The http_query_confirm variable is uninitialised, so place a
+                                       # '0' (meaning an unconfirmed action).
+                                       
+                                       $http_query_confirm = 0;
+                                       
+                               }
+                               
+                               if ($http_query_confirm eq 1){
+                               
+                                       # The action to delete a user has been confirmed.
+                                       
+                                       my $pagedata = xestiascan_users_delete($http_query_username, $http_query_confirm);
+                                       
+                                       xestiascan_output_header;       # Output the header to browser/console/stdout;
+                                       xestiascan_output_page($xestiascan_lang{users}{deleteuser}, $pagedata, "users");        # Output the page to browser/console/stdout;
+                                       exit;                           # End the script.
+                                       
+                               }
+                               
+                               my $pagedata = xestiascan_users_delete($http_query_username);
+                               
+                               xestiascan_output_header;       # Output the header to browser/console/stdout;
+                               xestiascan_output_page($xestiascan_lang{users}{deleteuser}, $pagedata, "users");        # Output the page to browser/console/stdout;
+                               exit;                           # End the script.
+                               
+                       } elsif ($http_query_action eq "flush"){
+                               
+                               my $http_query_confirm = $form_data->{'confirm'};
+                               
+                               $http_query_confirm = 0 if !$http_query_confirm;
+                               
+                               my $pagedata = xestiascan_users_flush($http_query_confirm);
+                               
+                               xestiascan_output_header;       # Output the header to browser/console/stdout;
+                               xestiascan_output_page($xestiascan_lang{users}{logoutallusers}, $pagedata, "users");    # Output the page to browser/console/stdout;
+                               exit;                           # End the script.
+                               
+                       } else {
+               
+                               # The action specified was something else other than those
+                               # above, so return an error.
+               
+                               xestiascan_error("invalidaction");
+
+                       }               
+
+               }               
+
+               my $showdeactivated = 0;
+
+               if ($form_data->{'showdeactivated'} && $form_data->{'showdeactivated'} eq "on"){
+                       
+                       $showdeactivated = 1;
+
+               }
+
+               my $pagedata = xestiascan_users_list({ ShowDeactivatedUsers => $showdeactivated });
+
+               xestiascan_output_header;       # Output the header to browser/console/stdout;
+               xestiascan_output_page($xestiascan_lang{users}{userslist}, $pagedata, "users"); # Output the page to browser/console/stdout;
+               exit;                           # End the script.
+
+       } elsif ($http_query_mode eq "settings"){
+
+               use Modules::System::Settings;
+
+               if ($form_data->{'action'}){
+                       my $http_query_action = $form_data->{'action'};
+               
+                       if ($http_query_action eq "edit"){
+               
+                               # The action specified is to edit the settings. Check if the action
+                               # to edit the settings has been confirmed.
+               
+                               my $http_query_confirm = $form_data->{'confirm'};
+               
+                               if (!$http_query_confirm){
+               
+                                       # The confirm value is blank, so set it to 0.
+               
+                                       $http_query_confirm = 0;
+               
+                               }
+               
+                               if ($http_query_confirm eq 1){
+               
+                                       # The action to edit the settings has been confirmed. Get the
+                                       # required settings from the HTTP query.
+               
+                                       my $http_query_imagesuri        = $form_data->{'imagesuripath'};
+                                       my $http_query_scansuri         = $form_data->{'scansuripath'};
+                                       my $http_query_scansfs          = $form_data->{'scansfspath'};
+                                       my $http_query_datetimeformat   = $form_data->{'datetime'};
+                                       my $http_query_systemlanguage   = $form_data->{'language'};
+                                       my $http_query_presmodule       = $form_data->{'presmodule'};
+                                       my $http_query_authmodule       = $form_data->{'authmodule'};
+                                       my $http_query_outputmodule     = $form_data->{'outputmodule'};
+               
+                                       my $http_query_database_server          = $form_data->{'database_server'};
+                                       my $http_query_database_port            = $form_data->{'database_port'};
+                                       my $http_query_database_protocol        = $form_data->{'database_protocol'};
+                                       my $http_query_database_sqldatabase     = $form_data->{'database_sqldatabase'};
+                                       my $http_query_database_username        = $form_data->{'database_username'};
+                                       my $http_query_database_passwordkeep    = $form_data->{'database_password_keep'};
+                                       my $http_query_database_password        = $form_data->{'database_password'};
+                                       my $http_query_database_tableprefix     = $form_data->{'database_tableprefix'};
+               
+                                       my $pagedata = xestiascan_settings_edit({ ImagesURIPath => $http_query_imagesuri, ScansURIPath => $http_query_scansuri, ScansFSPath => $http_query_scansfs, DateTimeFormat => $http_query_datetimeformat, SystemLanguage => $http_query_systemlanguage, PresentationModule => $http_query_presmodule, OutputModule => $http_query_outputmodule, AuthModule => $http_query_authmodule, DatabaseServer => $http_query_database_server, DatabasePort => $http_query_database_port, DatabaseProtocol => $http_query_database_protocol, DatabaseSQLDatabase => $http_query_database_sqldatabase, DatabaseUsername => $http_query_database_username, DatabasePasswordKeep => $http_query_database_passwordkeep, DatabasePassword => $http_query_database_password, DatabaseTablePrefix => $http_query_database_tableprefix, Confirm => 1 });
+               
+                                       xestiascan_output_header;       # Output the header to browser/console/stdout.
+                                       xestiascan_output_page($xestiascan_lang{setting}{editsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
+                                       exit;                           # End the script.
+               
+                               }
+               
+                               # The action to edit the settings has not been confirmed.
+               
+                               my $pagedata = xestiascan_settings_edit();
+               
+                               xestiascan_output_header;       # Output the header to browser/console/stdout.
+                               xestiascan_output_page($xestiascan_lang{setting}{editsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
+                               exit;                           # End the script.
+               
+                       } else {
+               
+                               # The action specified was something else other than those
+                               # above, so return an error.
+               
+                               xestiascan_error("invalidaction");
+               
+                       }
+               
+               }
+               
+               # No action has been specified, so print out the list of settings currently being used.
+               
+               my $pagedata = xestiascan_settings_view();
+               
+               xestiascan_output_header;               # Output the header to browser/console/stdout.
+               xestiascan_output_page($xestiascan_lang{setting}{viewsettings}, $pagedata, "settings"); # Output the page to browser/console/stdout.
+               exit;                                   # End the script.
+
+       } elsif ($http_query_mode eq "logout"){
+               
+               # The mode selected is to logout the user.
+               
+               my $pagedata = xestiascan_auth_logout();
+               
+               xestiascan_output_header("cookie_logout");      # Output the header to browser/console/stdout.
+               xestiascan_output_page($xestiascan_lang{setting}{logout}, $pagedata, "settings");       # Output the page to browser/console/stdout.
+               exit;                                           # End the script.
+               
+       } else {
+
+               # An invalid mode has been specified so return
+               # an error.
+
+               xestiascan_error("invalidmode");
+
+       }
+       
+} else {
+
+       # No mode has been specified, so print the default "first-run" view of the
+       # scanning setup.
+
+       use Modules::System::Scan;
+               
+       my $pagedata = xestiascan_scan_preview();
+
+       # Output the header to browser/console/stdout.
+
+       if ($print_cookie eq 1){
+               xestiascan_output_header("cookie", $auth_username, $auth_seed, $cookie_expirestime);
+       } else {
+               xestiascan_output_header;
+       }
+
+       xestiascan_output_page($xestiascan_lang{scan}{scanconfig}, $pagedata, "database");      # Output the page to browser/console/stdout.
+       exit;   # End the script.
+       
+}
+
+__END__
\ No newline at end of file
diff --git a/misc/dbspec.txt b/misc/dbspec.txt
new file mode 100644 (file)
index 0000000..ab8a58d
--- /dev/null
@@ -0,0 +1,60 @@
+User table
+==========
+
+uid autonumber
+username text(64)
+password memo (SHA512)
+name text(128)
+admin boolean
+deactivated
+
+create table xestiascan_users (
+uid SERIAL PRIMARY KEY,
+username varchar(64) UNIQUE NOT NULL,
+salt varchar(512) NOT NULL,
+password text NOT NULL,
+name varchar(128) NOT NULL,
+admin boolean NOT NULL,
+enabled boolean NOT NULL
+);
+
+Access Scanner table
+====================
+
+uid (linked to user table)
+scannerid text(256)
+enabled boolean
+
+create table xestiascan_scanners (
+uid bigint NOT NULL,
+scannerid varchar(256) NOT NULL,
+enabled boolean NOT NULL
+);
+
+Access Module table
+===================
+
+uid (linked to user table)
+moduletype text(12)
+modulename text(256)
+enabled boolean
+
+create table xestiascan_modules(
+uid bigint NOT NULL,
+moduletype varchar(12) NOT NULL,
+modulename varchar(256) NOT NULL,
+enabled boolean NOT NULL
+);
+
+Sessions table
+==============
+
+seed text(32) unique primary key not null,
+username memo NOT NULL,
+expires datetime NOT NULL
+
+create table xestiascan_sessions(
+seed varchar(32) UNIQUE PRIMARY KEY NOT NULL,
+username text NOT NULL,
+expires timestamp NOT NULL
+);
\ No newline at end of file
diff --git a/non-cgi-files/images/menutop.png b/non-cgi-files/images/menutop.png
new file mode 100755 (executable)
index 0000000..f824861
Binary files /dev/null and b/non-cgi-files/images/menutop.png differ
diff --git a/non-cgi-files/images/pagebackground.png b/non-cgi-files/images/pagebackground.png
new file mode 100755 (executable)
index 0000000..82053eb
Binary files /dev/null and b/non-cgi-files/images/pagebackground.png differ
diff --git a/non-cgi-files/images/scannertop.png b/non-cgi-files/images/scannertop.png
new file mode 100755 (executable)
index 0000000..970b9f1
Binary files /dev/null and b/non-cgi-files/images/scannertop.png differ
diff --git a/non-cgi-files/images/sectiontop.png b/non-cgi-files/images/sectiontop.png
new file mode 100755 (executable)
index 0000000..40d94d1
Binary files /dev/null and b/non-cgi-files/images/sectiontop.png differ
diff --git a/non-cgi-files/images/tabletop.png b/non-cgi-files/images/tabletop.png
new file mode 100755 (executable)
index 0000000..83a4436
Binary files /dev/null and b/non-cgi-files/images/tabletop.png differ
Xestia Software Development
Yn Maystri
© 2006 - 2019 Xestia Software Development
Software

Xestia Address Book
Xestia Calendar
Development

Xestia Gelforn
Everything else

About
News
Privacy Policy