<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.signature.net/skins/common/feed.css?270"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.signature.net/index.php?feed=atom&amp;target=Justin&amp;title=Special%3AContributions%2FJustin</id>
		<title>CometWiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.signature.net/index.php?feed=atom&amp;target=Justin&amp;title=Special%3AContributions%2FJustin"/>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Special:Contributions/Justin"/>
		<updated>2026-04-19T00:25:49Z</updated>
		<subtitle>From CometWiki</subtitle>
		<generator>MediaWiki 1.16.0</generator>

	<entry>
		<id>http://wiki.signature.net/index.php/Mnemonics_%22E%22</id>
		<title>Mnemonics &quot;E&quot;</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Mnemonics_%22E%22"/>
				<updated>2026-01-26T22:53:25Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==(Easy Scan)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Mnemonic''':    (Easy Scan)  Hex equivalent:  &amp;quot;@0E0000@&amp;quot;  &lt;br /&gt;
&lt;br /&gt;
'''Discussion''':  The (Easy Scan) mnemonic places the Comet console into &amp;quot;easy scan&amp;quot; mode.&amp;lt;br&amp;gt;&lt;br /&gt;
(This mnemonic does not apply to QTerm or terminals.) &amp;lt;br&amp;gt;&lt;br /&gt;
In &amp;quot;easy scan&amp;quot; mode, if the user presses one of the recognized keys while the program is at an INPUT prompt, the program responds as if an F10, Enter, or Tab key was pressed.&amp;lt;br&amp;gt;&lt;br /&gt;
In combination with the returned screen coordinates (see INPUT), this feature allows for an enriched style of screen I/O programming. &lt;br /&gt;
&lt;br /&gt;
In addition, if the mouse driver is active (see the (Mouse On) mnemonic), a mouse click also generates a transmit, and places the cursor's coordinates in the status buffer (see Example 2).&amp;lt;br&amp;gt; &lt;br /&gt;
Starting with Comet98 Build 232, (Easy Scan) turns the mouse on if it is not already being done. &lt;br /&gt;
&lt;br /&gt;
The (Scan Codes Off) mnemonic terminates &amp;quot;easy scan&amp;quot; mode. &lt;br /&gt;
&lt;br /&gt;
The &amp;quot;reason for transmit&amp;quot; information is stored in the 8th byte of the console's status buffer, and is stored in hex.&amp;lt;br&amp;gt; &lt;br /&gt;
To determine which key (or click) caused the transmit to occur, perform the following operation: &lt;br /&gt;
&lt;br /&gt;
VALUE = ASC(SUB(STS(0),8,1)) &lt;br /&gt;
&lt;br /&gt;
'''Note:''' VALUE is a numeric field with length/precision of 3.0. &lt;br /&gt;
&lt;br /&gt;
The following values are returned: &lt;br /&gt;
&lt;br /&gt;
Value Key that caused the transmit to occur &lt;br /&gt;
*4 Up arrow &lt;br /&gt;
*5 Down arrow &lt;br /&gt;
*6 Left mouse click &lt;br /&gt;
*7 Ctrl + Home &lt;br /&gt;
*8 Ctrl + End &lt;br /&gt;
*9 Pg Up &lt;br /&gt;
*10 Ctrl + Pg Up &lt;br /&gt;
*11 Pg Dn &lt;br /&gt;
*12 Ctrl + Pg Dn &lt;br /&gt;
*14 Right mouse click &lt;br /&gt;
*15 Window caption bar &amp;quot;X&amp;quot; was clicked. '''See''' (CreateWindowEx).  &lt;br /&gt;
*16 ?&lt;br /&gt;
*17 X1 mouse click (usually side 'back' button)&lt;br /&gt;
*18 X2 mouse click (usually side 'forward' button)&lt;br /&gt;
*19 Mouse wheel scroll 'back'&lt;br /&gt;
*20 Mouse wheel scroll 'forward'&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Values 1, 2, and 3 are generated via the INPUT statement, and do not require the (Easy Scan) mnemonic. &lt;br /&gt;
 &lt;br /&gt;
'''History:'''  The (Easy Scan) mnemonic was added in Comet version 504.208 as part of the enhanced INPUT statement. &amp;lt;br&amp;gt;&lt;br /&gt;
Values 7 through 12 were added in Comet 504.228 and Comet98 Build 228. &lt;br /&gt;
&lt;br /&gt;
Starting with Comet98 Build 232, (EasyScan) turns the mouse on if it is not already being done. &amp;lt;br&amp;gt;&lt;br /&gt;
If it is already on, it is assumed the whoever turned it on will also turn it off. &lt;br /&gt;
&lt;br /&gt;
Starting with Build 292, (EasyScan) disables any scan modes that are currently enabled. &lt;br /&gt;
&lt;br /&gt;
Value 14 was added in Build 294. &lt;br /&gt;
&lt;br /&gt;
As of Build 294, (EasyScan) mouse clicks now occur on the up-click instead of the down-click.&amp;lt;br&amp;gt; &lt;br /&gt;
This is consistent with other Windows applications. &lt;br /&gt;
&lt;br /&gt;
Value 15 was added in Comet2002 Build 306. &lt;br /&gt;
&lt;br /&gt;
Values 17-20 were added in Comet 542.&lt;br /&gt;
&lt;br /&gt;
Example 1:  &lt;br /&gt;
 PRINT (0) (Mouse On)           ! Mouse on (optional)&lt;br /&gt;
 .&lt;br /&gt;
 PRINT (0) (Easy Scan)          ! Easy scan mode on&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 INPUT (0) DATA$                ! Input a field&lt;br /&gt;
 .&lt;br /&gt;
 VALUE = ASC(SUB(STS(0),8,1))   ! Reason for transmit&lt;br /&gt;
 .&lt;br /&gt;
 IF VALUE = 1 ...               ! F10 key&lt;br /&gt;
 IF VALUE = 2 ...               ! Enter key&lt;br /&gt;
 IF VALUE = 3 ...               ! Tab key&lt;br /&gt;
 IF VALUE = 4 ...               ! Up arrow&lt;br /&gt;
 IF VALUE = 5 ...               ! Down arrow&lt;br /&gt;
 IF VALUE = 6 ...               ! Left mouse click&lt;br /&gt;
 IF VALUE = 7 ...               ! Ctrl + Home&lt;br /&gt;
 IF VALUE = 8 ...               ! Ctrl + End&lt;br /&gt;
 IF VALUE = 9 ...               ! Pg Up&lt;br /&gt;
 IF VALUE = 10 ...              ! Ctrl + Pg Up&lt;br /&gt;
 IF VALUE = 11 ...              ! Pg Dn&lt;br /&gt;
 IF VALUE = 12 ...              ! Ctrl + Pg Dn&lt;br /&gt;
 IF VALUE = 14 ...              ! Right mouse click&lt;br /&gt;
 IF VALUE = 15 ...              ! Window caption bar &amp;quot;X&amp;quot;&lt;br /&gt;
 IF VALUE = 17 ...              ! X1 mouse click (usually side 'back' button)&lt;br /&gt;
 IF VALUE = 18 ...              ! X2 mouse click (usually side 'forward' button)&lt;br /&gt;
 IF VALUE = 19 ...              ! Mouse wheel scroll 'back'&lt;br /&gt;
 IF VALUE = 20 ...              ! Mouse wheel scroll 'forward'&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 PRINT (0) (ScanCodesOff)       ! Easy scan mode off&lt;br /&gt;
 PRINT (0) (Mouse Off)          ! Mouse off (optional)&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
'''Example 2:'''  &lt;br /&gt;
 Data$ = Sub(Sts(0), 1, 254)    ! Get console status&lt;br /&gt;
 J = Asc(Sub(Data$, 8, 1))      ! Get reason for transmit&lt;br /&gt;
 If (J EQ 6)                    ! Mouse was clicked&lt;br /&gt;
  Row = Asc(Sub(Data$, 15, 1)) ! Get the row&lt;br /&gt;
  Col = Asc(sub(Data$, 16, 1)) ! Get the column&lt;br /&gt;
 Endif&lt;br /&gt;
&lt;br /&gt;
This example shows how to determine the cursor's coordinates when the mouse is clicked.&lt;br /&gt;
&lt;br /&gt;
==(Ellipse)==&lt;br /&gt;
'''Mnemonic''':   (Ellipse=left, top, right, bottom)  &lt;br /&gt;
&lt;br /&gt;
'''Discussion''':  This mnemonic draws an ellipse. &lt;br /&gt;
The center of the ellipse is the center of the bounding rectangle specified by left, top, right, bottom. &amp;lt;br&amp;gt;&lt;br /&gt;
The ellipse is drawn with the current pen, and its interior is filled with the current brush.&amp;lt;br&amp;gt; &lt;br /&gt;
The figure drawn by this function extends up to, but does not include, the right and bottom coordinates.&amp;lt;br&amp;gt;&lt;br /&gt;
This means that the height of the figure is bottom - top and the width of the figure is right - left.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
If either the width or the height of the bounding rectangle is 0, no ellipse is drawn. &lt;br /&gt;
 &lt;br /&gt;
'''History:'''  This mnemonic is valid in Comet98 and greater&lt;br /&gt;
&lt;br /&gt;
== (EmailDocument) ==&lt;br /&gt;
'''Email Mnemonic:'''   (EmailDocument=string-argument)  &lt;br /&gt;
&lt;br /&gt;
'''Discussion:'''  The (EmailDocument) mnemonic may be used to specify the name associated with an attachment file. If an extension is not assigned, one appropriate for the file type will automatically be included (.pdf, .htm, etc). If this mnemonic is not used, the attachment will carry the default name assigned to the document.  &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Example: &lt;br /&gt;
 OPEN (1) &amp;quot;LEH&amp;quot;&lt;br /&gt;
 PRINT (1) (EmailDocument=&amp;quot;OrderDetails&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==  Email printer mnemonics ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|Mnemonic &lt;br /&gt;
| Description  &lt;br /&gt;
|-&lt;br /&gt;
|(Server = SMTPServerName$) &lt;br /&gt;
| Specify SMTP server name and port  &lt;br /&gt;
|-&lt;br /&gt;
|(Domain = Domain$)  &lt;br /&gt;
|Specify email domain name  &lt;br /&gt;
|-&lt;br /&gt;
|(From = FromAddr$) &lt;br /&gt;
| Specify sender's name and address  &lt;br /&gt;
|-&lt;br /&gt;
|(To = ToAddr$)  &lt;br /&gt;
|Specify recipient's name and address  &lt;br /&gt;
|-&lt;br /&gt;
|(CC = CCaddr$)  &lt;br /&gt;
|Specify CC recipient's name and address  &lt;br /&gt;
|-&lt;br /&gt;
|(BCC = BCCaddr$)  &lt;br /&gt;
|Specify BCC recipient's name and address  &lt;br /&gt;
|-&lt;br /&gt;
|(Subject = Subject$)  &lt;br /&gt;
|Specify message's subject line  &lt;br /&gt;
|-&lt;br /&gt;
|(Text = Text$)  &lt;br /&gt;
|Specify a line of body text  &lt;br /&gt;
|-&lt;br /&gt;
|(EmailDocument = Name$) &lt;br /&gt;
| Specify a name for the attachment  &lt;br /&gt;
|-&lt;br /&gt;
|(Log = LogFile$,LogDir$,ERASE)  &lt;br /&gt;
|Specify a log file name and erase parameter  &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
Discussion of the Email Printer (requires access to web site) &lt;br /&gt;
&lt;br /&gt;
Read about other Email Mnemonics&lt;br /&gt;
&lt;br /&gt;
== (EN) ==&lt;br /&gt;
&lt;br /&gt;
'''Mnemonic:'''   (EN)  &lt;br /&gt;
&lt;br /&gt;
'''Hex equivalent:'''  &amp;quot;@0E06@&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
'''Discussion:'''  Enter normal mode.&amp;lt;br&amp;gt; &lt;br /&gt;
The (EN) control code sets the video display in normal mode.&amp;lt;br&amp;gt; &lt;br /&gt;
The location of displayed information, the placement of the cursor, and the places where data is transmitted are determined by the FORMAT statements in the program. &lt;br /&gt;
&lt;br /&gt;
The alternative to normal mode is typewriter mode. &lt;br /&gt;
 &lt;br /&gt;
'''Example:  a'''.&lt;br /&gt;
  100 FORMAT (EN);(SB);&amp;quot;CUSTOMER INQUIRY&amp;quot;,@(10,0)&lt;br /&gt;
   .&lt;br /&gt;
   PRINT (0,100)&lt;br /&gt;
&lt;br /&gt;
'''Example b.'''&lt;br /&gt;
  PRINT (0) (EN);(SB);&amp;quot;CUSTOMER INQUIRY&amp;quot;,@(10,0)&lt;br /&gt;
&lt;br /&gt;
This example shows how to set normal mode, either at the beginning of a FORMAT statement or within a PRINT statement. &amp;lt;br&amp;gt;&lt;br /&gt;
The additional controls set background mode and display a heading at column 10, row 0.&lt;br /&gt;
&lt;br /&gt;
== (Enable Close) ==&lt;br /&gt;
&lt;br /&gt;
'''Mnemonic:'''  (EnableClose = Arg) &lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
Arg = 0 – Disable [X] on main view window (If [X] is clicked the message: &amp;quot;Close has been disabled by the currently running program&amp;quot; will be displayed)&lt;br /&gt;
&lt;br /&gt;
Arg = 1 – Enable [X] on main view window if disable count reaches 0 (see discussion below)&lt;br /&gt;
&lt;br /&gt;
Arg = &amp;lt;anyothervalue&amp;gt; – Reset count and enable [X] on main view window&lt;br /&gt;
&lt;br /&gt;
'''Discussion''':  Enables or disables the [X] close button at the top of a main Comet Window. Due to the possibility of nested programs calling this mnemonic, Comet will maintain a count of the number of “disables” issued. Only when the disable count reaches 0 will the close button be enabled. If a value other than 0 or 1 is issued then the disable count will be forced to 0 and the close button will be enabled. This mnemonic requires at minimum Comet build 451 and REL version 11.10.&lt;br /&gt;
 &lt;br /&gt;
'''Example:'''&lt;br /&gt;
  Print (EnableClose = 0)   ! Disable [X] button while processing&lt;br /&gt;
 .&lt;br /&gt;
 . ! Perform uninterrupted processing&lt;br /&gt;
 .&lt;br /&gt;
  Print (EnableClose = 1)   ! Done - Enable [X] button&lt;br /&gt;
&lt;br /&gt;
== (End Metafile) ==&lt;br /&gt;
&lt;br /&gt;
'''Mnemonic:'''  (EndMetafile = flags) &lt;br /&gt;
 &lt;br /&gt;
'''Discussion''':  End the metafile collection process by saving and/or executing the currently active MetaFile. &lt;br /&gt;
&lt;br /&gt;
Where flags indicate: &lt;br /&gt;
&lt;br /&gt;
VMF.SAVE = 0    ! Save the file - do not execute&amp;lt;br&amp;gt;&lt;br /&gt;
VMF.EXECUTE	= 1 ! Execute the metafile&lt;br /&gt;
&lt;br /&gt;
== (EndWaitCursor) ==&lt;br /&gt;
 &lt;br /&gt;
'''Mnemonic''':  (EndWaitCursor)  &lt;br /&gt;
&lt;br /&gt;
'''Discussion:'''  This mnemonic turns off the hourglass cursor. &lt;br /&gt;
&lt;br /&gt;
'''See''' (BeginWaitCursor) and (RestoreWaitCursor). &lt;br /&gt;
 &lt;br /&gt;
'''Example:'''&lt;br /&gt;
  Print (BeginWaitCursor)&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 Print (EndWaitCursor)&lt;br /&gt;
&lt;br /&gt;
== (Enhanced Mouse On) ==&lt;br /&gt;
 &lt;br /&gt;
'''Mnemonic:'''   (Enhanced Mouse On) &lt;br /&gt;
 &lt;br /&gt;
'''Hex equivalent:'''  &amp;quot;@0E0906@&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
'''Discussion:'''  This control opens the enhanced mouse driver (if possible).&lt;br /&gt;
 &lt;br /&gt;
'''Also see''' (BIOS Mouse On) and (Mouse On). &lt;br /&gt;
 &lt;br /&gt;
'''Example:  a.'''&lt;br /&gt;
 100 FORMAT (Enhanced Mouse On)&lt;br /&gt;
   .&lt;br /&gt;
   PRINT (0,100)&lt;br /&gt;
&lt;br /&gt;
'''Example b'''&lt;br /&gt;
   PRINT (0) (Enhanced Mouse On&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[[Enhanced Printing]]==&lt;br /&gt;
&lt;br /&gt;
Link to Enhanced Printing Summary&lt;br /&gt;
&lt;br /&gt;
== (ET) ==&lt;br /&gt;
&lt;br /&gt;
'''Mnemonic:'''   (ET)  &lt;br /&gt;
&lt;br /&gt;
'''Hex equivalent:'''  &amp;quot;@0E05@&amp;quot; &lt;br /&gt;
 &lt;br /&gt;
'''Discussion:'''  Enter typewriter mode. &amp;lt;br&amp;gt;&lt;br /&gt;
The (ET) control code sets the video display in typewriter mode.&amp;lt;br&amp;gt; &lt;br /&gt;
Each new line of data written to the screen causes the screen to scroll up one line. &amp;lt;br&amp;gt;&lt;br /&gt;
The new line of data is written on the bottom line of the screen in background mode. &lt;br /&gt;
&lt;br /&gt;
Transmit marks are automatically placed after the last byte of data written and at the lower right corner of the screen (making the remaining part of the bottom line the foreground data entry field). &lt;br /&gt;
&lt;br /&gt;
The cursor is placed at the left-most position of the foreground field on the bottom line. &lt;br /&gt;
&lt;br /&gt;
The alternative to typewriter mode is normal mode. &lt;br /&gt;
 &lt;br /&gt;
'''Example:  a.''' &lt;br /&gt;
  100 FORMAT (ET)&lt;br /&gt;
   .&lt;br /&gt;
   PRINT (0,100)&lt;br /&gt;
   PRINT (0) &amp;quot;ENTER CUSTOMER NUMBER:&amp;quot;&lt;br /&gt;
   INPUT (0) CUSTNUM$&lt;br /&gt;
&lt;br /&gt;
'''Example b.''' &lt;br /&gt;
   PRINT (0) (ET)&lt;br /&gt;
   PRINT (0) &amp;quot;ENTER CUSTOMER NUMBER:&amp;quot;&lt;br /&gt;
   INPUT (0) CUSTNUM$&lt;br /&gt;
&lt;br /&gt;
In this example, the screen is placed into typewriter mode. &amp;lt;br&amp;gt;&lt;br /&gt;
Then a prompt is displayed and data is accepted into the variable named CUSTNUM$. &amp;lt;br&amp;gt;&lt;br /&gt;
Items such as foreground, background and transmit marks are handled automatically.&lt;br /&gt;
&lt;br /&gt;
== (EraseFile) ==&lt;br /&gt;
 &lt;br /&gt;
'''Mnemonic:'''  (EraseFile=file,flags) &lt;br /&gt;
 &lt;br /&gt;
'''Discussion:'''  The mnemonic erases a Windows file. &lt;br /&gt;
&lt;br /&gt;
This mnemonic may be used by foreground programs only. &lt;br /&gt;
&lt;br /&gt;
The file name is in Windows format, UNC format, or a directory alias. &lt;br /&gt;
&lt;br /&gt;
Flags is the sum of the specified decimal values from the following chart: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| Border=1&lt;br /&gt;
|Flag &lt;br /&gt;
|Description &lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Perform function on the server, CometAnywhere or not.&lt;br /&gt;
|-&lt;br /&gt;
|1 &lt;br /&gt;
|Perform function on the client, CometAnywhere or not. &lt;br /&gt;
|-&lt;br /&gt;
|2 &lt;br /&gt;
|Perform function for CometAnywhere only and perform it on the client. &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
After this mnemonic is issued, your program can issue an INPUT on LUN (0) to retrieve the error information. &lt;br /&gt;
&lt;br /&gt;
'''For example:''' &lt;br /&gt;
&lt;br /&gt;
  LENGTH 2 &amp;amp; LOCAL AX$,DX$&lt;br /&gt;
  LENGTH 254 &amp;amp; LOCAL RESULT$&lt;br /&gt;
  ResultFmt: FORMAT AX$;DX$;RESULT$&lt;br /&gt;
  .&lt;br /&gt;
  .&lt;br /&gt;
  Print (EraseFile=File$,Flags)&lt;br /&gt;
  Input (0,ResultFmt)&lt;br /&gt;
 .&lt;br /&gt;
 The first field, AX$, contains the function error code, and the second field, DX$, contains the suberror code (aka the Windows file error code).&lt;br /&gt;
 Both of these fields are in Intel 2's complement format, and should be processed as follows: &lt;br /&gt;
  AX$ = SUB(AX$,2,1) + SUB(AX$,1,1)   ! Flip the bytes around&lt;br /&gt;
  DX$ = SUB(DX$,2,1) + SUB(DX$,1,1)   ! Flip the bytes around&lt;br /&gt;
  FuncError = HexDec(AX$)             ! Function error code (decimal)&lt;br /&gt;
  FileError = HexDec(DX$)             ! File error code (decimal)&lt;br /&gt;
 .&lt;br /&gt;
  ! For unexpected values, convert to 2's complement signed integer&lt;br /&gt;
  If (FuncError &amp;gt; 32767) FuncError = FuncError-65536&lt;br /&gt;
  If (FileError &amp;gt; 32767) FileError = FileError-65536&lt;br /&gt;
&lt;br /&gt;
Here is a list of the function error codes in decimal form: &lt;br /&gt;
&lt;br /&gt;
'''Error'''&lt;br /&gt;
{| Border=1&lt;br /&gt;
|(FuncError)&lt;br /&gt;
| Description &lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
| Function not supported &lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
| Success &lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| CometAnywhere required &lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| Source file error (see suberrors) &lt;br /&gt;
|4 &lt;br /&gt;
|Aborted by user &lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
| Function in progress &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Here is a list of the suberror codes (common Windows file errors) in decimal form: &lt;br /&gt;
&lt;br /&gt;
'''Suberror'''&lt;br /&gt;
{| Border=1&lt;br /&gt;
|(FileError)&lt;br /&gt;
| Description &lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
| Success &lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
| File not found &lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
| Path not found &lt;br /&gt;
|-&lt;br /&gt;
|5 &lt;br /&gt;
|Access denied &lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Invalid access &lt;br /&gt;
|-&lt;br /&gt;
|15 &lt;br /&gt;
|Invalid drive &lt;br /&gt;
|-&lt;br /&gt;
|16 &lt;br /&gt;
|An error has occurred in the current directory &lt;br /&gt;
|-&lt;br /&gt;
|18 &lt;br /&gt;
|No more files &lt;br /&gt;
|-&lt;br /&gt;
|32 &lt;br /&gt;
|Sharing violation &lt;br /&gt;
|-&lt;br /&gt;
|33 &lt;br /&gt;
|Lock violation &lt;br /&gt;
|-&lt;br /&gt;
|80 &lt;br /&gt;
|File exists &lt;br /&gt;
|-&lt;br /&gt;
|161 &lt;br /&gt;
|Bad pathname &lt;br /&gt;
|-&lt;br /&gt;
|} &lt;br /&gt;
'''History:'''  This mnemonic was added in Comet Build 299 and REL Version 01.07.&lt;br /&gt;
&lt;br /&gt;
== Execute Metafile ==&lt;br /&gt;
 &lt;br /&gt;
'''Mnemonic:'''  (ExecuteMetafile = FileName)  &lt;br /&gt;
&lt;br /&gt;
'''Discussion:'''  Executes the previously saved metafile FileName.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION</id>
		<title>New Winsock Gateway Control - CERT-VALIDATION</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION"/>
				<updated>2025-03-29T01:26:03Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New Winsock Gateway (TCP Device) Control - CERT-VALIDATION ==&lt;br /&gt;
&lt;br /&gt;
As of Comet release 540, a new '''CERT-VALIDATION''' control has been added to the Winsock gateway (TCP Device) for managing SSL certificate verification. This control determines how the gateway handles certificates from the host.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
'''CERT-VALIDATION''', like '''SSL-ENABLE''', must be set before connecting to the remote server.&lt;br /&gt;
&lt;br /&gt;
==== Syntax ====&lt;br /&gt;
&lt;br /&gt;
result$ = control(LUN, &amp;quot;CERT-VALIDATION value&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
&lt;br /&gt;
*'''VERIFY'''&lt;br /&gt;
*'''VERIFY-AND-ASK''' (default)&lt;br /&gt;
*'''DONOT-VERIFY'''&lt;br /&gt;
&lt;br /&gt;
If not specified, or the control is not issued, the default behavior is '''VERIFY-AND-ASK'''.&lt;br /&gt;
&lt;br /&gt;
==== Options ====&lt;br /&gt;
&lt;br /&gt;
 VERIFY&lt;br /&gt;
&lt;br /&gt;
Ensures the certificate is valid before connecting. The connection will fail if verification fails, preventing connections with invalid or broken certificates (recommended for security).&lt;br /&gt;
&lt;br /&gt;
 VERIFY-AND-ASK (Default)&lt;br /&gt;
&lt;br /&gt;
Attempts verification and prompts the user if the certificate is invalid. This was the only behavior before Comet 540 and requires user confirmation before proceeding.&lt;br /&gt;
&lt;br /&gt;
 DONOT-VERIFY&lt;br /&gt;
&lt;br /&gt;
Skips verification, allowing connections even with invalid certificates. Useful for testing but not recommended for security reasons.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
For example, this code enables the SSL protocol, specifies that we will only accept valid certificates, then connects to the server:&lt;br /&gt;
&lt;br /&gt;
 open(LUN) &amp;quot;TCP&amp;quot; excp=tcperror&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;SSL-ENABLE&amp;quot;)&lt;br /&gt;
 print &amp;quot;&amp;lt;&amp;lt;&amp;quot;; result$&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;CERT-VALIDATION VERIFY&amp;quot;)&lt;br /&gt;
 print &amp;quot;&amp;lt;&amp;lt;&amp;quot;; result$&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;CONNECT example.com 443&amp;quot;, excp=tcperror)&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION</id>
		<title>New Winsock Gateway Control - CERT-VALIDATION</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION"/>
				<updated>2025-03-16T00:49:23Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New Winsock Gateway (TCP Device) Control - CERT-VALIDATION ==&lt;br /&gt;
&lt;br /&gt;
As of Comet release 540, a new '''CERT-VALIDATION''' control has been added to the Winsock gateway (TCP Device) for managing SSL certificate verification. This control determines how the gateway handles certificates from the host.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
'''CERT-VALIDATION''', like '''SSL-ENABLE''', must be set before connecting to the remote server.&lt;br /&gt;
&lt;br /&gt;
==== Syntax ====&lt;br /&gt;
&lt;br /&gt;
result$ = control(LUN, &amp;quot;CERT-VALIDATION value&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Options:&lt;br /&gt;
&lt;br /&gt;
*'''VERIFY'''&lt;br /&gt;
*'''VERIFY-AND-ASK''' (default)&lt;br /&gt;
*'''DONOT-VERIFY'''&lt;br /&gt;
&lt;br /&gt;
If not specified, or the control is not issued, the default behavior is '''VERIFY-AND-ASK'''.&lt;br /&gt;
&lt;br /&gt;
==== Options ====&lt;br /&gt;
&lt;br /&gt;
 VERIFY&lt;br /&gt;
&lt;br /&gt;
Ensures the certificate is valid before connecting. The connection will fail if verification fails, preventing connections with invalid or broken certificates (recommended for security).&lt;br /&gt;
&lt;br /&gt;
 VERIFY-AND-ASK (Default)&lt;br /&gt;
&lt;br /&gt;
Attempts verification and prompts the user if the certificate is invalid. This was the only behavior before Comet 540 and requires user confirmation before proceeding.&lt;br /&gt;
&lt;br /&gt;
 DONOT-VERIFY&lt;br /&gt;
&lt;br /&gt;
Skips verification, allowing connections even with invalid certificates. Useful for testing but not recommended for security reasons.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
For example, this code enables the SSL protocol, specifies that we will only accept valid certificates, then connects to the server:&lt;br /&gt;
&lt;br /&gt;
 open(LUN) &amp;quot;TCP&amp;quot; excp=tcperror&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;SSL-ENABLE&amp;quot;)&lt;br /&gt;
 print &amp;quot;&amp;lt;&amp;lt;&amp;quot;; strip(result$)&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;CERT-VALIDATION VERIFY&amp;quot;)&lt;br /&gt;
 print &amp;quot;&amp;lt;&amp;lt;&amp;quot;; strip(result$)&lt;br /&gt;
 &lt;br /&gt;
 result$ = control(LUN, &amp;quot;CONNECT example.com 443&amp;quot;, excp=tcperror)&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION</id>
		<title>New Winsock Gateway Control - CERT-VALIDATION</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_Winsock_Gateway_Control_-_CERT-VALIDATION"/>
				<updated>2025-03-16T00:43:23Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: Created page with &amp;quot;== New Winsock Gateway (TCP Device) Control - CERT-VALIDATION ==  A new CERT-VALIDATION control has been added to the winsock gateway (TCP Device) for managing SSL certificate ve...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New Winsock Gateway (TCP Device) Control - CERT-VALIDATION ==&lt;br /&gt;
&lt;br /&gt;
A new CERT-VALIDATION control has been added to the winsock gateway (TCP Device) for managing SSL certificate verification on the host side. Using this new control, you can tell the winsock gateway how to behave based on the certificate received from the host.&lt;br /&gt;
&lt;br /&gt;
=== Usage ===&lt;br /&gt;
&lt;br /&gt;
This control, like the SSL-ENABLE control, must be issued prior to connecting to the remote server. The syntax is as follows:&lt;br /&gt;
&lt;br /&gt;
 result$ = control(LUN, &amp;quot;CERT-VALIDATION value&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Where value can be one of three options:&lt;br /&gt;
&lt;br /&gt;
 VERIFY&lt;br /&gt;
 VERIFY-AND-ASK (default)&lt;br /&gt;
 DONOT-VERIFY&lt;br /&gt;
&lt;br /&gt;
If the CERT-VALIDATION control is not specified, the default behavior is VERIFY-AND-ASK.&lt;br /&gt;
&lt;br /&gt;
=== Options ===&lt;br /&gt;
&lt;br /&gt;
==== VERIFY ====&lt;br /&gt;
&lt;br /&gt;
 VERIFY &lt;br /&gt;
&lt;br /&gt;
This option ensures the certificate is valid before connecting. The connection will fail if verification fails.  This is the recommended setting for security, as the connection will not be allowed for invalid or broken certificates.&lt;br /&gt;
&lt;br /&gt;
==== VERIFY-AND-ASK ====&lt;br /&gt;
&lt;br /&gt;
 VERIFY-AND-ASK &lt;br /&gt;
&lt;br /&gt;
This is the default option, and was the only behavior prior to Comet release 540.&lt;br /&gt;
&lt;br /&gt;
Attempts verification and if there is an issue (invalid or broken certificate) Comet will pop up a message box asking the user if they wan to trust the certificate.  This option is good to ensure the user is aware if the certificate is invalid, but requires user interaction for the XAP program to continue.&lt;br /&gt;
&lt;br /&gt;
==== DONOT-VERIFY ====&lt;br /&gt;
&lt;br /&gt;
 DONOT-VERIFY&lt;br /&gt;
&lt;br /&gt;
Skips verification and allows connections even with invalid certificates.  This option can be useful for testing with invalid or broken certificates, but is not recommended for security reasons.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Main_Page</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Main_Page"/>
				<updated>2025-03-16T00:25:14Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Comet by Signature Systems, Inc.'''=&lt;br /&gt;
&lt;br /&gt;
* [[Getting Started With Comet]]&lt;br /&gt;
&lt;br /&gt;
* [[Subscription Benefits]]&lt;br /&gt;
&lt;br /&gt;
* [[Virtual Dongle]]&lt;br /&gt;
&lt;br /&gt;
* [[FAQs]]&lt;br /&gt;
&lt;br /&gt;
* [[CFILES - the replacement for DbMgr]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet Meetings]]&lt;br /&gt;
&lt;br /&gt;
* [[Configuration and Installation]]&lt;br /&gt;
&lt;br /&gt;
* [[Programming]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet32]]&lt;br /&gt;
&lt;br /&gt;
* [[STL Containers]]&lt;br /&gt;
&lt;br /&gt;
* [[Xap and Comet32]]&amp;lt;!-- Comment * [[CometAnywhere Mobile]] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Products]]&lt;br /&gt;
&lt;br /&gt;
* [[Utilities]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet Tips]]&lt;br /&gt;
&lt;br /&gt;
* [http://support.signature.net/ Support - Users Forum]&lt;br /&gt;
&lt;br /&gt;
* [[How to edit this Wiki]]&lt;br /&gt;
&lt;br /&gt;
* '''[http://cc.signature.net/guest/adduser Request ability to edit pages on this Wiki]'''&lt;br /&gt;
&lt;br /&gt;
*[[Comet And RDP]]&lt;br /&gt;
&lt;br /&gt;
* [[New XAP controls and File Upload]]&lt;br /&gt;
&lt;br /&gt;
* [[New Winsock Gateway Control - CERT-VALIDATION]]&lt;br /&gt;
&lt;br /&gt;
A hint from the old guy. The Wiki's text size is based on the browser's settings. In '''Firefox''' I set the minimum font size to 16.&lt;br /&gt;
&lt;br /&gt;
Tools &amp;gt;&amp;gt; Options &amp;gt;&amp;gt; Content &amp;gt;&amp;gt; Advanced. Minimum font size.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-14T18:36:31Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
As of Comet version 540, we have introduced new controls to enhance XAP’s support for form input arrays and file uploads. These controls are designed to improve data handling while maintaining backward compatibility. If you do not enable these new features, your existing programs will continue to function as they did in previous XAP versions, ensuring a seamless transition.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GET FILEDATA (XAP Control) ====&lt;br /&gt;
&lt;br /&gt;
Retrieve the data from an uploaded file inside an XAP program.&lt;br /&gt;
&lt;br /&gt;
When a file is uploaded to XAP using the '''type=&amp;quot;file&amp;quot;''' input attribute, the name is stored in the CGIFILE.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display an HTML input element to upload a file.  When a file is specified and submitted, the CGIFILE will contain:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE - filename.ext&lt;br /&gt;
&lt;br /&gt;
In order to retrieve the data from the upload, use the '''GET FILEDATA''' control to copy the file into a dynamic string:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;GET FILEDATA filename.ext&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
From here you can use something like '''PRINTFILE''' to save the data to the filesystem.&lt;br /&gt;
&lt;br /&gt;
Note, this method copies the entire file as a chunk of data into a dynamic string.  Be aware that large files could cause performance issues depending on usage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports HTML form input arrays. This allows multiple values to be submitted under the same field name and stored in an indexed array. This functionality enhances data collection and processing for forms.&lt;br /&gt;
&lt;br /&gt;
==== Defining an Input Array ====&lt;br /&gt;
&lt;br /&gt;
To designate an input field as an array, append '''[]''' to its '''name''' attribute. Each value submitted will be stored as a zero-indexed array using the input name as the key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example creates four text input fields in an HTML form.&lt;br /&gt;
&lt;br /&gt;
==== How XAP Handles Input Arrays ====&lt;br /&gt;
&lt;br /&gt;
When submitted, the data will be stored in the CGIFILE with key/value pairs in the order they appear:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
The last key, '''Q.STRINGINPUT[]''', ensures backward compatibility with older XAP versions where only the last submitted value was stored.&lt;br /&gt;
&lt;br /&gt;
==== URL Decoding of Keys ====&lt;br /&gt;
&lt;br /&gt;
If '''URLDECODEKEYS TRUE''' is included in the #XAP file, the query keys will be properly decoded. Without this setting, the CGIFILE will store encoded keys:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Handling Empty Values ====&lt;br /&gt;
&lt;br /&gt;
By default, XAP does not write key/value pairs to CGIFILE if the field is left empty. For example, if the second input field is empty, the stored values would be:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
To force XAP to store all fields, including empty ones, use the '''WRITEEMPTYFIELDS TRUE''' setting. This ensures all key/value pairs are written:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Summary ====&lt;br /&gt;
&lt;br /&gt;
*Use '''name=&amp;quot;fieldname[]&amp;quot;''' in your '''&amp;lt;input&amp;gt;''' element to create input arrays.&lt;br /&gt;
&lt;br /&gt;
*XAP stores submitted values as zero-indexed arrays.&lt;br /&gt;
&lt;br /&gt;
*The last submitted value is also stored under '''Q.FIELDNAME[]''' for backward compatibility.&lt;br /&gt;
&lt;br /&gt;
*Use '''URLDECODEKEYS TRUE''' to properly decode keys.&lt;br /&gt;
&lt;br /&gt;
*By default, empty values are not stored; enable '''WRITEEMPTYFIELDS TRUE''' to include them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data''' enctype attribute.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;get filedata file1.xxx&amp;quot;)&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-14T18:36:04Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
As of Comet version 540, we have introduced new controls to enhance XAP’s support for form input arrays and file uploads. These controls are designed to improve data handling while maintaining backward compatibility. If you do not enable these new features, your existing programs will continue to function as they did in previous XAP versions, ensuring a seamless transition.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GET FILEDATA (XAP Control) ====&lt;br /&gt;
&lt;br /&gt;
Retrieve the data from an uploaded file inside an XAP program.&lt;br /&gt;
&lt;br /&gt;
When a file is uploaded to XAP using the '''type=&amp;quot;file&amp;quot;''' input attribute, the name is stored in the CGIFILE.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display an HTML input element to upload a file.  When a file is specified and submitted, the CGIFILE will contain:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE - filename.ext&lt;br /&gt;
&lt;br /&gt;
In order to retrieve the data from the upload, use the '''GET FILEDATA''' control to copy the file into a dynamic string:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;GET FILEDATA filename.ext&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
From here you can use something like '''PRINTFILE''' to save the data to the filesystem.&lt;br /&gt;
&lt;br /&gt;
Note, this method copies the entire file as a chunk of data into a dynamic string.  Be aware that large files could cause performance issues depending on usage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports HTML form input arrays. This allows multiple values to be submitted under the same field name and stored in an indexed array. This functionality enhances data collection and processing for forms.&lt;br /&gt;
&lt;br /&gt;
==== Defining an Input Array ====&lt;br /&gt;
&lt;br /&gt;
To designate an input field as an array, append '''[]''' to its '''name''' attribute. Each value submitted will be stored as a zero-indexed array using the input name as the key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example creates four text input fields in an HTML form.&lt;br /&gt;
&lt;br /&gt;
==== How XAP Handles Input Arrays ====&lt;br /&gt;
&lt;br /&gt;
When submitted, the data will be stored in the CGIFILE with key/value pairs in the order they appear:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
The last key, '''Q.STRINGINPUT[]''', ensures backward compatibility with older XAP versions where only the last submitted value was stored.&lt;br /&gt;
&lt;br /&gt;
==== URL Decoding of Keys ====&lt;br /&gt;
&lt;br /&gt;
If '''URLDECODEKEYS TRUE''' is included in the #XAP file, the query keys will be properly decoded. Without this setting, the CGIFILE will store encoded keys:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Handling Empty Values ====&lt;br /&gt;
&lt;br /&gt;
By default, XAP does not write key/value pairs to CGIFILE if the field is left empty. For example, if the second input field is empty, the stored values would be:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
To force XAP to store all fields, including empty ones, use the '''WRITEEMPTYFIELDS TRUE''' setting. This ensures all key/value pairs are written:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Summary ====&lt;br /&gt;
&lt;br /&gt;
*Use '''name=&amp;quot;fieldname[]&amp;quot;''' in your '''&amp;lt;input&amp;gt;''' element to create input arrays.&lt;br /&gt;
&lt;br /&gt;
*XAP stores submitted values as zero-indexed arrays.&lt;br /&gt;
&lt;br /&gt;
*The last submitted value is also stored under '''Q.FIELDNAME[]''' for backward compatibility.&lt;br /&gt;
&lt;br /&gt;
*Use '''URLDECODEKEYS TRUE''' to properly decode keys.&lt;br /&gt;
&lt;br /&gt;
*By default, empty values are not stored; enable '''WRITEEMPTYFIELDS TRUE''' to include them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data' enctype attribute.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;get filedata file1.xxx&amp;quot;)&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-14T18:33:42Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
As of Comet version 540, we have introduced new controls to enhance XAP’s support for form input arrays and file uploads. These controls are designed to improve data handling while maintaining backward compatibility. If you do not enable these new features, your existing programs will continue to function as they did in previous XAP versions, ensuring a seamless transition.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS (#XAP Setting) ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GET FILEDATA (XAP Control) ====&lt;br /&gt;
&lt;br /&gt;
Retrieve the data from an uploaded file inside an XAP program.&lt;br /&gt;
&lt;br /&gt;
When a file is uploaded to XAP using the '''type=&amp;quot;file&amp;quot;''' input attribute, the name is stored in the CGIFILE.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display an HTML input element to upload a file.  When a file is specified and submitted, the CGIFILE will contain:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE - filename.ext&lt;br /&gt;
&lt;br /&gt;
In order to retrieve the data from the upload, use the '''GET FILEDATA''' control to copy the file into a dynamic string:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;GET FILEDATA filename.ext&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
From here you can use something like '''PRINTFILE''' to save the data to the filesystem.&lt;br /&gt;
&lt;br /&gt;
Note, this method copies the entire file as a chunk of data into a dynamic string.  Be aware that large files could cause performance issues depending on usage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports HTML form input arrays. This allows multiple values to be submitted under the same field name and stored in an indexed array. This functionality enhances data collection and processing for forms.&lt;br /&gt;
&lt;br /&gt;
==== Defining an Input Array ====&lt;br /&gt;
&lt;br /&gt;
To designate an input field as an array, append '''[]''' to its '''name''' attribute. Each value submitted will be stored as a zero-indexed array using the input name as the key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example creates four text input fields in an HTML form.&lt;br /&gt;
&lt;br /&gt;
==== How XAP Handles Input Arrays ====&lt;br /&gt;
&lt;br /&gt;
When submitted, the data will be stored in the CGIFILE with key/value pairs in the order they appear:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
The last key, '''Q.STRINGINPUT[]''', ensures backward compatibility with older XAP versions where only the last submitted value was stored.&lt;br /&gt;
&lt;br /&gt;
==== URL Decoding of Keys ====&lt;br /&gt;
&lt;br /&gt;
If '''URLDECODEKEYS TRUE''' is included in the #XAP file, the query keys will be properly decoded. Without this setting, the CGIFILE will store encoded keys:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Handling Empty Values ====&lt;br /&gt;
&lt;br /&gt;
By default, XAP does not write key/value pairs to CGIFILE if the field is left empty. For example, if the second input field is empty, the stored values would be:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
To force XAP to store all fields, including empty ones, use the '''WRITEEMPTYFIELDS TRUE''' setting. This ensures all key/value pairs are written:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Summary ====&lt;br /&gt;
&lt;br /&gt;
*Use '''name=&amp;quot;fieldname[]&amp;quot;''' in your '''&amp;lt;input&amp;gt;''' element to create input arrays.&lt;br /&gt;
&lt;br /&gt;
*XAP stores submitted values as zero-indexed arrays.&lt;br /&gt;
&lt;br /&gt;
*The last submitted value is also stored under '''Q.FIELDNAME[]''' for backward compatibility.&lt;br /&gt;
&lt;br /&gt;
*Use '''URLDECODEKEYS TRUE''' to properly decode keys.&lt;br /&gt;
&lt;br /&gt;
*By default, empty values are not stored; enable '''WRITEEMPTYFIELDS TRUE''' to include them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data' enctype attribute - '''POST''' will NOT work.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;get filedata file1.xxx&amp;quot;)&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-13T21:30:59Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GET FILEDATA ====&lt;br /&gt;
&lt;br /&gt;
Retrieve the data from an uploaded file inside an XAP program.&lt;br /&gt;
&lt;br /&gt;
When a file is uploaded to XAP using the '''type=&amp;quot;file&amp;quot;''' input attribute, the name is stored in the CGIFILE.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display an HTML input element to upload a file.  When a file is specified and submitted, the CGIFILE will contain:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE - filename.ext&lt;br /&gt;
&lt;br /&gt;
In order to retrieve the data from the upload, use the '''GET FILEDATA''' control to copy the file into a dynamic string:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;GET FILEDATA filename.ext&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
From here you can use something like '''PRINTFILE''' to save the data to the filesystem.&lt;br /&gt;
&lt;br /&gt;
Note, this method copies the entire file as a chunk of data into a dynamic string.  Be aware that large files could cause performance issues depending on usage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports HTML form input arrays. This allows multiple values to be submitted under the same field name and stored in an indexed array. This functionality enhances data collection and processing for forms.&lt;br /&gt;
&lt;br /&gt;
==== Defining an Input Array ====&lt;br /&gt;
&lt;br /&gt;
To designate an input field as an array, append '''[]''' to its '''name''' attribute. Each value submitted will be stored as a zero-indexed array using the input name as the key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example creates four text input fields in an HTML form.&lt;br /&gt;
&lt;br /&gt;
==== How XAP Handles Input Arrays ====&lt;br /&gt;
&lt;br /&gt;
When submitted, the data will be stored in the CGIFILE with key/value pairs in the order they appear:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
The last key, '''Q.STRINGINPUT[]''', ensures backward compatibility with older XAP versions where only the last submitted value was stored.&lt;br /&gt;
&lt;br /&gt;
==== URL Decoding of Keys ====&lt;br /&gt;
&lt;br /&gt;
If '''URLDECODEKEYS TRUE''' is included in the #XAP file, the query keys will be properly decoded. Without this setting, the CGIFILE will store encoded keys:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Handling Empty Values ====&lt;br /&gt;
&lt;br /&gt;
By default, XAP does not write key/value pairs to CGIFILE if the field is left empty. For example, if the second input field is empty, the stored values would be:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
To force XAP to store all fields, including empty ones, use the '''WRITEEMPTYFIELDS TRUE''' setting. This ensures all key/value pairs are written:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Summary ====&lt;br /&gt;
&lt;br /&gt;
*Use '''name=&amp;quot;fieldname[]&amp;quot;''' in your '''&amp;lt;input&amp;gt;''' element to create input arrays.&lt;br /&gt;
&lt;br /&gt;
*XAP stores submitted values as zero-indexed arrays.&lt;br /&gt;
&lt;br /&gt;
*The last submitted value is also stored under '''Q.FIELDNAME[]''' for backward compatibility.&lt;br /&gt;
&lt;br /&gt;
*Use '''URLDECODEKEYS TRUE''' to properly decode keys.&lt;br /&gt;
&lt;br /&gt;
*By default, empty values are not stored; enable '''WRITEEMPTYFIELDS TRUE''' to include them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data' enctype attribute - '''POST''' will NOT work.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;get filedata file1.xxx&amp;quot;)&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-13T20:51:55Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GET FILEDATA ====&lt;br /&gt;
&lt;br /&gt;
Retrieve the data from an uploaded file inside an XAP program.&lt;br /&gt;
&lt;br /&gt;
When a file is uploaded to XAP using the '''type=&amp;quot;file&amp;quot;''' input attribute, the name is stored in the CGIFILE.  For example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display an HTML input element to upload a file.  When a file is specified and submitted, the CGIFILE will contain:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE - filename.ext&lt;br /&gt;
&lt;br /&gt;
In order to retrieve the data from the upload, use the '''GET FILEDATA''' control to copy the file into a dynamic string:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;GET FILEDATA filename.ext&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Note, this method copies the entire file as a chunk of data into a dynamic string.  If the file is large, then further copies or manipulation of the string &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports HTML form input arrays. This allows multiple values to be submitted under the same field name and stored in an indexed array. This functionality enhances data collection and processing for forms.&lt;br /&gt;
&lt;br /&gt;
==== Defining an Input Array ====&lt;br /&gt;
&lt;br /&gt;
To designate an input field as an array, append '''[]''' to its '''name''' attribute. Each value submitted will be stored as a zero-indexed array using the input name as the key.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This example creates four text input fields in an HTML form.&lt;br /&gt;
&lt;br /&gt;
==== How XAP Handles Input Arrays ====&lt;br /&gt;
&lt;br /&gt;
When submitted, the data will be stored in the CGIFILE with key/value pairs in the order they appear:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
The last key, '''Q.STRINGINPUT[]''', ensures backward compatibility with older XAP versions where only the last submitted value was stored.&lt;br /&gt;
&lt;br /&gt;
==== URL Decoding of Keys ====&lt;br /&gt;
&lt;br /&gt;
If '''URLDECODEKEYS TRUE''' is included in the #XAP file, the query keys will be properly decoded. Without this setting, the CGIFILE will store encoded keys:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Handling Empty Values ====&lt;br /&gt;
&lt;br /&gt;
By default, XAP does not write key/value pairs to CGIFILE if the field is left empty. For example, if the second input field is empty, the stored values would be:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
To force XAP to store all fields, including empty ones, use the '''WRITEEMPTYFIELDS TRUE''' setting. This ensures all key/value pairs are written:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
==== Summary ====&lt;br /&gt;
&lt;br /&gt;
*Use '''name=&amp;quot;fieldname[]&amp;quot;''' in your '''&amp;lt;input&amp;gt;''' element to create input arrays.&lt;br /&gt;
&lt;br /&gt;
*XAP stores submitted values as zero-indexed arrays.&lt;br /&gt;
&lt;br /&gt;
*The last submitted value is also stored under '''Q.FIELDNAME[]''' for backward compatibility.&lt;br /&gt;
&lt;br /&gt;
*Use '''URLDECODEKEYS TRUE''' to properly decode keys.&lt;br /&gt;
&lt;br /&gt;
*By default, empty values are not stored; enable '''WRITEEMPTYFIELDS TRUE''' to include them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data' enctype attribute - '''POST''' will NOT work.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = control(0, &amp;quot;get filedata file1.xxx&amp;quot;)&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-13T20:35:09Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
Starting in Comet 540, XAP supports HTML form input arrays. You can designate any &amp;lt;input&amp;gt; as an array element by including &amp;quot;[]&amp;quot; at the end of the name.  Each value in a designated array will be written to a zero-indexed array using the &amp;lt;input&amp;gt; name as the key field.  For example,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display 4 text inputs in an HTML form.  When submitted to XAP, the CGIFILE will contain the following key/value pairs:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
where each key/value corresponds to the element in the order in the HTML form.  In order to be backwards compatible with previous versions of Comet/XAP, we include the last '''Q.STRINGINPUT[]''' as a key without an index, and the value of the last query value specified in the form.  In previous versions, this would be the only key/value defined in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
Note, this example assumes that '''URLDECODEKEYS TRUE''' was included in the #XAP file.  By default, the query keys will not be decoded, and your CGIFILE will look like this:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
Using this example, if the second value is empty (no value), then the CGIFILE will contain the following key/value pairs:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
because, by default, XAP does not write key/value pairs to the CGIFILE that have empty values.  Using the new control '''WRITEEMPTYFIELDS TRUE''' will force XAP to write all key/value pairs, regardless of whether the value is empty:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New XAP File Upload Mechanics ===&lt;br /&gt;
&lt;br /&gt;
==== Overview ====&lt;br /&gt;
&lt;br /&gt;
XAP now supports file uploads, allowing web-enabled programs to upload and process files within the system. This feature enables users to upload multiple files and manage them dynamically.&lt;br /&gt;
&lt;br /&gt;
==== Uploading Files via HTML Form ====&lt;br /&gt;
&lt;br /&gt;
To upload files in XAP, use the &amp;lt;input type=&amp;quot;file&amp;quot;&amp;gt; tag within an HTML form. Ensure that the enctype attribute is set to '''multipart/form-data''' for proper file handling.  File uploads will '''ONLY''' work with the '''multipart/form-data' enctype attribute - '''POST''' will NOT work.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;form id=&amp;quot;theform&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;upload&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;myFile[]&amp;quot; multiple&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example:&lt;br /&gt;
&lt;br /&gt;
*The multiple attribute allows users to select and upload multiple files.&lt;br /&gt;
&lt;br /&gt;
*The uploaded file names are stored in an array for easy access.&lt;br /&gt;
&lt;br /&gt;
==== Handling Uploaded Files in XAP ====&lt;br /&gt;
&lt;br /&gt;
Once uploaded, your CGIFILE will store the filenames as key/value pairs as follows:&lt;br /&gt;
&lt;br /&gt;
 Q.MYFILE[0] - file1.xxx&lt;br /&gt;
 Q.MYFILE[1] - file2.yyy&lt;br /&gt;
&lt;br /&gt;
You can retrieve the file data using the new '''GET FILEDATA''' command to copy the file data into a dynamic string and manipulate it as needed. For example, you can write it to the file system using the '''PRINTFILE''' statement.&lt;br /&gt;
&lt;br /&gt;
Example Usage:&lt;br /&gt;
&lt;br /&gt;
 filedata$ = &amp;quot;get filedata file1.xxx&amp;quot;&lt;br /&gt;
 newpath$ = path(&amp;quot;TMP&amp;quot;) + &amp;quot;file.xxx&amp;quot;&lt;br /&gt;
 Printfile newpath$ filedata$&lt;br /&gt;
&lt;br /&gt;
This command writes the uploaded file to the TMP directory while preserving the original filename.&lt;br /&gt;
&lt;br /&gt;
==== File Management ====&lt;br /&gt;
&lt;br /&gt;
Retrieve Data: Use '''GET FILEDATA''' to access uploaded file content.&lt;br /&gt;
&lt;br /&gt;
Save Files: Utilize '''PRINTFILE''' to store files in a specified directory.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-13T20:18:08Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
Starting in Comet 540, XAP supports HTML form input arrays. You can designate any &amp;lt;input&amp;gt; as an array element by including &amp;quot;[]&amp;quot; at the end of the name.  Each value in a designated array will be written to a zero-indexed array using the &amp;lt;input&amp;gt; name as the key field.  For example,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will display 4 text inputs in an HTML form.  When submitted to XAP, the CGIFILE will contain the following key/value pairs:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - second value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
where each key/value corresponds to the element in the order in the HTML form.  In order to be backwards compatible with previous versions of Comet/XAP, we include the last '''Q.STRINGINPUT[]''' as a key without an index, and the value of the last query value specified in the form.  In previous versions, this would be the only key/value defined in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
Note, this example assumes that '''URLDECODEKEYS TRUE''' was included in the #XAP file.  By default, the query keys will not be decoded, and your CGIFILE will look like this:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT%5B0%5D - first value&lt;br /&gt;
 Q.STRINGINPUT%5B1%5D - second value&lt;br /&gt;
 Q.STRINGINPUT%5B2%5D - third value&lt;br /&gt;
 Q.STRINGINPUT%5B3%5D - fourth value&lt;br /&gt;
 Q.STRINGINPUT%5B%5D - fourth/last value&lt;br /&gt;
&lt;br /&gt;
Using this example, if the second value is empty (no value), then the CGIFILE will contain the following key/value pairs:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
because, by default, XAP does not write key/value pairs to the CGIFILE that have empty values.  Using the new control '''WRITEEMPTYFIELDS TRUE''' will force XAP to write all key/value pairs, regardless of whether the value is empty:&lt;br /&gt;
&lt;br /&gt;
 Q.STRINGINPUT[0] - first value&lt;br /&gt;
 Q.STRINGINPUT[1] - empty&lt;br /&gt;
 Q.STRINGINPUT[2] - third value&lt;br /&gt;
 Q.STRINGINPUT[3] - fourth value&lt;br /&gt;
 Q.STRINGINPUT[] - fourth/last value&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New File Upload Mechanics ===&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-13T19:08:15Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  Special characters include, for example, '(', '[', and '%' which are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
=== New File Upload Mechanics ===&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload</id>
		<title>New XAP controls and File Upload</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/New_XAP_controls_and_File_Upload"/>
				<updated>2025-03-12T23:55:58Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: Created page with &amp;quot;== New XAP Controls and File Upload ==  === New Controls ===  These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query ke...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== New XAP Controls and File Upload ==&lt;br /&gt;
&lt;br /&gt;
=== New Controls ===&lt;br /&gt;
&lt;br /&gt;
These new controls can be added to your #XAP file, and will change how XAP builds the keyed file containing query key/value pairs.&lt;br /&gt;
&lt;br /&gt;
==== WRITEEMPTYFIELDS ====&lt;br /&gt;
&lt;br /&gt;
Force XAP to write keys to the CGIFILE even if the value is empty.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will skip writing keys to the CGIFILE if the value in the key/value pair is empty.  For instance, if you have&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the form is submitted with no text in the input field, then XAP will NOT write '''Q.STRINGINPUT''' into the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 WRITEEMPTYFIELDS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, even if the value in the text input is empty, there will be a '''Q.STRINGINPUT''' key in the CGIFILE, with a blank record for the value.&lt;br /&gt;
&lt;br /&gt;
==== URLDECODEKEYS ====&lt;br /&gt;
&lt;br /&gt;
Tell XAP to decode special characters when writing the keys in the CGIFILE.&lt;br /&gt;
&lt;br /&gt;
By default, XAP will NOT decode special characters inside the keys of the CGIFILE.  For example, '(', '[', and '%' are encoded as '%28', '%5B', and '%25' respectively.&lt;br /&gt;
&lt;br /&gt;
So if we have a input field for text named like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;stringinput[]&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
XAP will write the key for this input field into the CGIFILE as '''Q.STRINGINPUT%5B%5D'''&lt;br /&gt;
&lt;br /&gt;
By including&lt;br /&gt;
&lt;br /&gt;
 URLDECODEKEYS TRUE&lt;br /&gt;
&lt;br /&gt;
into your #XAP file, you can force XAP to write the encoded characters as they were originally intended.  In this case, '''Q.STRINGINPUT[]'''&lt;br /&gt;
&lt;br /&gt;
=== Array Handling for Form Elements ===&lt;br /&gt;
&lt;br /&gt;
=== New File Upload Mechanics ===&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Main_Page</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Main_Page"/>
				<updated>2025-03-12T23:27:28Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;='''Comet by Signature Systems, Inc.'''=&lt;br /&gt;
&lt;br /&gt;
* [[Getting Started With Comet]]&lt;br /&gt;
&lt;br /&gt;
* [[Subscription Benefits]]&lt;br /&gt;
&lt;br /&gt;
* [[Virtual Dongle]]&lt;br /&gt;
&lt;br /&gt;
* [[FAQs]]&lt;br /&gt;
&lt;br /&gt;
* [[CFILES - the replacement for DbMgr]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet Meetings]]&lt;br /&gt;
&lt;br /&gt;
* [[Configuration and Installation]]&lt;br /&gt;
&lt;br /&gt;
* [[Programming]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet32]]&lt;br /&gt;
&lt;br /&gt;
* [[STL Containers]]&lt;br /&gt;
&lt;br /&gt;
* [[Xap and Comet32]]&amp;lt;!-- Comment * [[CometAnywhere Mobile]] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Products]]&lt;br /&gt;
&lt;br /&gt;
* [[Utilities]]&lt;br /&gt;
&lt;br /&gt;
* [[Comet Tips]]&lt;br /&gt;
&lt;br /&gt;
* [http://support.signature.net/ Support - Users Forum]&lt;br /&gt;
&lt;br /&gt;
* [[How to edit this Wiki]]&lt;br /&gt;
&lt;br /&gt;
* '''[http://cc.signature.net/guest/adduser Request ability to edit pages on this Wiki]'''&lt;br /&gt;
&lt;br /&gt;
*[[Comet And RDP]]&lt;br /&gt;
&lt;br /&gt;
* [[New XAP controls and File Upload]]&lt;br /&gt;
&lt;br /&gt;
A hint from the old guy. The Wiki's text size is based on the browser's settings. In '''Firefox''' I set the minimum font size to 16.&lt;br /&gt;
&lt;br /&gt;
Tools &amp;gt;&amp;gt; Options &amp;gt;&amp;gt; Content &amp;gt;&amp;gt; Advanced. Minimum font size.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Using_the_email_printer</id>
		<title>Using the email printer</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Using_the_email_printer"/>
				<updated>2024-01-09T22:06:52Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Email Printing with Comet==&lt;br /&gt;
© 2007 Signature System Inc.&lt;br /&gt;
&lt;br /&gt;
Within a few minutes you can configure a &amp;quot;printer&amp;quot; that will automatically email any text, HTML, or PDF document produced using Comet's printer drivers.&lt;br /&gt;
 &lt;br /&gt;
==Understanding SMTP==&lt;br /&gt;
The Email Printer uses a DES program called EMAILPTR. It talks the SMTP protocol. &lt;br /&gt;
SMTP stands for '''S'''imple '''M'''ail '''T'''ransport '''P'''rotocol. It is the basic protocol used to send mail over the internet. SMTP mimics the process of sending a package or letter by snail mail or delivery service.  When mailing a physical letter, you first write the letter itself (the body), then write the envelope and then take the envelope to the post office, giving delivery instructions.&lt;br /&gt;
&lt;br /&gt;
===There are 3 sections of an SMTP email transaction.===&lt;br /&gt;
 &lt;br /&gt;
====1. The SMTP routing instructions:====&lt;br /&gt;
* The connection server and port (Connect)&lt;br /&gt;
* The introduction (Domain)&lt;br /&gt;
* Optional Authentication (User and Password)&lt;br /&gt;
* The Sender's ID (Mail from)&lt;br /&gt;
* The destination (rcpt to)&lt;br /&gt;
* Other SMTP Commands&lt;br /&gt;
&lt;br /&gt;
====2. The &amp;quot;envelope&amp;quot; or Header====&lt;br /&gt;
* The date&lt;br /&gt;
* From&lt;br /&gt;
* To&lt;br /&gt;
* Subject&lt;br /&gt;
* Other Header elements&lt;br /&gt;
&lt;br /&gt;
====3. The body of the mail====&lt;br /&gt;
* Possibly multiple parts, each a different format.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
There are a few requirements to make this feature work. &lt;br /&gt;
&lt;br /&gt;
* A WinSock gateway configured. It is better to configure multiple WinSock Gateways.&lt;br /&gt;
* A COM license for CometLib. &lt;br /&gt;
* A connection to the Internet. &lt;br /&gt;
* A reachable SMTP server. &lt;br /&gt;
* The TMP directory for Comet must be configured as a CFAM directory and it must be configured in SYSGEN using the $(CATEMP) alias: &lt;br /&gt;
 00 = c ,$(catemp); &lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
You can designate TEXT, HTML, and PDF printers as email printers. Here is a sample of a section of an INI file:&lt;br /&gt;
&lt;br /&gt;
 Printer = leh,h,n,,htm,EmailPtr;   ; Data records are limited to 254 bytes &lt;br /&gt;
 Printer = leh,h,n,,htm,EmlPtr32;   ; For Comet32 users only: no restriction on length of data records written to the printer &lt;br /&gt;
 Printer = lep,p,n,,pdfFactory,EmailPtr; &lt;br /&gt;
 Printer = let,x,n,,txt,EmailPtr;   ; Data records are limited to 254 bytes &lt;br /&gt;
 Printer = let,x,n,,txt,EmlPtr32;   ; For Comet32 users only: no restriction on length of data records written to the printer &lt;br /&gt;
&lt;br /&gt;
We could have named the printers any device name beginning with an &amp;quot;L&amp;quot;. What designates this as an email printer is the DES program &amp;quot;EmailPtr&amp;quot; or &amp;quot;EmlPtr32&amp;quot;. These DES programs are released as part of the REL Directory.&lt;br /&gt;
&lt;br /&gt;
===Doc Manager===&lt;br /&gt;
You can configure a printer as both an email printer and an archive printer.&lt;br /&gt;
 &lt;br /&gt;
 Printer = LPI,p,x,SPL:invoices,Adobe PDF,EmailPtr;&lt;br /&gt;
&lt;br /&gt;
Every document printed to that printer would be rendered in PDF by the Adobe Pdf driver, emailed, and placed into the INVOICES docmanager archive. With appropriate Email.ini settings (see below), no program changes would be required other than selecting 'LPI' as the printer.&lt;br /&gt;
&lt;br /&gt;
==Mnemonics==&lt;br /&gt;
&lt;br /&gt;
There are several mnemonics specifically related to the email printer. First, you need to specify the smtp server name and port to be used to send your email.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Server='smtp.ourserver.net mail')&lt;br /&gt;
&lt;br /&gt;
Look at the server settings in your email program for the correct setting for this. The word &amp;quot;mail&amp;quot; above is an alias for port 25. Thus, you could have written &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Server='smtp.ourserver.net 25') &lt;br /&gt;
&lt;br /&gt;
and accomplished the same thing. You can use any port mandated by your ISP. Port 25 is the default. If you do not specify a port as part of the server name, the email printer will attempt to use port 25. Note: Beginning with Comet 2006 you are able to send email from smtp servers that require authentication.&lt;br /&gt;
&lt;br /&gt;
If you wish, you may also specify a domain name. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Domain='signature.net')&lt;br /&gt;
&lt;br /&gt;
If it is not specified, the email printer will supply the same domain as designated in the server mnemonic. &lt;br /&gt;
&lt;br /&gt;
To specify the sender's name you use the &amp;quot;From&amp;quot; mnemonic.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (From='&amp;quot;jim guerber&amp;quot;&amp;lt;jim@@signature.net&amp;gt;')&lt;br /&gt;
&lt;br /&gt;
This is used both for SMTP routing (MAIL FROM:) and for the mail message header (From:). It should be set to a valid email address. &lt;br /&gt;
&lt;br /&gt;
Use the &amp;quot;To&amp;quot; mnemonic to specify your recipients. This will be used for SMTP routing (RCPT TO:) and the header (To:).&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (To = 'jim&amp;lt;jim@@signature.net&amp;gt;')&lt;br /&gt;
 Print (lun) (To = 'gina@@signature.net') &lt;br /&gt;
&lt;br /&gt;
You must specify at least one recipient. Use multiple instances of this mnemonic to send your email to more than one recipient. CC and BCC recipients may be specified in addition to or instead of TO recipients. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (CC = 'barbara@@signature.net')&lt;br /&gt;
 Print (lun) (BCC = 'brian@@signature.net') &lt;br /&gt;
&lt;br /&gt;
You must include a subject for your email, use the &amp;quot;Subject&amp;quot; mnemonic. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Subject='The Subject of this email') &lt;br /&gt;
&lt;br /&gt;
In addition to whatever is written to the email printer, you may want to include body text. Depending on your email client, for html printers body text will either appear in an attachment, since it is usual for HTML to appear as the main body of the email, or it will be appended following the html content. For PDF printers, this text will be the main body of the email and the PDF will appear as an attachment. For text printers, the body text will appear just before the printer output. To specify body text, use the &amp;quot;Text&amp;quot; mnemonic.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Text='yada yada yada') &lt;br /&gt;
&lt;br /&gt;
The email printer will optionally write to a log file, recording details about each email sent, including responses from the smtp server. The log file is a text file located on any directory to which the user has access. The email printer will append to this log file. The log file may optionally be erased before the print job is run. Otherwise, it is up to the administrator or outside program to erase this file periodically. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Log='file','dir','erase') &lt;br /&gt;
&lt;br /&gt;
If the log file name is not specified, a file named &amp;quot;email.log&amp;quot; will be used. If the email directory is not specified, &amp;quot;COS&amp;quot; will be used. By default, the file will not be erased. If there is no LOG statement at all, no log file will be generated.&lt;br /&gt;
&lt;br /&gt;
If you wish to specify a name for an attachment to your email, use the (EmailDocument=) mnemonic. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (EmailDocument='file') &lt;br /&gt;
 Without the (EmailDocument=) mnemonic, the attachment would carry the default name of the document.&lt;br /&gt;
&lt;br /&gt;
==Formatting of email addresses==&lt;br /&gt;
&lt;br /&gt;
In the examples above, we have shown a few different ways to specify an email address. Mail programs like addresses formatted in the following way: &amp;quot;FirstName LastName&amp;quot;&amp;lt;email@domain.tld&amp;gt; Any of the following should work: &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (To = 'Jim Guerber&amp;lt;jim@@signature.net&amp;gt;') ! Best &lt;br /&gt;
 Print (lun) (To = 'Jim&amp;lt;jim@@signature.net&amp;gt;')              ! ok &lt;br /&gt;
 Print (lun) (To = 'jim@@signature.net')                      ! worst &lt;br /&gt;
&lt;br /&gt;
If there is no space character in the name the double quotes are not necessary. Most email programs will take some sort of shortened form of email address, even just the address with no &amp;lt;&amp;gt; such as email@domain.tld, but some spam detection programs may object to this simple form. Note the use of double @ characters as an escape convention of Internet Basic. &lt;br /&gt;
&lt;br /&gt;
Email addresses used in the SMTP routing instructions &amp;quot;mail from&amp;quot; and &amp;quot;rcpt to&amp;quot; will have any name information (like &amp;quot;Jim Guerber&amp;quot; in the above example) stripped out. Microsoft Exchange Server doesn't tolerate anything other than the simple email address.&lt;br /&gt;
&lt;br /&gt;
== A Note on Verifying Email Addresses==&lt;br /&gt;
&lt;br /&gt;
If you're going to do email address validation, consider that VRFY and EXPN are blocked by most ISPs nowadays. Also, simulating VRFY by stacking RCPT TO: commands is something that spammers do. ISPs know this, and the smarter ones track how often you do this. You'll get blocked after some number of attempts. I wouldn't go looking for a lot of sympathy from ISPs when trying to get unblocked afterwards, as the ISPs consider this a very bad practice that good guys don't engage in.&lt;br /&gt;
==The email.ini file==&lt;br /&gt;
&lt;br /&gt;
Several settings for email printers never (or rarely) change. These settings can be placed in an initialization file (INI File). The email printer will look for a file named email.ini which can contain those settings. The email.ini file is optional since all values may be supplied by mnemonics in the program, but it may be a more convenient way to supply some parameters such as the smtp server name. Lines beginning with an exclamation marks ! are treated as comments.&lt;br /&gt;
&lt;br /&gt;
====Mnemonics vs the Email.ini file====&lt;br /&gt;
The information required for an email may be either specified by the use of mnemonics, or placed in a text file called email.ini or both. You may want to setup a standard email.ini file containing items that remain constant from one email to another such as server and domain, and specify the rest of the info using mnemonics, or you may want to write a new email.ini file in the temp directory containing all of the information required before initiating the email program. &lt;br /&gt;
* The email.ini file is not processed until the printer is closed. This means that any time during the execution of the print program, you may add items to the email.ini file.&lt;br /&gt;
* Each print of a mnemonic causes a new line to be generated in the document (the email body) unless Transparent mode is specified (TR).&lt;br /&gt;
* Use of the email.ini file allows general print programs to generate email with no change.&lt;br /&gt;
&lt;br /&gt;
The email printer will look for an equal sign (=) as a delimiter between the parameter name and the value. If an equal sign is not found, the whole line will be treated as text. This is the same as using the &amp;quot;text=&amp;quot; parameter. Here's an example:&lt;br /&gt;
&lt;br /&gt;
 server = smtp.ourserver.net &lt;br /&gt;
 from = OrderProcessing@OurCompany.com &lt;br /&gt;
 bcc = AcctsReceivable@OurCompany.com &lt;br /&gt;
 subject = Thank you for your order &lt;br /&gt;
 Thank you for your recent order. The attached document contains your invoice and delivery schedule. &lt;br /&gt;
&lt;br /&gt;
Using the preceding email.ini file, all that the program would need to supply is the recipient's email address (using the (To=) mnemonic) and write the unique details of the message to the email printer. Note that Accounts Receivable will automatically receive a copy (bcc) of each email.&lt;br /&gt;
 &lt;br /&gt;
Some mnemonics supplied by the program have precedence over the email.ini settings. In other cases both values from a mnemonic AND values from the email.ini file will be used. Those mnemonics which will super cede the equivalent setting in the email.ini file are Server, Domain, From, Subject, and Log. And, if you were to try to use more than one of any of those mnemonics for a given email, only the first one of each would be used. The other settings: To, CC, BCC, and Text, may have multiple occurrences. And, if you use these mnemonics and have equivalent settings in the email.ini, they will all be processed for your email. &lt;br /&gt;
&lt;br /&gt;
==Attachments==&lt;br /&gt;
&lt;br /&gt;
Before understanding attachments, It is good to know the order documents get placed in the email for various printers. For the sake of this document we will call any text specified by the (text=)mnemonic or in the email.ini file &amp;quot;body text&amp;quot;. For all email print jobs there are three possible components that are transmitted. The order depends on the printer type.&lt;br /&gt;
&lt;br /&gt;
For HTML printers, the email is composed of the HTML generated for the printer, followed by the body text, and then any attachments specified.&lt;br /&gt;
 &lt;br /&gt;
For Text printers, email is composed of the printer output followed by body text and then attachments.&lt;br /&gt;
 &lt;br /&gt;
For PDF printers, the email is composed of body text, followed by the printer output as an attachment and then followed by any other attachments specified.&lt;br /&gt;
 &lt;br /&gt;
To add an attachment to the email document, either use the (attachment=path) mnemonic or specify the attachment in the INI file. The path specified must be a valid windows path (use either drive letter or UNC conventions), and does not need to be a Comet file or reside in a Comet directory. Any number of attachment files may be specified. The Emailptr program attempts to determine the mime type of the file by reading the mime keyed file in the rel directory using the file extent ion as the key. If the mime type is not determine able, the default mime type of &amp;quot;application/octet-stream&amp;quot; is used.&lt;br /&gt;
&lt;br /&gt;
==Return Receipts==&lt;br /&gt;
&lt;br /&gt;
Occasionally you may want to know when the receiver of your email reads it. Some (not all) email programs support the &amp;quot;Return-Receipt-To:&amp;quot; command. You may specify (a single) return receipt address either in the ini file or by using the (rr=) mnemonic. Following the equal sign must be a valid email address. &lt;br /&gt;
&lt;br /&gt;
==Silent Running==&lt;br /&gt;
&lt;br /&gt;
The Emailptr will sometimes put up a message box if some component of the email such as the subject is missing. This will stop any program that is designed to produce a series of emails, and would crash if run from a background partition. For that reason, there is an extra instruction in the email.ini file to take care of this situation. If you do not want the emailptr to send any output to the screen, include the '''silent''' command in the email.ini file. If this command appears alone, the emailptr will simply close the email and continue. You may also optionally specify a program to be entered each time an error is encountered. In that case, # buffer will contain the error information (the text that would normally appear in the message box.&lt;br /&gt;
&lt;br /&gt;
==Other SMTP commands and header lines==&lt;br /&gt;
&lt;br /&gt;
You may want to supply other commands to the SMTP server or place additional commands in the header. There are 2 commands that allow you to do that. &lt;br /&gt;
&lt;br /&gt;
'''SmtpCmd=text''' includes the text into the smtp routing instructions. I can't find any good examples of why you would want to send one of these things, but in the future, some Exchange server or something may require one of these.&lt;br /&gt;
&lt;br /&gt;
'''Smtphdr=text''' includes the text in the envelope (the header). There are several interesting commands you could want to put here, but most of them are obsolete.&lt;br /&gt;
&lt;br /&gt;
Examples are:&lt;br /&gt;
&lt;br /&gt;
 print (LUN)(SmtpHdr='X-Priority: 1')    ! mark the email as urgent&lt;br /&gt;
&lt;br /&gt;
==Reference==&lt;br /&gt;
&lt;br /&gt;
For reference, here is a complete list of mnemonics and their corresponding email.ini file settings: &lt;br /&gt;
{|  border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;225&amp;quot;| Mnemonic&lt;br /&gt;
!width=&amp;quot;400&amp;quot;| Ini file&lt;br /&gt;
|-&lt;br /&gt;
| (log = log$)&lt;br /&gt;
| log = email.log,cos,cycle&lt;br /&gt;
|-&lt;br /&gt;
| (server = server$) &lt;br /&gt;
| server = smtp.ourserver.net &lt;br /&gt;
|-&lt;br /&gt;
| (domain= domain$) &lt;br /&gt;
| domain= smtp.ourserver.net &lt;br /&gt;
|-&lt;br /&gt;
| (user = user$) &lt;br /&gt;
|  user = username &lt;br /&gt;
|-&lt;br /&gt;
| (password= pw$) &lt;br /&gt;
| password = MyPassword &lt;br /&gt;
|-&lt;br /&gt;
| (from = from$) &lt;br /&gt;
| from = OrderProcessing@OurCompany.com&lt;br /&gt;
|-&lt;br /&gt;
| (to = to$)&lt;br /&gt;
| to = youraddress@yourisp.net&lt;br /&gt;
|-&lt;br /&gt;
| (cc = cc$) &lt;br /&gt;
| cc = mylawyer@protectme.net &lt;br /&gt;
|-&lt;br /&gt;
| (rr= ReturnReceipt$)&lt;br /&gt;
| rr = returnReceipt@OurCompany.com &lt;br /&gt;
|-&lt;br /&gt;
| (bcc = bcc$) &lt;br /&gt;
| bcc = AcctsReceivable@OurCompany.com &lt;br /&gt;
|-&lt;br /&gt;
| (subject = Subject$) &lt;br /&gt;
| subject = Thank you for your order &lt;br /&gt;
|-&lt;br /&gt;
| (attachment = a$) &lt;br /&gt;
| attachment = c:\boilerplate\terms.pdf &lt;br /&gt;
|-&lt;br /&gt;
| (silent = 'myprog')&lt;br /&gt;
| silent = myprog&lt;br /&gt;
|-&lt;br /&gt;
| (SmtpCmd = 'help')&lt;br /&gt;
| SmtpCmd=help&lt;br /&gt;
|-&lt;br /&gt;
| (SmtpHdr=h$)&lt;br /&gt;
| SmtpHdr=X-Priority: 1&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| ssl=true&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| tls=true&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| time = +/-#### (offset hours from GMT)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
Here is an interesting article aimed at writers of smtp servers with techniques for filtering spam. It is useful to us so that we can better format our emails to avoid being labeled as &amp;quot;ratware&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[http://slett.net/spam-filtering-for-mx/ Spam Filtering for Mail Exchangers]&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Using_the_email_printer</id>
		<title>Using the email printer</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Using_the_email_printer"/>
				<updated>2024-01-09T22:06:26Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Email Printing with Comet==&lt;br /&gt;
© 2007 Signature System Inc.&lt;br /&gt;
&lt;br /&gt;
Within a few minutes you can configure a &amp;quot;printer&amp;quot; that will automatically email any text, HTML, or PDF document produced using Comet's printer drivers.&lt;br /&gt;
 &lt;br /&gt;
==Understanding SMTP==&lt;br /&gt;
The Email Printer uses a DES program called EMAILPTR. It talks the SMTP protocol. &lt;br /&gt;
SMTP stands for '''S'''imple '''M'''ail '''T'''ransport '''P'''rotocol. It is the basic protocol used to send mail over the internet. SMTP mimics the process of sending a package or letter by snail mail or delivery service.  When mailing a physical letter, you first write the letter itself (the body), then write the envelope and then take the envelope to the post office, giving delivery instructions.&lt;br /&gt;
&lt;br /&gt;
===There are 3 sections of an SMTP email transaction.===&lt;br /&gt;
 &lt;br /&gt;
====1. The SMTP routing instructions:====&lt;br /&gt;
* The connection server and port (Connect)&lt;br /&gt;
* The introduction (Domain)&lt;br /&gt;
* Optional Authentication (User and Password)&lt;br /&gt;
* The Sender's ID (Mail from)&lt;br /&gt;
* The destination (rcpt to)&lt;br /&gt;
* Other SMTP Commands&lt;br /&gt;
&lt;br /&gt;
====2. The &amp;quot;envelope&amp;quot; or Header====&lt;br /&gt;
* The date&lt;br /&gt;
* From&lt;br /&gt;
* To&lt;br /&gt;
* Subject&lt;br /&gt;
* Other Header elements&lt;br /&gt;
&lt;br /&gt;
====3. The body of the mail====&lt;br /&gt;
* Possibly multiple parts, each a different format.&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
There are a few requirements to make this feature work. &lt;br /&gt;
&lt;br /&gt;
* A WinSock gateway configured. It is better to configure multiple WinSock Gateways.&lt;br /&gt;
* A COM license for CometLib. &lt;br /&gt;
* A connection to the Internet. &lt;br /&gt;
* A reachable SMTP server. &lt;br /&gt;
* The TMP directory for Comet must be configured as a CFAM directory and it must be configured in SYSGEN using the $(CATEMP) alias: &lt;br /&gt;
 00 = c ,$(catemp); &lt;br /&gt;
&lt;br /&gt;
==Configuration==&lt;br /&gt;
&lt;br /&gt;
You can designate TEXT, HTML, and PDF printers as email printers. Here is a sample of a section of an INI file:&lt;br /&gt;
&lt;br /&gt;
 Printer = leh,h,n,,htm,EmailPtr;   ; Data records are limited to 254 bytes &lt;br /&gt;
 Printer = leh,h,n,,htm,EmlPtr32;   ; For Comet32 users only: no restriction on length of data records written to the printer &lt;br /&gt;
 Printer = lep,p,n,,pdfFactory,EmailPtr; &lt;br /&gt;
 Printer = let,x,n,,txt,EmailPtr;   ; Data records are limited to 254 bytes &lt;br /&gt;
 Printer = let,x,n,,txt,EmlPtr32;   ; For Comet32 users only: no restriction on length of data records written to the printer &lt;br /&gt;
&lt;br /&gt;
We could have named the printers any device name beginning with an &amp;quot;L&amp;quot;. What designates this as an email printer is the DES program &amp;quot;EmailPtr&amp;quot; or &amp;quot;EmlPtr32&amp;quot;. These DES programs are released as part of the REL Directory.&lt;br /&gt;
&lt;br /&gt;
===Doc Manager===&lt;br /&gt;
You can configure a printer as both an email printer and an archive printer.&lt;br /&gt;
 &lt;br /&gt;
 Printer = LPI,p,x,SPL:invoices,Adobe PDF,EmailPtr;&lt;br /&gt;
&lt;br /&gt;
Every document printed to that printer would be rendered in PDF by the Adobe Pdf driver, emailed, and placed into the INVOICES docmanager archive. With appropriate Email.ini settings (see below), no program changes would be required other than selecting 'LPI' as the printer.&lt;br /&gt;
&lt;br /&gt;
==Mnemonics==&lt;br /&gt;
&lt;br /&gt;
There are several mnemonics specifically related to the email printer. First, you need to specify the smtp server name and port to be used to send your email.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Server='smtp.ourserver.net mail')&lt;br /&gt;
&lt;br /&gt;
Look at the server settings in your email program for the correct setting for this. The word &amp;quot;mail&amp;quot; above is an alias for port 25. Thus, you could have written &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Server='smtp.ourserver.net 25') &lt;br /&gt;
&lt;br /&gt;
and accomplished the same thing. You can use any port mandated by your ISP. Port 25 is the default. If you do not specify a port as part of the server name, the email printer will attempt to use port 25. Note: Beginning with Comet 2006 you are able to send email from smtp servers that require authentication.&lt;br /&gt;
&lt;br /&gt;
If you wish, you may also specify a domain name. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Domain='signature.net')&lt;br /&gt;
&lt;br /&gt;
If it is not specified, the email printer will supply the same domain as designated in the server mnemonic. &lt;br /&gt;
&lt;br /&gt;
To specify the sender's name you use the &amp;quot;From&amp;quot; mnemonic.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (From='&amp;quot;jim guerber&amp;quot;&amp;lt;jim@@signature.net&amp;gt;')&lt;br /&gt;
&lt;br /&gt;
This is used both for SMTP routing (MAIL FROM:) and for the mail message header (From:). It should be set to a valid email address. &lt;br /&gt;
&lt;br /&gt;
Use the &amp;quot;To&amp;quot; mnemonic to specify your recipients. This will be used for SMTP routing (RCPT TO:) and the header (To:).&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (To = 'jim&amp;lt;jim@@signature.net&amp;gt;')&lt;br /&gt;
 Print (lun) (To = 'gina@@signature.net') &lt;br /&gt;
&lt;br /&gt;
You must specify at least one recipient. Use multiple instances of this mnemonic to send your email to more than one recipient. CC and BCC recipients may be specified in addition to or instead of TO recipients. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (CC = 'barbara@@signature.net')&lt;br /&gt;
 Print (lun) (BCC = 'brian@@signature.net') &lt;br /&gt;
&lt;br /&gt;
You must include a subject for your email, use the &amp;quot;Subject&amp;quot; mnemonic. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Subject='The Subject of this email') &lt;br /&gt;
&lt;br /&gt;
In addition to whatever is written to the email printer, you may want to include body text. Depending on your email client, for html printers body text will either appear in an attachment, since it is usual for HTML to appear as the main body of the email, or it will be appended following the html content. For PDF printers, this text will be the main body of the email and the PDF will appear as an attachment. For text printers, the body text will appear just before the printer output. To specify body text, use the &amp;quot;Text&amp;quot; mnemonic.&lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Text='yada yada yada') &lt;br /&gt;
&lt;br /&gt;
The email printer will optionally write to a log file, recording details about each email sent, including responses from the smtp server. The log file is a text file located on any directory to which the user has access. The email printer will append to this log file. The log file may optionally be erased before the print job is run. Otherwise, it is up to the administrator or outside program to erase this file periodically. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (Log='file','dir','erase') &lt;br /&gt;
&lt;br /&gt;
If the log file name is not specified, a file named &amp;quot;email.log&amp;quot; will be used. If the email directory is not specified, &amp;quot;COS&amp;quot; will be used. By default, the file will not be erased. If there is no LOG statement at all, no log file will be generated.&lt;br /&gt;
&lt;br /&gt;
If you wish to specify a name for an attachment to your email, use the (EmailDocument=) mnemonic. &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (EmailDocument='file') &lt;br /&gt;
 Without the (EmailDocument=) mnemonic, the attachment would carry the default name of the document.&lt;br /&gt;
&lt;br /&gt;
==Formatting of email addresses==&lt;br /&gt;
&lt;br /&gt;
In the examples above, we have shown a few different ways to specify an email address. Mail programs like addresses formatted in the following way: &amp;quot;FirstName LastName&amp;quot;&amp;lt;email@domain.tld&amp;gt; Any of the following should work: &lt;br /&gt;
&lt;br /&gt;
 Print (lun) (To = 'Jim Guerber&amp;lt;jim@@signature.net&amp;gt;') ! Best &lt;br /&gt;
 Print (lun) (To = 'Jim&amp;lt;jim@@signature.net&amp;gt;')              ! ok &lt;br /&gt;
 Print (lun) (To = 'jim@@signature.net')                      ! worst &lt;br /&gt;
&lt;br /&gt;
If there is no space character in the name the double quotes are not necessary. Most email programs will take some sort of shortened form of email address, even just the address with no &amp;lt;&amp;gt; such as email@domain.tld, but some spam detection programs may object to this simple form. Note the use of double @ characters as an escape convention of Internet Basic. &lt;br /&gt;
&lt;br /&gt;
Email addresses used in the SMTP routing instructions &amp;quot;mail from&amp;quot; and &amp;quot;rcpt to&amp;quot; will have any name information (like &amp;quot;Jim Guerber&amp;quot; in the above example) stripped out. Microsoft Exchange Server doesn't tolerate anything other than the simple email address.&lt;br /&gt;
&lt;br /&gt;
== A Note on Verifying Email Addresses==&lt;br /&gt;
&lt;br /&gt;
If you're going to do email address validation, consider that VRFY and EXPN are blocked by most ISPs nowadays. Also, simulating VRFY by stacking RCPT TO: commands is something that spammers do. ISPs know this, and the smarter ones track how often you do this. You'll get blocked after some number of attempts. I wouldn't go looking for a lot of sympathy from ISPs when trying to get unblocked afterwards, as the ISPs consider this a very bad practice that good guys don't engage in.&lt;br /&gt;
==The email.ini file==&lt;br /&gt;
&lt;br /&gt;
Several settings for email printers never (or rarely) change. These settings can be placed in an initialization file (INI File). The email printer will look for a file named email.ini which can contain those settings. The email.ini file is optional since all values may be supplied by mnemonics in the program, but it may be a more convenient way to supply some parameters such as the smtp server name. Lines beginning with an exclamation marks ! are treated as comments.&lt;br /&gt;
&lt;br /&gt;
====Mnemonics vs the Email.ini file====&lt;br /&gt;
The information required for an email may be either specified by the use of mnemonics, or placed in a text file called email.ini or both. You may want to setup a standard email.ini file containing items that remain constant from one email to another such as server and domain, and specify the rest of the info using mnemonics, or you may want to write a new email.ini file in the temp directory containing all of the information required before initiating the email program. &lt;br /&gt;
* The email.ini file is not processed until the printer is closed. This means that any time during the execution of the print program, you may add items to the email.ini file.&lt;br /&gt;
* Each print of a mnemonic causes a new line to be generated in the document (the email body) unless Transparent mode is specified (TR).&lt;br /&gt;
* Use of the email.ini file allows general print programs to generate email with no change.&lt;br /&gt;
&lt;br /&gt;
The email printer will look for an equal sign (=) as a delimiter between the parameter name and the value. If an equal sign is not found, the whole line will be treated as text. This is the same as using the &amp;quot;text=&amp;quot; parameter. Here's an example:&lt;br /&gt;
&lt;br /&gt;
 server = smtp.ourserver.net &lt;br /&gt;
 from = OrderProcessing@OurCompany.com &lt;br /&gt;
 bcc = AcctsReceivable@OurCompany.com &lt;br /&gt;
 subject = Thank you for your order &lt;br /&gt;
 Thank you for your recent order. The attached document contains your invoice and delivery schedule. &lt;br /&gt;
&lt;br /&gt;
Using the preceding email.ini file, all that the program would need to supply is the recipient's email address (using the (To=) mnemonic) and write the unique details of the message to the email printer. Note that Accounts Receivable will automatically receive a copy (bcc) of each email.&lt;br /&gt;
 &lt;br /&gt;
Some mnemonics supplied by the program have precedence over the email.ini settings. In other cases both values from a mnemonic AND values from the email.ini file will be used. Those mnemonics which will super cede the equivalent setting in the email.ini file are Server, Domain, From, Subject, and Log. And, if you were to try to use more than one of any of those mnemonics for a given email, only the first one of each would be used. The other settings: To, CC, BCC, and Text, may have multiple occurrences. And, if you use these mnemonics and have equivalent settings in the email.ini, they will all be processed for your email. &lt;br /&gt;
&lt;br /&gt;
==Attachments==&lt;br /&gt;
&lt;br /&gt;
Before understanding attachments, It is good to know the order documents get placed in the email for various printers. For the sake of this document we will call any text specified by the (text=)mnemonic or in the email.ini file &amp;quot;body text&amp;quot;. For all email print jobs there are three possible components that are transmitted. The order depends on the printer type.&lt;br /&gt;
&lt;br /&gt;
For HTML printers, the email is composed of the HTML generated for the printer, followed by the body text, and then any attachments specified.&lt;br /&gt;
 &lt;br /&gt;
For Text printers, email is composed of the printer output followed by body text and then attachments.&lt;br /&gt;
 &lt;br /&gt;
For PDF printers, the email is composed of body text, followed by the printer output as an attachment and then followed by any other attachments specified.&lt;br /&gt;
 &lt;br /&gt;
To add an attachment to the email document, either use the (attachment=path) mnemonic or specify the attachment in the INI file. The path specified must be a valid windows path (use either drive letter or UNC conventions), and does not need to be a Comet file or reside in a Comet directory. Any number of attachment files may be specified. The Emailptr program attempts to determine the mime type of the file by reading the mime keyed file in the rel directory using the file extent ion as the key. If the mime type is not determine able, the default mime type of &amp;quot;application/octet-stream&amp;quot; is used.&lt;br /&gt;
&lt;br /&gt;
==Return Receipts==&lt;br /&gt;
&lt;br /&gt;
Occasionally you may want to know when the receiver of your email reads it. Some (not all) email programs support the &amp;quot;Return-Receipt-To:&amp;quot; command. You may specify (a single) return receipt address either in the ini file or by using the (rr=) mnemonic. Following the equal sign must be a valid email address. &lt;br /&gt;
&lt;br /&gt;
==Silent Running==&lt;br /&gt;
&lt;br /&gt;
The Emailptr will sometimes put up a message box if some component of the email such as the subject is missing. This will stop any program that is designed to produce a series of emails, and would crash if run from a background partition. For that reason, there is an extra instruction in the email.ini file to take care of this situation. If you do not want the emailptr to send any output to the screen, include the '''silent''' command in the email.ini file. If this command appears alone, the emailptr will simply close the email and continue. You may also optionally specify a program to be entered each time an error is encountered. In that case, # buffer will contain the error information (the text that would normally appear in the message box.&lt;br /&gt;
&lt;br /&gt;
==Other SMTP commands and header lines==&lt;br /&gt;
&lt;br /&gt;
You may want to supply other commands to the SMTP server or place additional commands in the header. There are 2 commands that allow you to do that. &lt;br /&gt;
&lt;br /&gt;
'''SmtpCmd=text''' includes the text into the smtp routing instructions. I can't find any good examples of why you would want to send one of these things, but in the future, some Exchange server or something may require one of these.&lt;br /&gt;
&lt;br /&gt;
'''Smtphdr=text''' includes the text in the envelope (the header). There are several interesting commands you could want to put here, but most of them are obsolete.&lt;br /&gt;
&lt;br /&gt;
Examples are:&lt;br /&gt;
&lt;br /&gt;
 print (LUN)(SmtpHdr='X-Priority: 1')    ! mark the email as urgent&lt;br /&gt;
&lt;br /&gt;
==Reference==&lt;br /&gt;
&lt;br /&gt;
For reference, here is a complete list of mnemonics and their corresponding email.ini file settings: &lt;br /&gt;
{|  border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!width=&amp;quot;225&amp;quot;| Mnemonic&lt;br /&gt;
!width=&amp;quot;400&amp;quot;| Ini file&lt;br /&gt;
|-&lt;br /&gt;
| (log = log$)&lt;br /&gt;
| log = email.log,cos,cycle&lt;br /&gt;
|-&lt;br /&gt;
| (server = server$) &lt;br /&gt;
| server = smtp.ourserver.net &lt;br /&gt;
|-&lt;br /&gt;
| (domain= domain$) &lt;br /&gt;
| domain= smtp.ourserver.net &lt;br /&gt;
|-&lt;br /&gt;
| (user = user$) &lt;br /&gt;
|  user = username &lt;br /&gt;
|-&lt;br /&gt;
| (password= pw$) &lt;br /&gt;
| password = MyPassword &lt;br /&gt;
|-&lt;br /&gt;
| (from = from$) &lt;br /&gt;
| from = OrderProcessing@OurCompany.com&lt;br /&gt;
|-&lt;br /&gt;
| (to = to$)&lt;br /&gt;
| to = youraddress@yourisp.net&lt;br /&gt;
|-&lt;br /&gt;
| (cc = cc$) &lt;br /&gt;
| cc = mylawyer@protectme.net &lt;br /&gt;
|-&lt;br /&gt;
| (rr= ReturnReceipt$)&lt;br /&gt;
| rr = returnReceipt@OurCompany.com &lt;br /&gt;
|-&lt;br /&gt;
| (bcc = bcc$) &lt;br /&gt;
| bcc = AcctsReceivable@OurCompany.com &lt;br /&gt;
|-&lt;br /&gt;
| (subject = Subject$) &lt;br /&gt;
| subject = Thank you for your order &lt;br /&gt;
|-&lt;br /&gt;
| (attachment = a$) &lt;br /&gt;
| attachment = c:\boilerplate\terms.pdf &lt;br /&gt;
|-&lt;br /&gt;
| (silent = 'myprog')&lt;br /&gt;
| silent = myprog&lt;br /&gt;
|-&lt;br /&gt;
| (SmtpCmd = 'help')&lt;br /&gt;
| SmtpCmd=help&lt;br /&gt;
|-&lt;br /&gt;
| (SmtpHdr=h$)&lt;br /&gt;
| SmtpHdr=X-Priority: 1&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| ssl=true&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| tls=true&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| time = '+/-####' (offset hours from GMT)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
Here is an interesting article aimed at writers of smtp servers with techniques for filtering spam. It is useful to us so that we can better format our emails to avoid being labeled as &amp;quot;ratware&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[http://slett.net/spam-filtering-for-mx/ Spam Filtering for Mail Exchangers]&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/STL_Container_IB_Reference</id>
		<title>STL Container IB Reference</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/STL_Container_IB_Reference"/>
				<updated>2023-10-13T21:46:38Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Core Functions===&lt;br /&gt;
These are the main functions you will use for each container.&lt;br /&gt;
&lt;br /&gt;
====Vector====&lt;br /&gt;
 '''stlPushBack( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' adds an element to the end of the vector&lt;br /&gt;
 '''stlPopBack( &amp;lt;container-name&amp;gt; )''' removes the element at the end of the vector&lt;br /&gt;
 '''stlFront( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the element at the front of the vector&lt;br /&gt;
 '''stlBack( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the element at the end of the vector&lt;br /&gt;
 '''stlGet( &amp;lt;container-name&amp;gt;, &amp;lt;index&amp;gt; [,EXCP=statement label])''' gets the element at the index specified&lt;br /&gt;
 '''stlSet( &amp;lt;container-name&amp;gt; &amp;lt;index&amp;gt; &amp;lt;data&amp;gt;)''' sets the element at the index specified&lt;br /&gt;
&lt;br /&gt;
Similar to arrays, vectors are mostly used to access data based on a numeric index, thus stlGet and stlSet are going to be your bread and butter functions for this container.  stlPushBack is a great way to programatically build a vector - it will append the specified data to the end of the vector, and increase its size by 1.  If you want to remove the last element, you would use stlPopBack.  Then the stlFront and stlBack functions have been included as shortcuts for accessing the first and last elements respectively.&lt;br /&gt;
&lt;br /&gt;
====List====&lt;br /&gt;
 '''stlPushBack( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' adds an element to the end of the list&lt;br /&gt;
 '''stlPopBack( &amp;lt;container-name&amp;gt; )''' removes the element at the end of the list&lt;br /&gt;
 '''stlPushFront( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' adds an element to the beginning of the list&lt;br /&gt;
 '''stlPopFront( &amp;lt;container-name&amp;gt; )''' removes the element at the beginning of the list&lt;br /&gt;
 '''stlFront( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the element at the beginning of the list&lt;br /&gt;
 '''stlBack( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the element at the end of the list&lt;br /&gt;
&lt;br /&gt;
Lists are designed to be accessed sequentially, that is each element is associated with the preceding and following elements in the container.  As such, the core functions provided are used to add, remove, and get the elements at the front and back of the list.  The real power of lists is utilized during iteration - they are the most efficient container for inserting and erasing elements in the middle of the container.&lt;br /&gt;
&lt;br /&gt;
====Map====&lt;br /&gt;
 '''stlGet( &amp;lt;container-name&amp;gt;, &amp;lt;key&amp;gt; [,EXCP=statement label])''' gets the element at the key specified&lt;br /&gt;
 '''stlSet( &amp;lt;container-name&amp;gt; &amp;lt;key&amp;gt; &amp;lt;data&amp;gt;)''' sets the element at the key specified&lt;br /&gt;
&lt;br /&gt;
Maps are used to relate an element to a key (string index).  Similar to vectors, to access a value, the key must be specified.&lt;br /&gt;
&lt;br /&gt;
====Stack/Queue====&lt;br /&gt;
 '''stlPush( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' adds an element to the container&lt;br /&gt;
 '''stlPop( &amp;lt;container-name&amp;gt; )''' removes the next element from the container&lt;br /&gt;
 '''stlPeek( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the next element from the container&lt;br /&gt;
 '''stlGet( &amp;lt;container-name&amp;gt;, &amp;lt;index&amp;gt; [,EXCP=statement label])''' gets the element at the index specified&lt;br /&gt;
 '''stlSet( &amp;lt;container-name&amp;gt; &amp;lt;index&amp;gt; &amp;lt;data&amp;gt;)''' sets the element at the index specified&lt;br /&gt;
&lt;br /&gt;
Both stacks and queues utilize the same set of functions, but perform differently depending on which container you have implemented.  In general, the stlPush, stlPop, and stlPeek functions are going to be the most important of these functions.  They perform the basic operations associated with these containers.  For stacks, stlPush and stlPop adds and removes from the end of the container.  For queues, stlPush adds to the end of the container, and stlPop removes from the front of the container.  For both containers, stlPeek will get the &amp;quot;next&amp;quot; element in the container (i.e. the last element for stacks, the first element for queues).&lt;br /&gt;
&lt;br /&gt;
Because these containers are implemented with deques internally, we also provide access via numeric indexes with the stlSet() and stlGet() operators.  These functions behave similarly to the vector functions of the same name, by getting and setting the elements at the specified index.&lt;br /&gt;
&lt;br /&gt;
===Iteration Functions===&lt;br /&gt;
These functions are used to iterate over the elements of a container.&lt;br /&gt;
&lt;br /&gt;
General:&lt;br /&gt;
 '''stlBegin( &amp;lt;container-name&amp;gt; )''' sets the iterator position at the beginning&lt;br /&gt;
 '''stlEnd( &amp;lt;container-name&amp;gt; )''' sets the iterator position at the end&lt;br /&gt;
 '''stlNext( &amp;lt;container-name&amp;gt; ) [, EXCP=statement label]''' moves the iterator position forward one element&lt;br /&gt;
 '''stlPrev( &amp;lt;container-name&amp;gt; )''' moves the iterator position back one element&lt;br /&gt;
 '''stlRead( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the element at the current iterator position&lt;br /&gt;
 '''stlWrite( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' - sets the element at the current iterator position&lt;br /&gt;
&lt;br /&gt;
Maps only:&lt;br /&gt;
 '''stlReadKey( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' gets the key at the current iterator position&lt;br /&gt;
&lt;br /&gt;
Lists only:&lt;br /&gt;
 '''stlInsert( &amp;lt;container-name&amp;gt;, &amp;lt;data&amp;gt; )''' inserts the element BEFORE the current iterator position&lt;br /&gt;
 '''stlErase( &amp;lt;container-name&amp;gt; )''' erases the element at the current iterator position&lt;br /&gt;
 (stlErase will subsequently move the iterator position to the next element)&lt;br /&gt;
&lt;br /&gt;
===Utility Functions===&lt;br /&gt;
These are basic functions that return information about the specified container.&lt;br /&gt;
&lt;br /&gt;
 '''stlSize( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' returns the size of the container&lt;br /&gt;
 '''stlEmpty( &amp;lt;container-name&amp;gt; [,EXCP=statement label])''' returns whether the container is empty&lt;br /&gt;
 '''stlClear( &amp;lt;container-name&amp;gt; )''' empties the specified container&lt;br /&gt;
 '''stlReset( &amp;lt;container-name&amp;gt; )''' resets the container to its initial values&lt;br /&gt;
&lt;br /&gt;
===Meta Functions===&lt;br /&gt;
These functions perform some action either on all of the elements in the container, or using all the elements in the container.&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate</id>
		<title>Retrieving and Installing your license certificate</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate"/>
				<updated>2023-07-01T00:38:59Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SecLic - Comet License Retrieval / Installation Utility&lt;br /&gt;
&lt;br /&gt;
SecLic is a utility which allows the retrieval and/or installation of the latest license certificate for your Comet Security Server. The license will be retrieved directly from a Signature Systems server and will be the most recent one issued for your security token. SecLic may be run either directly as a user utility or incorporated into your own application and ENTERed to run silently. Just be sure to have a WinSock gateway configured (a type 3 gateway).&lt;br /&gt;
&lt;br /&gt;
To run it directly simply run SecLic from READY:&lt;br /&gt;
&lt;br /&gt;
[[image:SecLic.jpg]] &lt;br /&gt;
&lt;br /&gt;
To run it silently from your own app, you pass your choice of options via # buffer this way:&lt;br /&gt;
&lt;br /&gt;
print (#) &amp;quot;OPT 1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
enter &amp;quot;SecLic&amp;quot; dir=&amp;quot;REL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
input (#) Result$&lt;br /&gt;
&lt;br /&gt;
There are 3 options:&lt;br /&gt;
&lt;br /&gt;
    * 1 - retrieve the latest certificate from the server and put it in the CometServices folder&lt;br /&gt;
    * 2 - activate whatever certificate is in the CometServices folder&lt;br /&gt;
    * 3 - retrieve and then activate&lt;br /&gt;
    * 4 - retrieve expiration dates and license counts for currently installed certificate&lt;br /&gt;
&lt;br /&gt;
The message you pass via the # buffer is case insensitive and any number of blanks are allowed between &amp;quot;opt&amp;quot; and the number. If the first 3 bytes of the buffer are anything other than ucase(&amp;quot;opt&amp;quot;) the dialog will display instead of running silently.&lt;br /&gt;
&lt;br /&gt;
The result string will indicate the success or failure of the operation(s). It will begin with either &amp;quot;+OK&amp;quot; or &amp;quot;-ERR&amp;quot; and be followed by a descriptive message.&lt;br /&gt;
&lt;br /&gt;
This utility is available on both Comet16 and Comet32 and for both USB and parallel plugs.&lt;br /&gt;
&lt;br /&gt;
SecLic was added to the REL release in version 10.02 and requires Comet version .413 or higher and Comet Security Server version 10.0 or higher.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Notes for Option 4 ===&lt;br /&gt;
&lt;br /&gt;
Option 4 was first released with Comet Security Server version 23.0, and requires REL version 23.01&lt;br /&gt;
&lt;br /&gt;
When run directly, the seclic program will have a button on the top of the screen titled &amp;quot;Check currently installed certificate&amp;quot; which, when pressed, will pop up a message box with license counts and expiration dates for your currently installed certificate.&lt;br /&gt;
&lt;br /&gt;
[[image:Seclic-new.png]] [[image:Seclic-newmsg.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When ENTERed, specifying &amp;quot;OPT 4&amp;quot; will return the data in a 31 byte string with the following format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Position     Length    Description&lt;br /&gt;
===========================================================&lt;br /&gt;
1            8         Certificate Expiration Date&lt;br /&gt;
9            8         XAP Expiration Date (if applicable)&lt;br /&gt;
17           5         Number of Full Comet licenses&lt;br /&gt;
22           5         Number of Comet Anywhere licenses&lt;br /&gt;
27           5         Number of XAP licenses&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error occurs, the return string will have the following format: &amp;quot;-ERR -- error message&amp;quot;&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/File:Seclic-newmsg.png</id>
		<title>File:Seclic-newmsg.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/File:Seclic-newmsg.png"/>
				<updated>2023-07-01T00:36:33Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate</id>
		<title>Retrieving and Installing your license certificate</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate"/>
				<updated>2023-07-01T00:36:02Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SecLic - Comet License Retrieval / Installation Utility&lt;br /&gt;
&lt;br /&gt;
SecLic is a utility which allows the retrieval and/or installation of the latest license certificate for your Comet Security Server. The license will be retrieved directly from a Signature Systems server and will be the most recent one issued for your security token. SecLic may be run either directly as a user utility or incorporated into your own application and ENTERed to run silently. Just be sure to have a WinSock gateway configured (a type 3 gateway).&lt;br /&gt;
&lt;br /&gt;
To run it directly simply run SecLic from READY:&lt;br /&gt;
&lt;br /&gt;
[[image:SecLic.jpg]] &lt;br /&gt;
&lt;br /&gt;
To run it silently from your own app, you pass your choice of options via # buffer this way:&lt;br /&gt;
&lt;br /&gt;
print (#) &amp;quot;OPT 1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
enter &amp;quot;SecLic&amp;quot; dir=&amp;quot;REL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
input (#) Result$&lt;br /&gt;
&lt;br /&gt;
There are 3 options:&lt;br /&gt;
&lt;br /&gt;
    * 1 - retrieve the latest certificate from the server and put it in the CometServices folder&lt;br /&gt;
    * 2 - activate whatever certificate is in the CometServices folder&lt;br /&gt;
    * 3 - retrieve and then activate&lt;br /&gt;
    * 4 - retrieve expiration dates and license counts for currently installed certificate&lt;br /&gt;
&lt;br /&gt;
The message you pass via the # buffer is case insensitive and any number of blanks are allowed between &amp;quot;opt&amp;quot; and the number. If the first 3 bytes of the buffer are anything other than ucase(&amp;quot;opt&amp;quot;) the dialog will display instead of running silently.&lt;br /&gt;
&lt;br /&gt;
The result string will indicate the success or failure of the operation(s). It will begin with either &amp;quot;+OK&amp;quot; or &amp;quot;-ERR&amp;quot; and be followed by a descriptive message.&lt;br /&gt;
&lt;br /&gt;
This utility is available on both Comet16 and Comet32 and for both USB and parallel plugs.&lt;br /&gt;
&lt;br /&gt;
SecLic was added to the REL release in version 10.02 and requires Comet version .413 or higher and Comet Security Server version 10.0 or higher.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Notes for Option 4 ===&lt;br /&gt;
&lt;br /&gt;
Option 4 was first released with Comet Security Server version 23.0, and requires REL version 23.01&lt;br /&gt;
&lt;br /&gt;
When run directly, the seclic program will have a button on the top of the screen titled &amp;quot;Check currently installed certificate&amp;quot; which, when pressed, will pop up a message box with license counts and expiration dates for your currently installed certificate.&lt;br /&gt;
&lt;br /&gt;
[[image:Seclic-new.png]] [[image::Seclic-newmsg.png]]&lt;br /&gt;
&lt;br /&gt;
When ENTERed, specifying &amp;quot;OPT 4&amp;quot; will return the data in the following format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Position     Length    Description&lt;br /&gt;
===========================================================&lt;br /&gt;
1            8         Certificate Expiration Date&lt;br /&gt;
9            8         XAP Expiration Date (if applicable)&lt;br /&gt;
17           5         Number of Full Comet licenses&lt;br /&gt;
22           5         Number of Comet Anywhere licenses&lt;br /&gt;
27           5         Number of XAP licenses&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error occurs, the return string will have the following format: &amp;quot;-ERR -- error message&amp;quot;&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate</id>
		<title>Retrieving and Installing your license certificate</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate"/>
				<updated>2023-07-01T00:34:15Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SecLic - Comet License Retrieval / Installation Utility&lt;br /&gt;
&lt;br /&gt;
SecLic is a utility which allows the retrieval and/or installation of the latest license certificate for your Comet Security Server. The license will be retrieved directly from a Signature Systems server and will be the most recent one issued for your security token. SecLic may be run either directly as a user utility or incorporated into your own application and ENTERed to run silently. Just be sure to have a WinSock gateway configured (a type 3 gateway).&lt;br /&gt;
&lt;br /&gt;
To run it directly simply run SecLic from READY:&lt;br /&gt;
&lt;br /&gt;
[[image:SecLic.jpg]] &lt;br /&gt;
&lt;br /&gt;
To run it silently from your own app, you pass your choice of options via # buffer this way:&lt;br /&gt;
&lt;br /&gt;
print (#) &amp;quot;OPT 1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
enter &amp;quot;SecLic&amp;quot; dir=&amp;quot;REL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
input (#) Result$&lt;br /&gt;
&lt;br /&gt;
There are 3 options:&lt;br /&gt;
&lt;br /&gt;
    * 1 - retrieve the latest certificate from the server and put it in the CometServices folder&lt;br /&gt;
    * 2 - activate whatever certificate is in the CometServices folder&lt;br /&gt;
    * 3 - retrieve and then activate&lt;br /&gt;
    * 4 - retrieve expiration dates and license counts for currently installed certificate&lt;br /&gt;
&lt;br /&gt;
The message you pass via the # buffer is case insensitive and any number of blanks are allowed between &amp;quot;opt&amp;quot; and the number. If the first 3 bytes of the buffer are anything other than ucase(&amp;quot;opt&amp;quot;) the dialog will display instead of running silently.&lt;br /&gt;
&lt;br /&gt;
The result string will indicate the success or failure of the operation(s). It will begin with either &amp;quot;+OK&amp;quot; or &amp;quot;-ERR&amp;quot; and be followed by a descriptive message.&lt;br /&gt;
&lt;br /&gt;
This utility is available on both Comet16 and Comet32 and for both USB and parallel plugs.&lt;br /&gt;
&lt;br /&gt;
SecLic was added to the REL release in version 10.02 and requires Comet version .413 or higher and Comet Security Server version 10.0 or higher.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Notes for Option 4 ===&lt;br /&gt;
&lt;br /&gt;
Option 4 was first released with Comet Security Server version 23.0, and requires REL version 23.01&lt;br /&gt;
&lt;br /&gt;
When run directly, the seclic program will have a button on the top of the screen titled &amp;quot;Check currently installed certificate&amp;quot; which, when pressed, will pop up a message box with license counts and expiration dates for your currently installed certificate.&lt;br /&gt;
&lt;br /&gt;
[[image:Seclic-new.png]] &lt;br /&gt;
&lt;br /&gt;
When ENTERed, specifying &amp;quot;OPT 4&amp;quot; will return the data in the following format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Position     Length    Description&lt;br /&gt;
===========================================================&lt;br /&gt;
1            8         Certificate Expiration Date&lt;br /&gt;
9            8         XAP Expiration Date (if applicable)&lt;br /&gt;
17           5         Number of Full Comet licenses&lt;br /&gt;
22           5         Number of Comet Anywhere licenses&lt;br /&gt;
27           5         Number of XAP licenses&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error occurs, the return string will have the following format: &amp;quot;-ERR -- error message&amp;quot;&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate</id>
		<title>Retrieving and Installing your license certificate</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/Retrieving_and_Installing_your_license_certificate"/>
				<updated>2023-07-01T00:31:16Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SecLic - Comet License Retrieval / Installation Utility&lt;br /&gt;
&lt;br /&gt;
SecLic is a utility which allows the retrieval and/or installation of the latest license certificate for your Comet Security Server. The license will be retrieved directly from a Signature Systems server and will be the most recent one issued for your security token. SecLic may be run either directly as a user utility or incorporated into your own application and ENTERed to run silently. Just be sure to have a WinSock gateway configured (a type 3 gateway).&lt;br /&gt;
&lt;br /&gt;
To run it directly simply run SecLic from READY:&lt;br /&gt;
&lt;br /&gt;
[[image:SecLic.jpg]] &lt;br /&gt;
&lt;br /&gt;
To run it silently from your own app, you pass your choice of options via # buffer this way:&lt;br /&gt;
&lt;br /&gt;
print (#) &amp;quot;OPT 1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
enter &amp;quot;SecLic&amp;quot; dir=&amp;quot;REL&amp;quot;&lt;br /&gt;
&lt;br /&gt;
input (#) Result$&lt;br /&gt;
&lt;br /&gt;
There are 3 options:&lt;br /&gt;
&lt;br /&gt;
    * 1 - retrieve the latest certificate from the server and put it in the CometServices folder&lt;br /&gt;
    * 2 - activate whatever certificate is in the CometServices folder&lt;br /&gt;
    * 3 - retrieve and then activate&lt;br /&gt;
    * 4 - retrieve expiration dates and license counts for currently installed certificate&lt;br /&gt;
&lt;br /&gt;
The message you pass via the # buffer is case insensitive and any number of blanks are allowed between &amp;quot;opt&amp;quot; and the number. If the first 3 bytes of the buffer are anything other than ucase(&amp;quot;opt&amp;quot;) the dialog will display instead of running silently.&lt;br /&gt;
&lt;br /&gt;
The result string will indicate the success or failure of the operation(s). It will begin with either &amp;quot;+OK&amp;quot; or &amp;quot;-ERR&amp;quot; and be followed by a descriptive message.&lt;br /&gt;
&lt;br /&gt;
This utility is available on both Comet16 and Comet32 and for both USB and parallel plugs.&lt;br /&gt;
&lt;br /&gt;
SecLic was added to the REL release in version 10.02 and requires Comet version .413 or higher and Comet Security Server version 10.0 or higher.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Notes for Option 4 ===&lt;br /&gt;
&lt;br /&gt;
When run directly, the seclic program will have a button on the top of the screen titled &amp;quot;Check currently installed certificate&amp;quot; which, when pressed, will pop up a message box with license counts and expiration dates for your currently installed certificate.&lt;br /&gt;
&lt;br /&gt;
[[image:SecLic-new.png]] &lt;br /&gt;
&lt;br /&gt;
When ENTERed, specifying &amp;quot;OPT 4&amp;quot; will return the data in the following format:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Position     Length    Description&lt;br /&gt;
===========================================================&lt;br /&gt;
1            8         Certificate Expiration Date&lt;br /&gt;
9            8         XAP Expiration Date (if applicable)&lt;br /&gt;
17           5         Number of Full Comet licenses&lt;br /&gt;
22           5         Number of Comet Anywhere licenses&lt;br /&gt;
27           5         Number of XAP licenses&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error occurs, the return string will have the following format: &amp;quot;-ERR -- error message&amp;quot;&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	<entry>
		<id>http://wiki.signature.net/index.php/File:Seclic-new.png</id>
		<title>File:Seclic-new.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.signature.net/index.php/File:Seclic-new.png"/>
				<updated>2023-07-01T00:29:31Z</updated>
		
		<summary type="html">&lt;p&gt;Justin: new version of seclic&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;new version of seclic&lt;/div&gt;</summary>
		<author><name>Justin</name></author>	</entry>

	</feed>